Severity: medium — a legal parameter value breaks the env file for the whole instance
pkg/launcher/bootstrap.go:531-536 builds the sweep environment by appending shell source
lines, one per spawn:param:* tag:
echo "$PARAM_TAGS" | while IFS=$'\t' read -r key value; do
if [[ $key == spawn:param:* ]]; then
param_name=${key#spawn:param:}
echo "export PARAM_${param_name}=\"${value}\"" >> /etc/profile.d/spawn-params.sh
fi
done
${value} goes in raw, inside double quotes. So for a param file row like
params:
- instance_type: c7g.16xlarge
mdp_flags: -maxh 0.5 -notunepme
label: run "A"
prefix: $HOME/out
the generated /etc/profile.d/spawn-params.sh contains
export PARAM_label="run "A"" # quoting broken
export PARAM_prefix="$HOME/out" # expanded at source time, not the literal
/etc/profile.d/*.sh is sourced by every login shell, so the workload sees a value it never set
(PARAM_prefix becomes /root/out or /home/ec2-user/out), and a value containing a double
quote mangles that line and possibly the next.
Three distinct failures from the same line:
| value |
result |
run "A" |
quoting broken; PARAM_label is not what was written |
$HOME/out |
expanded on the instance at source time |
a`hostname`b |
command substitution runs |
| value containing a newline |
the tag stores it, read -r splits it, the rest becomes a stray line |
The values come from the user's own param file, so this is not a privilege boundary — it is a
correctness bug, and a $ in a path or flag string is an entirely ordinary thing to sweep over.
It is also the silent kind: nothing fails, the workload just runs with a different value than
the manifest says it did, which is a reproducibility problem as much as a bug.
Expected behaviour
Emit the value in a form the shell cannot reinterpret. Options:
- Single-quote and escape embedded single quotes:
export PARAM_x='...'"'"'...'. Cheap and
exact for everything except a literal newline.
- Write the values with a quoted heredoc (
<<'EOF') as KEY=VALUE pairs and have the profile
script read them rather than export them as shell source.
- Reject values containing a newline at launch time, since a tag round-trip through
--output text cannot represent them faithfully anyway.
(1) plus (3) is the smallest correct change.
Regression test to add
A Tier 0 sweep with label: run "A", prefix: $HOME/out and a backtick value; assert the
generated env file (or the spawn:param:* tags plus a shell-parse of the rendered script)
yields the literal strings. The assertion must be on the rendered value, not on the tag — the
tag is already correct today, which is what makes this easy to miss.
Found while fixing #526, whose fix rejects param keys that cannot be valid shell
identifiers for the same reason: export PARAM_on-complete="x" is not a line the shell accepts.
That fix covers the key side of this line only; the value side is untouched.
Related: #524, #525, #526, #530.
Severity: medium — a legal parameter value breaks the env file for the whole instance
pkg/launcher/bootstrap.go:531-536builds the sweep environment by appending shell sourcelines, one per
spawn:param:*tag:${value}goes in raw, inside double quotes. So for a param file row likethe generated
/etc/profile.d/spawn-params.shcontains/etc/profile.d/*.shis sourced by every login shell, so the workload sees a value it never set(
PARAM_prefixbecomes/root/outor/home/ec2-user/out), and a value containing a doublequote mangles that line and possibly the next.
Three distinct failures from the same line:
run "A"PARAM_labelis not what was written$HOME/outa`hostname`bread -rsplits it, the rest becomes a stray lineThe values come from the user's own param file, so this is not a privilege boundary — it is a
correctness bug, and a
$in a path or flag string is an entirely ordinary thing to sweep over.It is also the silent kind: nothing fails, the workload just runs with a different value than
the manifest says it did, which is a reproducibility problem as much as a bug.
Expected behaviour
Emit the value in a form the shell cannot reinterpret. Options:
export PARAM_x='...'"'"'...'. Cheap andexact for everything except a literal newline.
<<'EOF') asKEY=VALUEpairs and have the profilescript read them rather than
exportthem as shell source.--output textcannot represent them faithfully anyway.(1) plus (3) is the smallest correct change.
Regression test to add
A Tier 0 sweep with
label: run "A",prefix: $HOME/outand a backtick value; assert thegenerated env file (or the
spawn:param:*tags plus a shell-parse of the rendered script)yields the literal strings. The assertion must be on the rendered value, not on the tag — the
tag is already correct today, which is what makes this easy to miss.
Found while fixing #526, whose fix rejects param keys that cannot be valid shell
identifiers for the same reason:
export PARAM_on-complete="x"is not a line the shell accepts.That fix covers the key side of this line only; the value side is untouched.
Related: #524, #525, #526, #530.