Wiki - https://fedoraproject.org/wiki/Changes/ShadowStack Discussion thread - https://discussion.fedoraproject.org/t/f45-change-proposal-enable-shadow-stack-by-default-on-x86-64-system-wide/195400 This is a proposed Change for Fedora Linux. This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee. == Summary == This change enables Shadow Stack protection on applications and libraries built with gcc (C, C++), clang (C, C++), and rustc (Rust) by default on x86_64 machines that support it on Fedora Linux 45. The dynamic linker or static startup routines will activate Shadow Stack for any process whose binary and shared library dependencies are all built with Shadow Stack support (marked with ELF metadata), protecting processes by default whenever possible. == Owner == * Name: [[User:submachine| Arjun Shankar]] * Email: arjun@redhat.com == Detailed Description == Shadow Stacks are a hardware enforced security feature that maintains a separate, tamper proof list of return addresses to protect against Return-Oriented Programming style exploits. This change enables Shadow Stack protection by default on x86_64 machines that support it on Fedora Linux 45. The dynamic linker, or static startup routines, will activate Shadow Stack for any process whose binary and shared library dependencies are all built with Shadow Stack support, protecting processes by default whenever possible. Shadow Stacks are one of two Control-Flow Enforcement features introduced in Intel CET, alongside Indirect Branch Tracking (IBT), designed to defend against Return-Oriented Programming (ROP) and Jump-Oriented Programming (JOP) attacks by protecting return addresses. This Fedora change only covers enabling Shadow Stack support. Enabling Indirect Branch Tracking by default is not in scope. This change is backward compatible for the most part: `-fcf-protection` is a default compile time flag already enabled in `redhat-rpm-config` for Fedora since 2018 and thus the majority of binaries are already built with the appropriate markup. Thus, after this change is applied, applications whose dependencies carry Shadow Stack markup gain protection transparently while applications that load any non-compliant object at startup continue to run without Shadow Stack protection. The only new failure mode is when a Shadow Stack enabled process attempts to `dlopen` a non-compliant shared object at runtime, which results in a `dlopen` error that looks like `error: dlopen: /path/to/library.so: rebuild shared object with SHSTK support enabled`. Two mitigation strategies can be used, depending on the package: # Where the `dlopen`ed library can be fixed to include Shadow Stack support, the library is fixed and rebuilt with the appropriate markup. This is the preferred fix because it preserves Shadow Stack protection for the calling application. # Where the non-compliant code cannot be fixed in time, the calling application is opted out of Shadow Stack via glibc's [https://inbox.sourceware.org/libc-alpha/cover.1782444639.git.dj@redhat.com/T/#u System-Wide Tunables] configuration that can be shipped per-application as a configuration file. This disables Shadow Stack for that specific application while all other processes retain protection. == Feedback == No community feedback has been received yet. This section will be updated as feedback is collected. == Benefit to Fedora == This change provides hardware-enforced protection against Return-Oriented Programming (ROP) style attacks for the majority of Fedora binaries at negligible performance cost. Shadow Stacks are enforced by the CPU and do not require software instrumentation at runtime. The overhead is limited to maintaining a second copy of the return address stack in protected memory, which has no measurable impact on typical workloads. The change is transparent: compliant applications are protected without any code change, rebuild, or user action. Because `-fcf-protection` is already a default compile flag in Fedora, the majority of packages are already built with the appropriate ELF markup. Enabling Shadow Stack in the dynamic linker activates protection for these packages immediately. This also lays groundwork for enabling Indirect Branch Tracking (IBT) in a future release, which together with Shadow Stack would provide full Control-Flow Enforcement Technology (CET) protection. == Scope == * Proposal owners: The glibc maintainers will: # Apply a glibc downstream patch that reverts an upstream change that deactivates Shadow Stack support. # Include the upstream glibc [https://inbox.sourceware.org/libc-alpha/cover.1782444639.git.dj@redhat.com/T/#u System-Wide Tunables] feature, which has obtained upstream consensus and will be part of the next glibc release. This feature enables per-application opt-out via configuration files. # Ship `/etc/tunables.conf` with `include /etc/tunables.conf.d/*.conf` so that individual packages can drop in their own configuration files in order to opt-out. # Validate that SUID/SGID applications correctly sanitize tunables so that unprivileged users cannot disable Shadow Stack for privileged programs. # Open tracking bugs for all known incompatible packages. * Other developers: Most packages built with Fedora's default flags already produce Shadow Stack compatible binaries and no action is needed in this case. Packages that include hand-written assembly or build with different flags might ship ELF objects without Shadow Stack markup. Maintainers of such packages will need to make changes to their package to include Shadow Stack markup (e.g., annotate assembly routines). A special case is applications built with Shadow Stack support that currently `dlopen` shared objects built without it. These applications will encounter a runtime error at `dlopen` unless one of these fixes is applied: # The `dlopen`ed library is compiled with Shadow Stack support enabled. # The application opts out of Shadow Stack support using glibc's System-Wide Tunables feature. For example, a package named `app` providing `/usr/bin/app` would install `/etc/tunables.conf.d/app.conf` containing: <pre> [proc:/usr/bin/app] glibc.cpu.x86_shstk=off </pre> This disables Shadow Stack for that specific application while all other processes retain protection. The drop-in file is owned by the affected package's RPM, so it is added and removed with the package. Once the dependency is fixed, the package update removes the drop-in file and the application gains Shadow Stack protection. * Release engineering: [https://forge.fedoraproject.org/releng/tickets/issues/13388 #13388] Most objects are already built with support, and enablement is via a glibc update. For Rust, binary packages need to be rebuilt once the Rust dependency is in place. This can be done as part of the regularly scheduled Fedora 45 mass-rebuild. We will track this as part of the F45 GNU Toolchain release engineering ticket linked to above. * Policies and guidelines: No changes to packaging guidelines are required at this time. Default build configuration already builds objects with support and for the majority of packages, the change is transparent. * Trademark approval: N/A (not needed for this Change) * Alignment with the Fedora Strategy: This change is in line with Fedora's security posture and commitment to shipping secure-by-default systems. == Upgrade/compatibility impact == After upgrading to Fedora 45, Shadow Stack support will be enabled automatically for processes whose binary and all loaded shared libraries carry the appropriate markup. Processes that load any non-compliant shared object will have Shadow Stack silently disabled at startup. The only exception is applications that are fully Shadow Stack compliant at startup and then use `dlopen` to load a shared object without Shadow Stack markup at runtime. This will lead to a `dlopen` failure. However, affected applications can be configured to opt out of Shadow Stack protection, or have their dependencies fixed. Incompatible packages will be identified by scanning the Fedora package set for ELF objects missing the SHSTK property note, and by testing critical desktop and server workloads against the COPR repository with Shadow Stack enabled. Tracking bugs will be filed for all known incompatible packages. This work has already started and is being tracked in [https://bugzilla.redhat.com/show_bug.cgi?id=2458434 Bugzilla]. # Where the `dlopen`ed library is under Fedora's control, it can either be fixed and rebuilt with support, or the dependent package configured to run with Shadow Stack turned off as described in the Scope section above. # Users who encounter this problem with third party applications can work around it using the System-Wide Tunables feature as described earlier. == Early Testing (Optional) == A COPR repository with the updated glibc (Shadow Stack enabled) is available for Fedora 43, 44, and Rawhide for early testing: https://copr.fedorainfracloud.org/coprs/submachine/glibc-x86_64-SHSTK-Testing/ Do you require 'QA Blueprint' support? No <!-- Optional Step for System-Wide Changes only --> == How To Test == 1. Shadow Stack hardware support is available on Intel 11th Generation and newer CPUs, and AMD Zen3 and newer CPUs, so testing does not require any special hardware except a recent enough x86_64 processor. 2. Machine learning workloads that use GPU acceleration via AMD ROCm are a specific area of interest because the ROCm runtime libraries may lack Shadow Stack markup. Testing these workloads (e.g., pytorch with ROCm) requires access to AMD GPUs. 3. Once the runtime has been enabled for Shadow Stack, testing involves (a) verifying the shadow stack status of running processes (`cat /proc/$pid/status | grep x86_Thread_features`), and (b) verifying that there are no application errors or crashes due to incompatible binaries. 4. The majority of running processes should be protected, with Shadow Stack enabled. == User Experience == This change is transparent to users. No action is required to enable or configure support. Applications that are not compatible with Shadow Stack run without the protection; they continue to function normally but do not benefit from the additional security. In rare cases, an application that loads a non-compliant plugin at runtime may encounter a `dlopen` error. Known affected applications ship with a drop-in configuration file that prevents this. Users who encounter this with other applications can create a file in `/etc/tunables.conf.d/` to opt the application out, and then run `ldconfig`. == Dependencies == 1. Rust: The rust compiler needs to be able to generate Shadow Stack compatible binaries. This affects a significant part of the Fedora runtime and applications, including `rpm` and `firefox`. However, we are collaborating with the Rust team and have already tested a `rustc` change that enables emitting compatible binaries by default (without the use of any flags). The [https://bugzilla.redhat.com/show_bug.cgi?id=2196282 Rust Fedora Bug] tracks this. 2. Firefox and Chrome: Both browsers are currently not compatible with Shadow Stack although the Firefox binary and some objects are built with Shadow Stack enabled. Upstream work, in particular around their JIT compilers, as well as the rust tooling change mentioned above are needed in order to fix this. Until then, we propose to disable Shadow Stack protection flags when building Firefox. Both browsers will gain Shadow Stack protection once their upstream dependencies are resolved, at which point they can be rebuilt with protection turned on. == Contingency Plan == * Contingency mechanism: Downstream patch applied to glibc to enable Shadow Stacks by default in Fedora will be reverted. * Contingency deadline: No deadline. The patch can be reverted as late as necessary in the development cycle. * Blocks release? No. == Documentation == === Guide for package maintainers === ==== Checking an ELF object for CET support ==== Use `readelf` to inspect the GNU property note on any object file, shared library, or binary. e.g.: <pre> readelf -n /usr/lib64/libc.so.6 | grep 'IBT\|SHSTK' </pre> A fully compliant object shows both properties: <pre> Properties: x86 feature: IBT, SHSTK </pre> While this change only requires `SHSTK`, IBT (Indirect Branch Tracking) will be enabled in a future release and fixing both now avoids having to revisit these packages later. For this change, only `SHSTK` is required. An object with `IBT` but not `SHSTK` will still cause Shadow Stack to be disabled for the process. An object with `SHSTK` but not `IBT` is fully compliant with this change. Fixing both properties is recommended so that packages are ready for a future IBT enablement, but only `SHSTK` is needed now. The linker ANDs these bits across all inputs, so a single unmarked object will strip the property from the final binary. Packages are built by default with `-fcf-protection` enabled, so source files when compiled with default flags are automatically built with SHSTK/IBT support. However, hand-written assembly needs annotations in order to be built with the property enabled. This leads to situations where linking against objects built with hand-written assembly without the appropriate annotations strips the final binary or shared object of CET support. ==== Annotating a GAS assembly file ==== Hand-written `.S` files compiled through GCC do not automatically receive the CET property note. To fix this, add one line near the top of the file: <pre> #include <cet.h> </pre> For IBT compatibility, add `_CET_ENDBR` (also defined by `cet.h`) at the entry point of any function that may be reached via an indirect branch (e.g. function pointer): <pre> #include <cet.h> .text .globl my_handwritten_func .type my_handwritten_func, @function my_handwritten_func: _CET_ENDBR /* ..function body */ ret </pre> == Release Notes == -- Aoife Moloney Fedora Operations Architect Fedora Project Matrix: @amoloney:fedora.im IRC: amoloney -- _______________________________________________ devel-announce mailing list -- devel-announce@lists.fedoraproject.org To unsubscribe send an email to devel-announce-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/devel-announce@lists.fedoraproject.org Do not reply to spam, report it: https://forge.fedoraproject.org/infra/tickets/issues/new
No comments:
Post a Comment