aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2019-11-21 15:51:47 +0100
committerThierry Vignaud <thierry.vignaud@gmail.com>2019-12-23 16:02:47 +0100
commit8ecaeab1b79c20f83eda540e39f31e6a73018d7f (patch)
treed0be71a0a008f4aad7819822fc5f58292b0ec4e6
parent7944a0608672698b96767550fa265fde01f29bf0 (diff)
downloadrpm-setup-8ecaeab1b79c20f83eda540e39f31e6a73018d7f.tar
rpm-setup-8ecaeab1b79c20f83eda540e39f31e6a73018d7f.tar.gz
rpm-setup-8ecaeab1b79c20f83eda540e39f31e6a73018d7f.tar.bz2
rpm-setup-8ecaeab1b79c20f83eda540e39f31e6a73018d7f.tar.xz
rpm-setup-8ecaeab1b79c20f83eda540e39f31e6a73018d7f.zip
brp-mangle-shebangs: fix unsafe/incorrect command expansion
trim() { printf '%s' "$*" } ... read shebang_line < "$f" || : orig_shebang=$(trim $(echo "$shebang_line" | grep -Po "#!\K.*" || echo)) The "trimming", i.e. replacement of multiple spaces and removal of leading and trailing spaces, is achieved because "trim $(cmd)" construct has an unquoted $(), which is subject to word splitting. This works, yes. BUT. It is also subject to glob expansion - any ?s and *s will be attempted to be expanded as well - definitely NOT what we want! This change replaces this trick with code which avoids the expansion issue, and which does not spawn any subprocesses for string manipulations - this is ~3 times faster (fork+execs are expensive). Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rwxr-xr-xbrp-mangle-shebangs33
1 files changed, 19 insertions, 14 deletions
diff --git a/brp-mangle-shebangs b/brp-mangle-shebangs
index d79af5a..11809b4 100755
--- a/brp-mangle-shebangs
+++ b/brp-mangle-shebangs
@@ -70,10 +70,6 @@ done
cd "$RPM_BUILD_ROOT"
-trim() {
- printf '%s' "$*"
-}
-
# Large packages such as kernel can have thousands of executable files.
# We take care to not fork/exec thousands of "file"s and "grep"s,
# but run just two of them.
@@ -98,22 +94,31 @@ while IFS= read -r line; do
ts=$(stat -c %y "$f")
- read shebang_line < "$f" || :
- orig_shebang=$(trim $(echo "$shebang_line" | grep -Po "#!\K.*" || echo))
- shebang="$orig_shebang"
- if [ -n "$exclude_shebangs" ]; then
- echo "$shebang" | grep -q -E "$exclude_shebangs" && continue
- fi
- if [ -n "$exclude_shebangs_from" ]; then
- echo "$shebang" | grep -q -E -f "$exclude_shebangs_from" && continue
+ read shebang_line < "$f"
+ orig_shebang="${shebang_line#\#!}"
+ if [ "$orig_shebang" = "$shebang_line" ]; then
+ echo >&2 "*** WARNING: $f is executable but has no shebang, removing executable bit"
+ chmod -x "$f"
+ touch -d "$ts" "$f"
+ continue
fi
+ # Trim spaces
+ while shebang="${orig_shebang// / }"; [ "$shebang" != "$orig_shebang" ]; do
+ orig_shebang="$shebang"
+ done
+ # Treat "#! /path/to " as "#!/path/to"
+ orig_shebang="${orig_shebang# }"
+
+ shebang="$orig_shebang"
+
if [ -z "$shebang" ]; then
- echo >&2 "*** WARNING: $f is executable but has empty or no shebang, removing executable bit"
+ echo >&2 "*** WARNING: $f is executable but has empty shebang, removing executable bit"
chmod -x "$f"
touch -d "$ts" "$f"
continue
- elif [ -n "${shebang##/*}" ]; then
+ fi
+ if [ -n "${shebang##/*}" ]; then
echo >&2 "*** ERROR: $f has shebang which doesn't start with '/' ($shebang)"
fail=1
continue