From 94d164dd7f20c785a543d1fb1d5bd359fb38bd25 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 May 2017 20:06:40 +0200 Subject: [PATCH] Add a setup hook for detecting $TMPDIR references in RPATHs and wrapper scripts --- .../build-support/setup-hooks/audit-tmpdir.sh | 41 +++++++++++++++++++ pkgs/stdenv/generic/default.nix | 1 + pkgs/stdenv/generic/setup.sh | 12 ++++++ 3 files changed, 54 insertions(+) create mode 100644 pkgs/build-support/setup-hooks/audit-tmpdir.sh diff --git a/pkgs/build-support/setup-hooks/audit-tmpdir.sh b/pkgs/build-support/setup-hooks/audit-tmpdir.sh new file mode 100644 index 000000000000..ffaa61f2d809 --- /dev/null +++ b/pkgs/build-support/setup-hooks/audit-tmpdir.sh @@ -0,0 +1,41 @@ +# Check whether RPATHs or wrapper scripts contain references to +# $TMPDIR. This is a serious security bug because it allows any user +# to inject files into search paths of other users' processes. +# +# It might be better to have Nix scan build output for any occurrence +# of $TMPDIR (which would also be good for reproducibility), but at +# the moment that would produce too many spurious errors (e.g. debug +# info or assertion messages that refer to $TMPDIR). + +fixupOutputHooks+=('if [ -z "$noAuditTmpdir" -a -e "$prefix" ]; then auditTmpdir "$prefix"; fi') + +auditTmpdir() { + local dir="$1" + [ -e "$dir" ] || return 0 + + header "checking for references to $TMPDIR in $dir..." + + local i + while IFS= read -r -d $'\0' i; do + if [[ "$i" =~ .build-id ]]; then continue; fi + + if isELF "$i"; then + if patchelf --print-rpath "$i" | grep -q -F "$TMPDIR"; then + echo "RPATH of binary $i contains a forbidden reference to $TMPDIR" + exit 1 + fi + fi + + if isScript "$i"; then + if [ -e "$(dirname $i)/.$(basename $i)-wrapped" ]; then + if grep -q -F "$TMPDIR" "$i"; then + echo "wrapper script $i contains a forbidden reference to $TMPDIR" + exit 1 + fi + fi + fi + + done < <(find "$dir" -type f -print0) + + stopNest +} diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index a063a1ed2dc9..43b35082161d 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -94,6 +94,7 @@ let ../../build-support/setup-hooks/compress-man-pages.sh ../../build-support/setup-hooks/strip.sh ../../build-support/setup-hooks/patch-shebangs.sh + ../../build-support/setup-hooks/audit-tmpdir.sh ../../build-support/setup-hooks/multiple-outputs.sh ../../build-support/setup-hooks/move-sbin.sh ../../build-support/setup-hooks/move-lib64.sh diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index de33ab565982..eb63b18e5f3d 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -199,6 +199,18 @@ isELF() { if [[ "$magic" =~ ELF ]]; then return 0; else return 1; fi } +# Return success if the specified file is a script (i.e. starts with +# "#!"). +isScript() { + local fn="$1" + local magic + if ! [ -x /bin/sh ]; then return 0; fi + exec {fd}< "$fn" + read -n 2 -u $fd magic + exec {fd}<&- + if [[ "$magic" =~ \#! ]]; then return 0; else return 1; fi +} + ###################################################################### # Initialisation.