Linux will support SHSTK in userspace and glibc will eventually have support to use it and subsequently enable shadow stacks on all binaries that are marked up with SHSTK in ELF notes. Rust still does not have support for cf-protection in a stable release yet and hence compiled binaries don't have the SHSTK markup. This is problematic for applications that dlopen rust based plugins, since that will be unsupported and hence result in program termination. Work on rust support is ongoing; CET support is in unstable but there are still some loose ends to resolve, e.g. actual generation of the property note. Track rebase of rust into rawhide, to the version that supports SHSTK markup in ELF binaries generated by rust so that dependent packages can be rebuilt with it. References: https://github.com/rust-lang/rust/issues/73820 https://github.com/rust-lang/rust/pull/110304 Reproducible: Always
This bug appears to have been reported against 'rawhide' during the Fedora Linux 39 development cycle. Changing version to 39.
As an experiment, I applied a small patch to get the Rust standard library built with CET: diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 5b18cb3f7e1e..904e23e3e1d1 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -543,6 +543,12 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car cargo.rustflag("-Cforce-unwind-tables=yes"); } + // Enable CET in the standard library so users can unstably opt-in, since all compiled modules + // must be CET-enabled to have any effect. (Otherwise users need `-Zbuild-std` too.) + if target.starts_with("x86_64") { + cargo.rustflag("-Zcf-protection=full"); + } + // Enable frame pointers by default for the library. Note that they are still controlled by a // separate setting for the compiler. cargo.rustflag("-Cforce-frame-pointers=yes"); Then I also enabled the flag in rust-rpm-sequoia to build its library with CET: diff --git a/rust-rpm-sequoia.spec b/rust-rpm-sequoia.spec index 371cbdc909d7..a2baeb2d3b73 100644 --- a/rust-rpm-sequoia.spec +++ b/rust-rpm-sequoia.spec @@ -17,6 +17,11 @@ Patch: rpm-sequoia-fix-metadata.diff BuildRequires: cargo-rpm-macros >= 24 +%ifarch x86_64 +# Enable unstable CET support. (The cargo macros also set RUSTC_BOOTSTRAP=1.) +%global build_rustflags %{build_rustflags} -Zcf-protection=full +%endif + %global _description %{expand: An implementation of the RPM PGP interface using Sequoia.} $ readelf -n rpm-sequoia-1.6.0-4.fc41.x86_64/usr/lib64/librpm_sequoia.so.1 Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: x86 feature: IBT, SHSTK @sipoyare - would it be useful to have Rust CET available on an opt-in basis like this? Or does it really need to be enabled distro-wide?
It should really be distrowide IMO, but we can start with this and build towards that goal.
I don't like doing experiments on critical components. Either this should be safe to enable in general, or it shouldn't be enabled for a component used by RPM. And before it's not available on stable Rust without setting RUSTC_BOOTSTRAP, I wouldn't like to enable it at all. We already depend on too many things that are potentially unstable, I wouldn't want to add another thing to that list.
The reason I picked rust-rpm-sequoia was because ISTR it was a particular barrier to enabling SHSTK in general. That is, a process that starts in full SHSTK mode can't dlopen libraries that are not enabled, and librpm -> librpm_sequoia was involved like that, I think from dnf? But I'm not sure. I believe it is reasonably safe to enable, apart from the CLI option itself being unstable. Mainly, I suggest opt-in because I would not like to have a lot of places to update when that -Z option eventually changes to some -C, but that could also be addressed by just adding it to rust-packaging flags. I have also considered patching the compiler to hard-code it on, but that's rather blunt.