Re: [PATCH] arm64/module: Fix livepatch BTI exceptions with Clang 21+
Josh Poimboeuf <[email protected]>
| Newsgroups | org.kernel.vger.live-patching,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <e5q2mvqtf6iw4lco55uny5ffhppw6vlflxguhc4gg5nm3zdvmo@zs6rw7iov5qc> |
On Mon, Aug 10, 2026 at 11:31:10AM +0100, Will Deacon wrote: > On Fri, Aug 07, 2026 at 02:46:11PM -0700, Josh Poimboeuf wrote: > > The following BTI exception was seen when loading a livepatch module: > > > > Internal error: Oops - BTI: 0000000036000001 [#1] SMP > > pstate: 634004c9 (nZCv daIF +PAN -UAO +TCO +DIT -SSBS BTYPE=jc) > > pc : kill_orphaned_pgrp+0x0/0x150 > > lr : do_exit+0x498/0xaf0 [livepatch_combined] > > > > The problem is that the patch module's do_exit() is branching to a > > static function in vmlinux using a module PLT veneer (indirect branch), > > but the target function doesn't have a BTI landing pad. > > > > Clang 21+ omits the landing pad for static functions which can only be > > reached by a direct branch. That's fine for ordinary modules which only > > branch to global exported functions. But livepatch modules use klp > > relocations to reference arbitrary kernel symbols, and with > > CONFIG_RANDOMIZE_MODULE_REGION_FULL the module is far enough from the > > kernel that every R_AARCH64_CALL26 needs a PLT. > > > > RET is exempt from BTI checking, so use it instead of BR when the target > > has no landing pad, similar to what ftrace and BPF do. > > Hmm, doesn't that somewhat undermine the purpose of using BTI in the > kernel? Now we're going to create PLTs that can branch to arbitrary > addresses. Yes, but just to clarify: - Only with livepatch modules loaded (and we can add an is_livepatch_module() check). - Only a small minority of livepatch klp relocations need it. - There are already other instances of "ret <reg>" in the kernel in ftrace, BPF, and kvm. > > This was found by testing with klp-build and Clang 21, but the issue is > > not specific to klp-build. It's inherent to any livepatch module use of > > klp relocations. > > > > Previous tests with Clang 20 did not show this problem, as older Clang > > unconditionally emits "bti c" for every C function. > > Is there an option to restore that behaviour if CONFIG_LIVEPATCH=y? > Otherwise, I think I'd be more inclined to add yet-another dependency > to CONFIG_ARM64_BTI_KERNEL so it's disabled if LIVEPATCH is selected. Hm, looking deeper, is BTI just fundamentally broken now, independent of livepatch? config ARM64_BTI_KERNEL ... # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106671 depends on !CC_IS_GCC ... AFAICT, the reason for the "depends on !CC_IS_GCC" is that GCC was already doing the exact same thing Clang is now doing: namely, omitting BTI for static functions that don't have a pointer taken to them. So Clang 21+ now has the original GCC edge case: an .init.text direct branching to a .text function which happens to be allocated >= 128MB away and which doesn't have BTI. In which case I think to properly support BTI going forward we would need two "veneers"? Either that or remove BTI kernel support altogether. -- Josh