禁用“nix-shell”环境的安全强化选项

禁用“nix-shell”环境的安全强化选项

在尝试在 NixOS (16.09) 上构建 GCC (6.3) 时,nix-shell我得到了以下信息:

make[1]: Entering directory '<my-build-path>/coreboot/util/crossgcc/build-i386-elf-GCC/build-x86_64-pc-linux-gnu/libcpp'
test -f config.h || (rm -f stamp-h1 && make stamp-h1)
g++  -I../../../gcc-6.3.0/libcpp -I. -I../../../gcc-6.3.0/libcpp/../include -I../../../gcc-6.3.0/libcpp/include  -O2  -fomit-frame-pointer -m64 -W -Wall -Wno-narrowing -Wwrite-strings -Wmissing-format-attribute -pedantic -Wno-long-long  -fno-exceptions -fno-rtti -I../../../gcc-6.3.0/libcpp -I. -I../../../gcc-6.3.0/libcpp/../include -I../../../gcc-6.3.0/libcpp/include   -c -o expr.o -MT expr.o -MMD -MP -MF .deps/expr.Tpo ../../../gcc-6.3.0/libcpp/expr.c
../../../gcc-6.3.0/libcpp/expr.c: In function 'unsigned int cpp_classify_number(cpp_reader*, const cpp_token*, const char**, source_location)':
../../../gcc-6.3.0/libcpp/expr.c:686:18: error: format not a string literal and no format arguments [-Werror=format-security]
        0, message);
                  ^
../../../gcc-6.3.0/libcpp/expr.c:689:39: error: format not a string literal and no format arguments [-Werror=format-security]
           virtual_location, 0, message);
                                       ^
cc1plus: some warnings being treated as errors
make[1]: *** [Makefile:224: expr.o] Error 1
make[1]: Leaving directory '<my-build-path>/coreboot/util/crossgcc/build-i386-elf-GCC/build-x86_64-pc-linux-gnu/libcpp'
make: *** [Makefile:2730: all-build-libcpp] Error 2
sh ../gcc-6.3.0/mkinstalldirs <my-build-path>/coreboot/util/crossgcc/xgcc <my-build-path>/coreboot/util/crossgcc/xgcc
sh: line 3: cd: i386-elf/libgcc: No such file or directory
make: *** [Makefile:10462: install-target-libgcc] Error 1

哪里-Werror=format-security似乎是失败的原因(尽管我在命令中没有看到这个确切的选项)。然而<nixpkgs>/pkgs/development/compilers/gcc/6/default.nix我发现这个:

hardeningDisable = [ "format" ];

并且猜测失败可能是由于NixOS的安全加固措施造成的,其中有一些禁用以编译 GCC(假设 GCC 开发人员知道他们在这些函数中做什么)。用 GCC 6.2 和 5.4 进行了测试——同样的事情。

所以问题是如何禁用环境format的强化选项(特别是)nix-shell?或者那些“被视为错误的警告”从何而来?

选项描述:


根据这个答案

nix-shell与 Nix 表达式无关...但是当我makeNIX_DEBUG标志调用时,

env NIX_DEBUG=' ' make crossgcc-i386

我得到的输出<nixpkgs>/pkgs/build-support/cc-wrapper/add-hardening.sh,例如HARDENING: enabling format;据我推断,当我make调用nix-shell.


也许我只是需要通过 碰撞一些东西nixos-option,但到底是哪个选项?我不能只是grep这样...(没有dconf dump /or的类似物gsettings list-recursively

答案1

警告format-security被禁用,或者至少不被-Werror禁用,因为:

强化选项是由编译器包装器强加的,这就是它们不显示在日志中的原因。

显然hardeningDisable这是影响包装器的唯一方法。

一种可能的解决方案是创建一个与 一起使用的虚拟 Nix 表达式nix-shell -A。例如:
复制~/.nix-defexpr/channels_root/nixos/到一个单独的地方(<nixpkgs'>)并使其可写,
添加<nixpkgs'>/pkgs/tools/misc/coreboot/default.nix包含

{ stdenv, gcc6, flex, bison, ncurses, iasl, doxygen, zlib, isl, python }:

stdenv.mkDerivation {
  name = "coreboot";

  buildInputs = [ gcc6 flex bison ncurses iasl doxygen zlib isl python ];

  hardeningDisable = [ "format" ];  # to build the cross-compiler
}

<nixpkgs'>/top-level/all-packages.nix并像往常一样注册它
,最后调用nix-shell <nixpkgs'> -A coreboot创建所需的环境。

不过我认为它应该更容易(适用于nix-shell -p)。

答案2

在 nix-shell 中禁用 gcc 强化标志

# shell.nix

{ pkgs ? import <nixpkgs> {} }:

with pkgs;

mkShell {
  # disable all hardening flags
  NIX_HARDENING_ENABLE = "";

  # enable default hardening flags
  #NIX_HARDENING_ENABLE = "pie pic format stackprotector fortify strictoverflow";

  buildInputs = [
    #gnumake
    #python3
    # ...
  ];
}

核实

$ NIX_DEBUG=1 gcc -v 2>&1 | grep ^HARDENING
HARDENING: disabled flags: pie pic format stackprotector fortify strictoverflow

基于

$ which gcc 
/nix/store/l0fvy72hpfdpjjs3dk4112f57x7r3dlm-gcc-wrapper-12.2.0/bin/gcc

$ grep add-hardening.sh /nix/store/l0fvy72hpfdpjjs3dk4112f57x7r3dlm-gcc-wrapper-12.2.0/bin/gcc
source /nix/store/l0fvy72hpfdpjjs3dk4112f57x7r3dlm-gcc-wrapper-12.2.0/nix-support/add-hardening.sh

也可以看看:Nixpkgs 中的强化在 nixpkgs 手册中

相关内容