Bug 2274882 - gcc: CONFIG_ARM64_BTI_KERNEL is disabled due to BTI instruction not being inserted for cross-section direct calls
Summary: gcc: CONFIG_ARM64_BTI_KERNEL is disabled due to BTI instruction not being ins...
Keywords:
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: aarch64
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: ARMTracker
TreeView+ depends on / blocked
 
Reported: 2024-04-13 09:56 UTC by Neal Gompa
Modified: 2026-01-20 22:09 UTC (History)
21 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Type: ---
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 106671 0 P3 WAITING aarch64: BTI instruction are not inserted for cross-section direct calls 2024-04-13 11:18:54 UTC
Sourceware 30076 0 P2 RESOLVED aarch64: stubs can add indirect branch that breaks BTI 2024-04-13 17:35:18 UTC

Description Neal Gompa 2024-04-13 09:56:21 UTC
It was discovered in the Fedora Asahi room that the Linux kernel has been silently disabling in-kernel BTI since 6.0 because of a bug in GCC that results in the BTI instruction not being inserted for cross-section direct calls. 

This seriously limits BTI protection that was enabled in Fedora 33: https://fedoraproject.org/wiki/Changes/Aarch64_PointerAuthentication

Reproducible: Always

Actual Results:  
CONFIG_ARM64_BTI_KERNEL=y is missing in the installed kernel config file

Expected Results:  
CONFIG_ARM64_BTI_KERNEL=y is found in the installed kernel config file

Upstream GCC bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106671
Upstream Linux commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c0a454b9044fdc99486853aa424e5b3be2107078

Comment 1 Florian Weimer 2024-04-13 17:35:18 UTC
I think Arm identified part of this as a binutils bug and fixed it?

Bug 30076 - aarch64: stubs can add indirect branch that breaks BTI
<https://sourceware.org/bugzilla/show_bug.cgi?id=30076>

The remaining issue concerns kernel module loading, which is rather tricky because AArch64 does not have BTI-exempt branches (x86-64 has a NOTRACK prefix for that).

Comment 2 jvoisin 2024-04-15 11:38:57 UTC
What's the problem with kernel module loading? The whole toolchain is controlled by Fedora, so modules can be built with BTI. As for proprietary ones, BTI can be disabled when such modules are loaded: it'll be a strict improvement over the current situation.

Comment 3 Florian Weimer 2024-04-15 11:46:43 UTC
As far as I understand it, kernel modules cannot always use direct calls to exported symbols. If the module is loaded too far away from the kernel code, an indirect call has to be used. This means that the called function becomes an indirect branch target and needs a BTI marker. However, Arm does not want to add markers to all (exported?) kernel functions proactively, as explained on the GCC bug.

(Note that kernel module loading is a dynamic linking mechanism, but it's very different from ELF dynamic linking we implement across binutils/gcc/glibc.)

Comment 4 Aoife Moloney 2025-04-25 10:26:12 UTC
This message is a reminder that Fedora Linux 40 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora Linux 40 on 2025-05-13.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
'version' of '40'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, change the 'version' 
to a later Fedora Linux version. Note that the version field may be hidden.
Click the "Show advanced fields" button if you do not see it.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora Linux 40 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora Linux, you are encouraged to change the 'version' to a later version
prior to this bug being closed.

Comment 5 Neal Gompa 2025-04-27 19:06:29 UTC
Still an issue now, marked as such.

Comment 6 Jeremy Linton 2025-12-11 18:14:34 UTC
I duplicated this yesterday too on F43 + mainline kernel by enlarging a module. I think the sequence is pretty specific to the -fpatchable-function-entry + static functions + inner module cross sectional calls. All of which are totally grey area, and the problematic sequence is 'entry: nop; nop; paciasp; ...' because it expects to only be directly called from functions inside the compilation unit rather than 'entry: bti c; nop; nop; paciasp; ...' that shows up for global symbols. I understand there was an ABI update, so I need to check and see if it actually addresses this case, which is at least largely caused by the patchable-function-entry because without it the paciasp correctly acts as the landing pad, although I guess in theory this could trigger with just static leaf functions, that for whatever reason, aren't inlined. I'm trying (and at the moment failing) to recreate this with a standalone userspace compilation. OTOH, I also suspect that the kernel module loader+ftrace could be tweaked to detect it and simply correct the call address and disable the ftrace point, which is what happens for a lot of static functions anyway as they tend to get inlined.


And to the earlier point about the BTI on fedora, this only affects the kernel's BTI usage, not the system as a whole where it remains in force.

Comment 7 Jeremy Linton 2025-12-11 20:18:23 UTC
As a FYI: The abi change: https://github.com/ARM-software/abi-aa/commit/0051acdaf08fdadaed5b206fb8977a65e53e59ba

Comment 8 Jeremy Linton 2025-12-11 20:31:42 UTC
And as a further clarification, the case I hit isn't for an exported symbol, its the __init entrypoint calling a static function within the module. So normally it would be just a direct bl to that function and doesn't need a landing pad, but because __init is in another section it needs a relocation... for a static function...

Comment 9 Jeremy Linton 2026-01-20 22:09:15 UTC
Since its been a while, I have a partial patch to the binutils/bfd code which detects this, and attempts to enable this with the stub/veneer. The idea is to add an additional 'force-veneer-for-cross-section' type command line option for partial -r ld links, which are used by the kernel for linking modules. This differs from how ld only inserts the veneers when finalized (shared or otherwise) based on the actual distance between the caller and the target function. In that case, ld actually does the right thing and goes ahead and inserts the bti landing pad and adjusts the caller's relocation. This can be simulated with a userspace executable by simply setting the offset for a section (in the linker script) far away from the text section being called and then doing the final link. 

So the last, and important missing piece above is that beyond the above requirements the final link must still be ET_REL to trigger this.


Note You need to log in before you can comment on or make changes to this bug.