Skip to content

Commit 263fe3b

Browse files
committed
anonymize-fdt: allocate every temporary file with mktemp
The awk report was named by appending `.report` to the mktemp name of the cleaned dts, and created by shell redirection. mktemp guarantees the name it returns, not one derived from it: the temporary directory is shared and world-writable, so the derived name is predictable from the moment the first file appears, and anyone on the host could pre-create it as a symlink that `2>` then writes through — an arbitrary file write as the invoking user. Give the report its own mktemp, and check all three calls for failure. A cleanup trap on EXIT, INT, TERM and HUP replaces the end-of-loop rm, so a dtc failure part-way through a file no longer leaves the temporaries behind under `set -e`. The names are cleared after each iteration so the trap only removes what is live, and cleanup tests them with `if` rather than `[ -n ... ] && rm`, whose non-zero status would abandon the removals after an unset name.
1 parent 4773ce0 commit 263fe3b

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

extra/anonymize-fdt

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,39 @@ command -v dtc >/dev/null 2>&1 || {
3535
exit 2
3636
}
3737

38+
# Every temporary file is allocated by mktemp and removed by the trap, so an
39+
# error or a signal part-way through a file does not leave one behind. Names are
40+
# never derived from each other: the temporary directory is shared and
41+
# world-writable, and a name built by appending to another (`$clean.report`) is
42+
# predictable from the moment the first one appears, so anyone on the host could
43+
# pre-create it as a symlink and have the redirection below write through it.
44+
dts=''
45+
clean=''
46+
report=''
47+
cleanup() {
48+
# `if` rather than `[ ... ] && rm`: under `set -e` an unset name would make the
49+
# && list return non-zero and abandon the removals after it.
50+
if [ -n "$dts" ]; then rm -f "$dts"; fi
51+
if [ -n "$clean" ]; then rm -f "$clean"; fi
52+
if [ -n "$report" ]; then rm -f "$report"; fi
53+
return 0
54+
}
55+
trap cleanup EXIT INT TERM HUP
56+
3857
for dtb in "$@"; do
3958
if [ ! -f "$dtb" ]; then
4059
echo "skip (not a file): $dtb" >&2
4160
continue
4261
fi
4362
cp -f "$dtb" "$dtb.orig"
44-
dts=$(mktemp)
45-
clean=$(mktemp)
63+
dts=$(mktemp) || { echo "anonymize-fdt: mktemp failed" >&2; exit 1; }
64+
clean=$(mktemp) || { echo "anonymize-fdt: mktemp failed" >&2; exit 1; }
65+
report=$(mktemp) || { echo "anonymize-fdt: mktemp failed" >&2; exit 1; }
4666
dtc -I dtb -O dts -o "$dts" "$dtb" 2>/dev/null
4767

4868
# Drop any property assignment whose name is in SCRUB, handling values that
4969
# span multiple lines (keep dropping until the terminating ';'). Names of the
5070
# removed properties (and a trailing count) go to the report on stderr.
51-
report="$clean.report"
5271
awk -v scrub="$SCRUB" '
5372
BEGIN { n = split(scrub, a, " "); for (i = 1; i <= n; i++) deny[a[i]] = 1 }
5473
skip { if ($0 ~ /;[[:space:]]*$/) skip = 0; next }
@@ -72,5 +91,8 @@ for dtb in "$@"; do
7291
grep '^ removed:' "$report" >&2 || true
7392
echo "$dtb: removed ${n} identifying propert$([ "$n" = 1 ] && echo y || echo ies); backup at $dtb.orig"
7493
echo " review: dtc -I dtb -O dts $dtb | less"
75-
rm -f "$dts" "$clean" "$report"
94+
cleanup
95+
dts=''
96+
clean=''
97+
report=''
7698
done

0 commit comments

Comments
 (0)