(#9400 P1b) Replace unsafe eval with declare -g and nameref#9461
(#9400 P1b) Replace unsafe eval with declare -g and nameref#9461
Conversation
📝 WalkthroughWalkthroughThese changes replace unsafe Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
|
||
| # if the var is an array... | ||
| if [[ "${array_values:-"no"}" == "yes" ]]; then | ||
| eval "var_value=\"\${${var_name}[@]}\"" # sorry |
There was a problem hiding this comment.
The comment tells me that Ricardo put some thought into this before leaving as it is. So I'd like to hear his opinion on the change.
eval "declare -g $name=\"$value\"" is equivalent to the safer
declare -g "${name}=${value}" which avoids code injection risk.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two eval calls in set_interactive_config_value():
- eval "$1"='$2' → declare -g "${1}=${2}"
- eval "ARMBIAN_INTERACTIVE_CONFIGS[${1}]"='$2' → direct array assignment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The original code used eval to read an array variable with a dynamic name:
eval "var_value=\"\${${var_name}[@]}\"" # sorry
eval works, but it executes arbitrary code — if $var_name were ever a
crafted string, it could inject commands.
bash 4.3+ nameref (local -n) creates an alias to the variable named in
$var_name without executing any code:
local -n _ct_arr_ref="${var_name}"
var_value="${_ct_arr_ref[*]}"
unset -n _ct_arr_ref
unset -n removes only the alias (not the referenced array), preventing
"already a nameref" warnings on subsequent loop iterations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
a4e2d2c to
17f8209
Compare
Summary
Replaces 5
evalusages that can be trivially eliminated — part of the bash safety plan in #9400 (P1b).lib/functions/cli/utils-cli.sheval "declare -g $name=\"$value\""declare -g "${name}=${value}"lib/functions/configuration/interactive.sheval "$1"='$2'declare -g "${1}=${2}"lib/functions/configuration/interactive.sheval "ARMBIAN_INTERACTIVE_CONFIGS[${1}]"='$2'ARMBIAN_INTERACTIVE_CONFIGS["${1}"]="${2}"lib/functions/configuration/change-tracking.sheval "var_value=\"\${${var_name}[@]}\""local -nnamereflib/functions/artifacts/artifacts-obtain.sheval "declare ${var}_ARRAY=\"\${${var}[*]}\""local -nnamerefWhy eval is risky here
evalexecutes its argument as shell code. If a variable name or value were ever a crafted string (e.g. from user input or a config file), it could inject arbitrary commands. The bash builtins used as replacements do not have this property.Note:
parse_cmdline_paramsalready validates parameter names against^[a-zA-Z_][a-zA-Z0-9_]*$before inserting intoARMBIAN_PARSED_CMDLINE_PARAMS, so names reachingapply_cmdline_params_to_envare guaranteed to be valid identifiers — closing the array-index injection vector at the source.The nameref case explained
change-tracking.shandartifacts-obtain.shboth needed to read an array variable whose name is stored in a scalar at runtime. The original comment in change-tracking said# sorry. The fix uses bash 4.3+ nameref (local -n), which creates an alias to the variable without executing any code:Out of scope
Other
evalusages inlib/intentionally left alone:cli-configdump.sh:61— deserializer for@Q-quoted serialization (safe by construction, cannot be trivially replaced without reworking serialization).extensions.sh,armbian-bsp-desktop-deb.sh,traps.sh, heredocs inutils-cli.sh) — legitimate dynamic code generation.eval env "${COMPILER}gcc"in compilation paths — redundantevalbut no injection risk; not in P1b scope.Test plan
shellcheckpasses with no new warningscompile.shruns normally (cmdline param application, interactive config, change tracking, artifact config dump all exercised in normal builds)🤖 Generated with Claude Code