Skip to content

stdenv: disable hardening for embedded (kernel=none) targets#378825

Closed
midnightveil wants to merge 2 commits intoNixOS:masterfrom
midnightveil:disable-hardening-embedded
Closed

stdenv: disable hardening for embedded (kernel=none) targets#378825
midnightveil wants to merge 2 commits intoNixOS:masterfrom
midnightveil:disable-hardening-embedded

Conversation

@midnightveil
Copy link
Contributor

@midnightveil midnightveil commented Feb 2, 2025

A very partial fix for #18995. This should make the relatively common case of embedded targets Just Work™, since these systems rarely are setup in the standard way.

I've often seen __stack__chk failures when building for embedded systems, enabling this should make these architectures usable without needing to do crimes in nix shells / build environments.


DRAFT, because I need to make sure this works as expected, i.e. I can build things without adding hardeningDisable to nix-shells for embedded work.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 25.05 Release Notes (or backporting 24.11 and 25.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

cc @wucke13 since this might be of shared interest

@github-actions github-actions bot added 6.topic: stdenv Standard environment 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. labels Feb 2, 2025
@wucke13
Copy link
Contributor

wucke13 commented Feb 2, 2025

@midnightveil Thank you! I do this all the time for embedded targets, this is a net positive in usability of Nix for niche target environments

@midnightveil
Copy link
Contributor Author

midnightveil commented Feb 2, 2025

@midnightveil Thank you! I do this all the time for embedded targets, this is a net positive in usability of Nix for niche target environments

Yep, I know :)

I have a suspicion that it might need to be targetPlatform instead of hostPlatform (or that it might not work since the mkShell is usually a non-cross stdenv and might override the compiler)... unfortunately it rebuilds the universe since it modifies most of the target's packages which will take a while. No, that's right, if we have a cross stdenv then we want hostPlatform. I've added a second commit which handles the cross-compiler case. (targetPlatform).

A very partial fix for [NixOS#18995]. This should make the relatively
common case of embedded targets Just Work™, since these systems rarely
are setup in the standard way.

I've often seen __stack__chk failures when building for embedded systems,
enabling this should make these architectures usable without needing
to do crimes in nix shells / build environments.

[NixOS#18995]: NixOS#18995
@midnightveil midnightveil force-pushed the disable-hardening-embedded branch from 213bdce to b3929bb Compare March 25, 2025 08:18
A very partial fix for [NixOS#18995]. This should make the relatively
common case of embedded targets Just Work™, since these systems rarely
are setup in the standard way, and don't like having stack protectors.

This should make these architectures usable as a cross-compiler without
needing crimes in build environments or nix shells.

[NixOS#18995]: NixOS#18995
@midnightveil midnightveil force-pushed the disable-hardening-embedded branch from b3929bb to 68c3282 Compare March 25, 2025 08:26
@midnightveil
Copy link
Contributor Author

midnightveil commented Mar 25, 2025

OK, so, closing this, because of hardening_unsupported_flags:

'' + optionalString (targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano") ''
hardening_unsupported_flags+=" stackprotector fortify pie pic"

We already disable the hardening flags if we're compiling for newlib, which is the case for isNone targets already:

else if final.isNone then "newlib"

This is probably why there were only 44 changes (mostly in some uboot compiles), and the second commit didn't add any more.

This is also the case if you specify a target triple instead of using the recommended pkgsCross.aarch64-embedded:

nix-repl>  (import <nixpkgs> { crossSystem.config = "aarch64-unknown-none-elf"; }).stdenv.targetPlatform.libc
"newlib"

Though (as, I was probably confused in the past), aarch64-unknown-linux-gnu won't get this treatment (somewhat expectedly, however, though various embedded builds "support" it as the prefix).


What this didn't solve, is clang. clang doesn't have a targetPlatform usually; much of the infrastructure in "gcc-like".

nix-shell:~/code/github/nixpkgs]$ NIX_DEBUG=1 clang -target riscv64-none-elf
HARDENING: disabled flags: pacret pie stackclashprotection fortify3 shadowstack trivialautovarinit
HARDENING: Is active (not completely disabled with "all" flag)
HARDENING: enabling pic
HARDENING: enabling format
HARDENING: enabling zerocallusedregs
HARDENING: enabling stackprotector
HARDENING: enabling fortify
HARDENING: enabling strictoverflow
extra flags before to /nix/store/f74fi945gdb4yg8vcj0xlhn9ckrdcwmi-clang-18.1.8/bin/clang:

Compare with e.g., pkgsCross.riscv64-embedded.stdenv.cc:

[nix-shell:~/code/github/nixpkgs]$ NIX_DEBUG=1 riscv64-none-elf-gcc
HARDENING: disabled flags: pacret pie pic stackclashprotection fortify3 shadowstack format zerocallusedregs stackprotector fortify strictoverflow trivialautovarinit

Now, what's (somewhat) hilarious, is that we can actually get this intended behaviour, by requesting pkgsCross.riscv64-embedded.buildPackages.clang. This re-uses the same "clang" package, but builds the cc-wrapper so that we get:

[nix-shell:~/code/github/nixpkgs]$ NIX_DEBUG=1 riscv64-none-elf-clang
HARDENING: disabled flags: pacret pie pic stackclashprotection fortify3 shadowstack format zerocallusedregs stackprotector fortify strictoverflow trivialautovarinit
extra flags before to /nix/store/9wk0c4i44g7jgxvk4x4dkli743845hvy-clang-18.1.8/bin/clang:
  -target
  riscv64-none-elf

So in essence, a fix for the "hardening issue" (not the random extra compile arguments that point the compilers at random sysroots for gcc even if its clang, etc), is to fix clang so that these are applied dynamically based on the -target argument. However, what was recently done is #323869 which adds a warning for this case (though it would be nice to explain how to "actually" do it).


Looks like Wanja's lovely "just merge the directories from unwrapped clang into clang" is probably still the way to go for clang compilers, but for the gcc ones we shouldn't need hardeningDisable = ["all"] anymore. (and the combination makes it not necessary).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: stdenv Standard environment 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants