cc-wrapper: use `-fmacro-prefix-map` to scrub `__FILE__` references (#429880)

Emily feb38c09 343b9374

Changed files
+46 -65
pkgs
build-support
by-name
ed
edencommon
fb
fbthrift
fi
fo
folly
gt
gtest
mv
mvfst
sa
wa
wangle
development
compilers
libraries
boost
+33 -8
pkgs/build-support/cc-wrapper/default.nix
···
else
targetPlatform.darwinPlatform
);
+
+
# Header files that use `__FILE__` (e.g., for error reporting) lead
+
# to unwanted references to development packages and outputs in built
+
# binaries, like C++ programs depending on GCC and Boost at runtime.
+
#
+
# We use `-fmacro-prefix-map` to avoid the store references in these
+
# situations while keeping them in compiler diagnostics and debugging
+
# and profiling output.
+
#
+
# Unfortunately, doing this with GCC runs into issues with compiler
+
# argument length limits due to <https://gcc.gnu.org/PR111527>, so we
+
# disable it there in favour of our existing patch.
+
#
+
# TODO: Drop `mangle-NIX_STORE-in-__FILE__.patch` from GCC and make
+
# this unconditional once the upstream bug is fixed.
+
useMacroPrefixMap = !isGNU;
in
assert includeFortifyHeaders' -> fortify-headers != null;
···
substituteAll "$wrapper" "$out/bin/$dst"
chmod +x "$out/bin/$dst"
}
+
+
include() {
+
printf -- '%s %s\n' "$1" "$2"
+
${lib.optionalString useMacroPrefixMap ''
+
local scrubbed="$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-''${2#"$NIX_STORE"/*-}"
+
printf -- '-fmacro-prefix-map=%s=%s\n' "$2" "$scrubbed"
+
''}
+
}
''
+ (
···
echo "-B${libc_lib}${libc.libdir or "/lib/"}" >> $out/nix-support/libc-crt1-cflags
''
+ optionalString (!(cc.langD or false)) ''
-
echo "-${
+
include "-${
if isArocc then "I" else "idirafter"
-
} ${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags
+
}" "${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags
''
+ optionalString (isGNU && (!(cc.langD or false))) ''
for dir in "${cc}"/lib/gcc/*/*/include-fixed; do
-
echo '-idirafter' ''${dir} >> $out/nix-support/libc-cflags
+
include '-idirafter' ''${dir} >> $out/nix-support/libc-cflags
done
''
+ ''
···
# like option that forces the libc headers before all -idirafter,
# hence -isystem here.
+ optionalString includeFortifyHeaders' ''
-
echo "-isystem ${fortify-headers}/include" >> $out/nix-support/libc-cflags
+
include -isystem "${fortify-headers}/include" >> $out/nix-support/libc-cflags
''
)
···
# https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903)
+ optionalString (libcxx == null && isClang && (useGccForLibs && gccForLibs.langCC or false)) ''
for dir in ${gccForLibs}/include/c++/*; do
-
echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags
+
include -isystem "$dir" >> $out/nix-support/libcxx-cxxflags
done
for dir in ${gccForLibs}/include/c++/*/${targetPlatform.config}; do
-
echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags
+
include -isystem "$dir" >> $out/nix-support/libcxx-cxxflags
done
''
+ optionalString (libcxx.isLLVM or false) ''
-
echo "-isystem ${getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
+
include -isystem "${getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags
''
# GCC NG friendly libc++
+ optionalString (libcxx != null && libcxx.isGNU or false) ''
-
echo "-isystem ${getDev libcxx}/include" >> $out/nix-support/libcxx-cxxflags
+
include -isystem "${getDev libcxx}/include" >> $out/nix-support/libcxx-cxxflags
''
##
···
inherit libc_bin libc_dev libc_lib;
inherit darwinPlatformForCC;
default_hardening_flags_str = builtins.toString defaultHardeningFlags;
+
inherit useMacroPrefixMap;
}
// lib.mapAttrs (_: lib.optionalString targetPlatform.isDarwin) {
# These will become empty strings when not targeting Darwin.
+9
pkgs/build-support/cc-wrapper/setup-hook.sh
···
local role_post
getHostRoleEnvHook
+
local found=
+
if [ -d "$1/include" ]; then
export NIX_CFLAGS_COMPILE${role_post}+=" -isystem $1/include"
+
found=1
fi
if [ -d "$1/Library/Frameworks" ]; then
export NIX_CFLAGS_COMPILE${role_post}+=" -iframework $1/Library/Frameworks"
+
found=1
+
fi
+
+
if [[ -n "@useMacroPrefixMap@" && -n ${NIX_STORE:-} && -n $found ]]; then
+
local scrubbed="$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${1#"$NIX_STORE"/*-}"
+
export NIX_CFLAGS_COMPILE${role_post}+=" -fmacro-prefix-map=$1=$scrubbed"
fi
}
-2
pkgs/by-name/ed/edencommon/package.nix
···
cmake,
ninja,
-
sanitiseHeaderPathsHook,
glog,
gflags,
···
nativeBuildInputs = [
cmake
ninja
-
sanitiseHeaderPathsHook
];
buildInputs = [
-2
pkgs/by-name/fb/fbthrift/package.nix
···
cmake,
ninja,
-
sanitiseHeaderPathsHook,
openssl,
gflags,
···
nativeBuildInputs = [
cmake
ninja
-
sanitiseHeaderPathsHook
];
buildInputs = [
-2
pkgs/by-name/fi/fizz/package.nix
···
cmake,
ninja,
-
sanitiseHeaderPathsHook,
openssl,
glog,
···
nativeBuildInputs = [
cmake
ninja
-
sanitiseHeaderPathsHook
];
buildInputs = [
-2
pkgs/by-name/fo/folly/package.nix
···
cmake,
ninja,
pkg-config,
-
sanitiseHeaderPathsHook,
double-conversion,
fast-float,
···
cmake
ninja
pkg-config
-
sanitiseHeaderPathsHook
];
# See CMake/folly-deps.cmake in the Folly source tree.
-2
pkgs/by-name/gt/gtest/package.nix
···
fetchFromGitHub,
cmake,
ninja,
-
sanitiseHeaderPathsHook,
# Enable C++17 support
# https://github.com/google/googletest/issues/3081
# Projects that require a higher standard can override this package.
···
nativeBuildInputs = [
cmake
ninja
-
sanitiseHeaderPathsHook
];
cmakeFlags = [
-2
pkgs/by-name/mv/mvfst/package.nix
···
cmake,
ninja,
-
sanitiseHeaderPathsHook,
folly,
gflags,
···
nativeBuildInputs = [
cmake
ninja
-
sanitiseHeaderPathsHook
];
buildInputs = [
-18
pkgs/by-name/sa/sanitiseHeaderPathsHook/package.nix
···
-
{
-
lib,
-
makeSetupHook,
-
removeReferencesTo,
-
}:
-
-
makeSetupHook {
-
name = "sanitise-header-paths-hook";
-
-
substitutions = {
-
removeReferencesTo = lib.getExe removeReferencesTo;
-
};
-
-
meta = {
-
description = "Setup hook to sanitise header file paths to avoid leaked references through `__FILE__`";
-
maintainers = [ lib.maintainers.emily ];
-
};
-
} ./sanitise-header-paths-hook.bash
-10
pkgs/by-name/sa/sanitiseHeaderPathsHook/sanitise-header-paths-hook.bash
···
-
sanitiseHeaderPaths() {
-
local header
-
while IFS= read -r -d '' header; do
-
nixLog "sanitising header path in $header"
-
sed -i "1i#line 1 \"$header\"" "$header"
-
@removeReferencesTo@ -t "${!outputInclude}" "$header"
-
done < <(find "${!outputInclude}/include" -type f -print0)
-
}
-
-
preFixupHooks+=(sanitiseHeaderPaths)
-2
pkgs/by-name/wa/wangle/package.nix
···
cmake,
ninja,
-
sanitiseHeaderPathsHook,
folly,
fizz,
···
nativeBuildInputs = [
cmake
ninja
-
sanitiseHeaderPathsHook
];
buildInputs = [
-5
pkgs/development/compilers/gcc/common/dependencies.nix
···
gmp,
mpfr,
libmpc,
-
sanitiseHeaderPathsHook,
libucontext ? null,
libxcrypt ? null,
isSnapshot ? false,
···
texinfo
which
gettext
-
-
# Prevent GCC leaking into the runtime closure of C++ packages
-
# through headers using `__FILE__`.
-
sanitiseHeaderPathsHook
]
++ optionals (perl != null) [ perl ]
++ optionals (with stdenv.targetPlatform; isVc4 || isRedox || isSnapshot && flex != null) [ flex ]
-2
pkgs/development/compilers/gcc/default.nix
···
!enablePlugin
|| (stdenv.targetPlatform.isAvr && stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64),
nukeReferences,
-
sanitiseHeaderPathsHook,
callPackage,
majorMinorVersion,
apple-sdk,
···
pkgsBuildTarget
profiledCompiler
reproducibleBuild
-
sanitiseHeaderPathsHook
staticCompiler
stdenv
targetPackages
+4
pkgs/development/compilers/gcc/patches/default.nix
···
# Do not try looking for binaries and libraries in /lib and /usr/lib
./13/no-sys-dirs-riscv.patch
# Mangle the nix store hash in __FILE__ to prevent unneeded runtime references
+
#
+
# TODO: Remove these and the `useMacroPrefixMap` conditional
+
# in `cc-wrapper` once <https://gcc.gnu.org/PR111527>
+
# is fixed.
./13/mangle-NIX_STORE-in-__FILE__.patch
];
"14" = [
-8
pkgs/development/libraries/boost/generic.nix
···
fixDarwinDylibNames,
libiconv,
libxcrypt,
-
sanitiseHeaderPathsHook,
makePkgconfigItem,
copyPkgconfigItems,
boost-build,
···
which
boost-build
copyPkgconfigItems
-
sanitiseHeaderPathsHook
]
++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames;
buildInputs = [
···
b2 ${b2Args} install
runHook postInstall
-
'';
-
-
preFixup = ''
-
# Strip UTF‐8 BOMs for `sanitiseHeaderPathsHook`.
-
cd "$dev" && find include \( -name '*.hpp' -or -name '*.h' -or -name '*.ipp' \) \
-
-exec sed '1s/^\xef\xbb\xbf//' -i '{}' \;
'';
postFixup = lib.optionalString stdenv.hostPlatform.isMinGW ''