Found during a Codex global scan of deepmodeling/deepmd-kit at commit 73de44b1f94471b2e3bdb6b11f57b34d7bc791bb.
Problem
Several LAMMPS option parsers read arguments after a keyword without first checking that enough arguments remain.
Evidence:
- In
FixDPLR, the model option checks iarg + 1 > narg, but then reads arg[iarg + 1]; when the keyword is the final token, the check passes and the code reads past the argv array:
|
if (string(arg[iarg]) == string("model")) { |
|
if (iarg + 1 > narg) { |
|
error->all(FLERR, "Illegal fix adapt command"); |
|
} |
|
model = string(arg[iarg + 1]); |
|
iarg += 2; |
- The
efield option needs three following values, but checks iarg + 3 > narg before reading through arg[iarg + 3]:
|
} else if (string(arg[iarg]) == string("efield")) { |
|
if (iarg + 3 > narg) { |
|
error->all(FLERR, |
|
"Illegal fix adapt command, efield should be provided 3 " |
|
"float numbers"); |
|
} |
|
if (utils::strmatch(arg[iarg + 1], "^v_")) { |
|
xstr = utils::strdup(arg[iarg + 1] + 2); |
|
} else { |
|
efield[0] = qe2f * utils::numeric(FLERR, arg[iarg + 1], false, lmp); |
|
xstyle = CONSTANT; |
|
} |
|
|
|
if (utils::strmatch(arg[iarg + 2], "^v_")) { |
|
ystr = utils::strdup(arg[iarg + 2] + 2); |
|
} else { |
|
efield[1] = qe2f * utils::numeric(FLERR, arg[iarg + 2], false, lmp); |
|
ystyle = CONSTANT; |
|
} |
|
|
|
if (utils::strmatch(arg[iarg + 3], "^v_")) { |
|
zstr = utils::strdup(arg[iarg + 3] + 2); |
|
} else { |
|
efield[2] = qe2f * utils::numeric(FLERR, arg[iarg + 3], false, lmp); |
|
zstyle = CONSTANT; |
|
} |
|
iarg += 4; |
pair_style deepmd reads arg[iarg + 1] for relative and relative_v without any bounds/key check:
|
} else if (string(arg[iarg]) == string("relative")) { |
|
out_rel = 1; |
|
eps = atof(arg[iarg + 1]) / ener_unit_cvt_factor; |
|
iarg += 2; |
|
} else if (string(arg[iarg]) == string("relative_v")) { |
|
out_rel_v = 1; |
|
eps_v = atof(arg[iarg + 1]) / ener_unit_cvt_factor; |
|
iarg += 2; |
pair_style deepmd also reads virtual_len and spin_norm values in loops without checking that numb_types_spin values remain:
|
} else if (string(arg[iarg]) == string("virtual_len")) { |
|
virtual_len.resize(numb_types_spin); |
|
for (int ii = 0; ii < numb_types_spin; ++ii) { |
|
virtual_len[ii] = atof(arg[iarg + ii + 1]); |
|
} |
|
iarg += numb_types_spin + 1; |
|
} else if (string(arg[iarg]) == string("spin_norm")) { |
|
spin_norm.resize(numb_types_spin); |
|
for (int ii = 0; ii < numb_types_spin; ++ii) { |
|
spin_norm[ii] = atof(arg[iarg + ii + 1]); |
|
} |
|
iarg += numb_types_spin + 1; |
pair_style deepspin has the same unchecked relative/relative_v and spin-option reads:
|
} else if (string(arg[iarg]) == string("relative")) { |
|
out_rel = 1; |
|
eps = atof(arg[iarg + 1]) / ener_unit_cvt_factor; |
|
iarg += 2; |
|
} else if (string(arg[iarg]) == string("relative_v")) { |
|
out_rel_v = 1; |
|
eps_v = atof(arg[iarg + 1]) / ener_unit_cvt_factor; |
|
iarg += 2; |
|
} else if (string(arg[iarg]) == string("virtual_len")) { |
|
virtual_len.resize(numb_types_spin); |
|
for (int ii = 0; ii < numb_types_spin; ++ii) { |
|
virtual_len[ii] = atof(arg[iarg + ii + 1]); |
|
} |
|
iarg += numb_types_spin + 1; |
|
} else if (string(arg[iarg]) == string("spin_norm")) { |
|
spin_norm.resize(numb_types_spin); |
|
for (int ii = 0; ii < numb_types_spin; ++ii) { |
|
spin_norm[ii] = atof(arg[iarg + ii + 1]); |
|
} |
|
iarg += numb_types_spin + 1; |
Impact
Malformed LAMMPS input such as a trailing relative, relative_v, virtual_len, spin_norm, model, or incomplete efield option can read beyond the arg array and crash instead of producing a normal LAMMPS input error.
Suggested Fix
Use >= narg style bounds checks before every argument read and reject another keyword where a numeric value is required. Replace the type_associate parity assert with a runtime error->all() as part of the same parser hardening. Add parser tests for truncated options.
Found during a Codex global scan of
deepmodeling/deepmd-kitat commit73de44b1f94471b2e3bdb6b11f57b34d7bc791bb.Problem
Several LAMMPS option parsers read arguments after a keyword without first checking that enough arguments remain.
Evidence:
FixDPLR, themodeloption checksiarg + 1 > narg, but then readsarg[iarg + 1]; when the keyword is the final token, the check passes and the code reads past the argv array:deepmd-kit/source/lmp/fix_dplr.cpp
Lines 82 to 87 in 73de44b
efieldoption needs three following values, but checksiarg + 3 > nargbefore reading througharg[iarg + 3]:deepmd-kit/source/lmp/fix_dplr.cpp
Lines 88 to 114 in 73de44b
pair_style deepmdreadsarg[iarg + 1]forrelativeandrelative_vwithout any bounds/key check:deepmd-kit/source/lmp/pair_deepmd.cpp
Lines 846 to 853 in 73de44b
pair_style deepmdalso readsvirtual_lenandspin_normvalues in loops without checking thatnumb_types_spinvalues remain:deepmd-kit/source/lmp/pair_deepmd.cpp
Lines 854 to 865 in 73de44b
pair_style deepspinhas the same uncheckedrelative/relative_vand spin-option reads:deepmd-kit/source/lmp/pair_deepspin.cpp
Lines 736 to 755 in 73de44b
Impact
Malformed LAMMPS input such as a trailing
relative,relative_v,virtual_len,spin_norm,model, or incompleteefieldoption can read beyond theargarray and crash instead of producing a normal LAMMPS input error.Suggested Fix
Use
>= nargstyle bounds checks before every argument read and reject another keyword where a numeric value is required. Replace thetype_associateparityassertwith a runtimeerror->all()as part of the same parser hardening. Add parser tests for truncated options.