* Re: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions [not found] <CANd6bgL=v+uReoQznRGKunZQApwV5ESHAQn2_MOt-J-=cPkm9g@mail.gmail.com> @ 2026-08-11 11:50 ` Jürgen Groß 2026-08-12 9:22 ` 李则良 0 siblings, 1 reply; 6+ messages in thread From: Jürgen Groß @ 2026-08-11 11:50 UTC (permalink / raw) To: 李则良, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86 Cc: H. Peter Anvin, Peter Zijlstra, Kees Cook, Nathan Chancellor, Josh Poimboeuf, linux-kernel [-- Attachment #1.1.1: Type: text/plain, Size: 2462 bytes --] On 11.08.26 13:41, 李则良 wrote: > From cd58bd112a6178593c6bc9c0f9b307d6897ae3d0 Mon Sep 17 00:00:00 2001 > From: Zeliang Li <lizeliang.linux@gmail.com <mailto:lizeliang.linux@gmail.com>> > Date: Tue, 11 Aug 2026 19:09:09 +0800 > Subject: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call > instructions > > When the kernel is compiled at a non-default optimization level > (e.g., KCFLAGS=-O1), the compiler may emit call instruction > patterns that differ from the expected 6-byte sequence > (opcodes 0xff 0x15 followed by a 32-bit displacement) checked > by alt_replace_call(). > > Currently this triggers a BUG() in apply_alternatives(), causing > an immediate kernel panic during early boot: > > kernel BUG at arch/x86/kernel/alternative.c:558! > > Instead of crashing, print a warning (once per boot) and preserve > the original call instruction verbatim. The call will execute as > compiled, without any alternatives patching applied. This is a > graceful degradation: the indirect call remains indirect, which is > functionally correct albeit slower than the direct-call patching > that was skipped. > > No change to normal -O2 builds, where call instructions continue > to match the expected pattern. > > Signed-off-by: Zeliang Li <lizeliang.linux@gmail.com > <mailto:lizeliang.linux@gmail.com>> Please don't send patches as HTML mails! > --- > arch/x86/kernel/alternative.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > index 62936a3bde19..0e3903e76b55 100644 > --- a/arch/x86/kernel/alternative.c > +++ b/arch/x86/kernel/alternative.c > @@ -554,8 +554,15 @@ static unsigned int alt_replace_call(u8 *instr, u8 > *insn_buff, struct alt_instr > if (a->instrlen != 6 || > instr[0] != CALL_RIP_REL_OPCODE || > instr[1] != CALL_RIP_REL_MODRM) { > - pr_err("ALT_FLAG_DIRECT_CALL set for unrecognized indirect call\n"); > - BUG(); > + static bool warned; > + > + if (!warned) { > + warned = true; > + pr_warn("%s: skipping unrecognized indirect call (instrlen=%d)\n", > + __func__, a->instrlen); > + } You are open coding pr_warn_once() here. > + memcpy(insn_buff, instr, a->instrlen); > + return a->instrlen; And now you are letting an indirect call survive which is not subject to any cpu bug mitigations. Juergen [-- Attachment #1.1.2: OpenPGP public key --] [-- Type: application/pgp-keys, Size: 3743 bytes --] [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 495 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions 2026-08-11 11:50 ` [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions Jürgen Groß @ 2026-08-12 9:22 ` 李则良 2026-08-12 11:00 ` Peter Zijlstra 0 siblings, 1 reply; 6+ messages in thread From: 李则良 @ 2026-08-12 9:22 UTC (permalink / raw) To: Jürgen Groß Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Kees Cook, Nathan Chancellor, Josh Poimboeuf, linux-kernel From cd58bd112a6178593c6bc9c0f9b307d6897ae3d0 Mon Sep 17 00:00:00 2001 From: Zeliang Li <lizeliang.linux@gmail.com> Date: Tue, 11 Aug 2026 19:09:09 +0800 Subject: [PATCH v2] x86/alternative: WARN and skip unrecognized indirect call only for non-O2 builds When the kernel is compiled at a non-default optimization level (e.g., KCFLAGS=-O1 or -O0), the compiler may emit call instruction patterns that differ from the expected 6-byte sequence (opcodes 0xff 0x15 followed by a 32-bit displacement) checked by alt_replace_call(). Currently this triggers a BUG() in apply_alternatives(), causing an immediate kernel panic during early boot. For official -O2 builds, the BUG() is appropriate and should be retained, as the kernel only guarantees correct operation at this optimization level[reference:0]. For non-standard optimization levels used for debugging purposes, crashing the kernel is too severe. Instead, issue a WARN_ONCE() and skip patching for this particular site, preserving the original indirect call. This approach balances safety for production builds with usability for developers using non-standard optimization levels. Signed-off-by: Zeliang Li <zeliang.li@linux@gmail.com> --- arch/x86/kernel/alternative.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 62936a3bde19..b8c9d0e1f2a3 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -554,8 +554,21 @@ static unsigned int alt_replace_call(u8 *instr, u8 *insn_buff, struct alt_instr if (a->instrlen != 6 || instr[0] != CALL_RIP_REL_OPCODE || instr[1] != CALL_RIP_REL_MODRM) { - pr_err("ALT_FLAG_DIRECT_CALL set for unrecognized indirect call\n"); - BUG(); + /* + * Unrecognized indirect call pattern. For -O2 builds this is a + * fatal error - the kernel only guarantees correct operation at + * this optimization level. For non-O2 builds (debugging), skip + * patching to avoid a boot-time crash. + */ +#ifdef __OPTIMIZE__ +#if __OPTIMIZE__ == 2 + BUG(); +#endif +#endif + WARN_ONCE(1, + "ALT_FLAG_DIRECT_CALL: unrecognized indirect call at %pS (instrlen=%d)\n", + instr, a->instrlen); + memcpy(insn_buff, instr, a->instrlen); + return a->instrlen; } Jürgen Groß <jgross@suse.com> 于2026年8月11日周二 19:50写道: > > On 11.08.26 13:41, 李则良 wrote: > > From cd58bd112a6178593c6bc9c0f9b307d6897ae3d0 Mon Sep 17 00:00:00 2001 > > From: Zeliang Li <lizeliang.linux@gmail.com <mailto:lizeliang.linux@gmail.com>> > > Date: Tue, 11 Aug 2026 19:09:09 +0800 > > Subject: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call > > instructions > > > > When the kernel is compiled at a non-default optimization level > > (e.g., KCFLAGS=-O1), the compiler may emit call instruction > > patterns that differ from the expected 6-byte sequence > > (opcodes 0xff 0x15 followed by a 32-bit displacement) checked > > by alt_replace_call(). > > > > Currently this triggers a BUG() in apply_alternatives(), causing > > an immediate kernel panic during early boot: > > > > kernel BUG at arch/x86/kernel/alternative.c:558! > > > > Instead of crashing, print a warning (once per boot) and preserve > > the original call instruction verbatim. The call will execute as > > compiled, without any alternatives patching applied. This is a > > graceful degradation: the indirect call remains indirect, which is > > functionally correct albeit slower than the direct-call patching > > that was skipped. > > > > No change to normal -O2 builds, where call instructions continue > > to match the expected pattern. > > > > Signed-off-by: Zeliang Li <lizeliang.linux@gmail.com > > <mailto:lizeliang.linux@gmail.com>> > > Please don't send patches as HTML mails! My apologies. I have now configured my Gmail to send plain text by default. Thank you for pointing this out. > > > --- > > arch/x86/kernel/alternative.c | 11 +++++++++-- > > 1 file changed, 9 insertions(+), 2 deletions(-) > > > > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > > index 62936a3bde19..0e3903e76b55 100644 > > --- a/arch/x86/kernel/alternative.c > > +++ b/arch/x86/kernel/alternative.c > > @@ -554,8 +554,15 @@ static unsigned int alt_replace_call(u8 *instr, u8 > > *insn_buff, struct alt_instr > > if (a->instrlen != 6 || > > instr[0] != CALL_RIP_REL_OPCODE || > > instr[1] != CALL_RIP_REL_MODRM) { > > - pr_err("ALT_FLAG_DIRECT_CALL set for unrecognized indirect call\n"); > > - BUG(); > > + static bool warned; > > + > > + if (!warned) { > > + warned = true; > > + pr_warn("%s: skipping unrecognized indirect call (instrlen=%d)\n", > > + __func__, a->instrlen); > > + } > > You are open coding pr_warn_once() here. > > > + memcpy(insn_buff, instr, a->instrlen); > > + return a->instrlen; > > And now you are letting an indirect call survive which is not subject to > any cpu bug mitigations. You are absolutely right – this was a serious oversight in my original patch. Simply preserving the indirect call would bypass retpoline and other CPU mitigations, which is unacceptable for production kernels. To address this, I have revised the patch to distinguish between optimization levels: - For -O2 builds (the officially supported configuration), the existing BUG() is retained, as the kernel only guarantees correct operation at this level. - For non-standard -O1/-O0 builds (typically used for debugging), we issue a WARN_ONCE() and skip patching. This avoids a boot-time crash for developers, while keeping the production (-O2) path fully secure. This way, the security impact is limited to non-standard builds, which are outside the official support scope and are already considered "developer‑only". > > > Juergen > -- KISS == Keep it simple,stupid~:-) http://lizeliang.org ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions 2026-08-12 9:22 ` 李则良 @ 2026-08-12 11:00 ` Peter Zijlstra 2026-08-12 11:24 ` H. Peter Anvin 2026-08-12 17:14 ` 李则良 0 siblings, 2 replies; 6+ messages in thread From: Peter Zijlstra @ 2026-08-12 11:00 UTC (permalink / raw) To: 李则良 Cc: Jürgen Groß, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Kees Cook, Nathan Chancellor, Josh Poimboeuf, linux-kernel On Wed, Aug 12, 2026 at 05:22:14PM +0800, 李则良 wrote: > From cd58bd112a6178593c6bc9c0f9b307d6897ae3d0 Mon Sep 17 00:00:00 2001 > From: Zeliang Li <lizeliang.linux@gmail.com> > Date: Tue, 11 Aug 2026 19:09:09 +0800 > Subject: [PATCH v2] x86/alternative: WARN and skip unrecognized indirect call > only for non-O2 builds > > When the kernel is compiled at a non-default optimization level > (e.g., KCFLAGS=-O1 or -O0), the compiler may emit call instruction > patterns that differ from the expected 6-byte sequence > (opcodes 0xff 0x15 followed by a 32-bit displacement) checked > by alt_replace_call(). I don't think we want to cater for this. But what actual instruction sequences is it emitting? ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions 2026-08-12 11:00 ` Peter Zijlstra @ 2026-08-12 11:24 ` H. Peter Anvin 2026-08-12 15:30 ` Borislav Petkov 2026-08-12 17:14 ` 李则良 1 sibling, 1 reply; 6+ messages in thread From: H. Peter Anvin @ 2026-08-12 11:24 UTC (permalink / raw) To: Peter Zijlstra, 李则良 Cc: Jürgen Groß, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, Kees Cook, Nathan Chancellor, Josh Poimboeuf, linux-kernel On August 12, 2026 4:00:23 AM PDT, Peter Zijlstra <peterz@infradead.org> wrote: >On Wed, Aug 12, 2026 at 05:22:14PM +0800, 李则良 wrote: >> From cd58bd112a6178593c6bc9c0f9b307d6897ae3d0 Mon Sep 17 00:00:00 2001 >> From: Zeliang Li <lizeliang.linux@gmail.com> >> Date: Tue, 11 Aug 2026 19:09:09 +0800 >> Subject: [PATCH v2] x86/alternative: WARN and skip unrecognized indirect call >> only for non-O2 builds >> >> When the kernel is compiled at a non-default optimization level >> (e.g., KCFLAGS=-O1 or -O0), the compiler may emit call instruction >> patterns that differ from the expected 6-byte sequence >> (opcodes 0xff 0x15 followed by a 32-bit displacement) checked >> by alt_replace_call(). > >I don't think we want to cater for this. But what actual instruction >sequences is it emitting? I'm kind of surprised the kernel compiles with -O0 at all; it certainly didn't used to. -Og was created for a reason. That being said, if it helps someone debug a problem as long as the kernel also screams "bloody murder don't use me in production" it might be useful. Honestly, thinking about it, an "unsafe_debug=..." or similar kernel command line option might be justified for things like this; by requiring an active user step to enable the unsafe behavior it should make it much harder for something to sneak into production. -hpa ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions 2026-08-12 11:24 ` H. Peter Anvin @ 2026-08-12 15:30 ` Borislav Petkov 0 siblings, 0 replies; 6+ messages in thread From: Borislav Petkov @ 2026-08-12 15:30 UTC (permalink / raw) To: H. Peter Anvin Cc: Peter Zijlstra, 李则良, Jürgen Groß, Thomas Gleixner, Ingo Molnar, Dave Hansen, x86, Kees Cook, Nathan Chancellor, Josh Poimboeuf, linux-kernel On Wed, Aug 12, 2026 at 04:24:37AM -0700, H. Peter Anvin wrote: > >I don't think we want to cater for this. But what actual instruction > >sequences is it emitting? > > I'm kind of surprised the kernel compiles with -O0 at all; it certainly didn't used to. -Og was created for a reason. I'm with PeterZ on this. If you hack the tree to modify KCFLAGS, then you get to keep the pieces too. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions 2026-08-12 11:00 ` Peter Zijlstra 2026-08-12 11:24 ` H. Peter Anvin @ 2026-08-12 17:14 ` 李则良 1 sibling, 0 replies; 6+ messages in thread From: 李则良 @ 2026-08-12 17:14 UTC (permalink / raw) To: Peter Zijlstra Cc: Jürgen Groß, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Kees Cook, Nathan Chancellor, Josh Poimboeuf, linux-kernel > > I don't think we want to cater for this. But what actual instruction > sequences is it emitting? This is the scene that triggers the bug, which can be perfectly reproduced when KCFLAGS=-O1. [ 0.111827] SMP alternatives: ALT_FLAG_DIRECT_CALL set for unrecognized indirect call [ 0.112083] ------------[ cut here ]------------ [ 0.112417] kernel BUG at arch/x86/kernel/alternative.c:558! [ 0.113080] Oops: invalid opcode: 0000 [#1] SMP NOPTI [ 0.113424] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.2.0-rc7-00016-g3d6d817622b0-dirty #2 PREEMPT(lazy) [ 0.114077] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014 [ 0.114077] RIP: 0010:apply_alternatives+0x3a6/0x540 [ 0.114077] Code: 8d 04 80 89 95 d1 fe ff ff e9 dd fe ff ff 48 c7 c7 f8 88 9d 82 e8 ea 94 0d 00 90 0f 0b 48 c7 c7 50 89 9d 82 e8 db 94 0d 00 90 <0f> 0b 80 7d ce 00 75 0d 41 80 7e 0d 00 0f 84 14 ff ff ff eb 62 48 [ 0.114077] RSP: 0000:ffffffff82c03d60 EFLAGS: 00010246 [ 0.114077] RAX: 0000000000000049 RBX: ffffffff831dae1c RCX: 0000000000000003 [ 0.114077] RDX: 0000000000000000 RSI: ffffffff82d3cd08 RDI: 0000000000000001 [ 0.114077] RBP: ffffffff82c03ea8 R08: 0000000000000000 R09: 205d373238313131 [ 0.114077] R10: 7265746c6120504d R11: 65746c6120504d53 R12: ffffffff831e116c [ 0.114077] R13: ffffffff82ee2880 R14: ffffffff831dae0e R15: ffffffff831e1f58 [ 0.114077] FS: 0000000000000000(0000) GS:ffff8882f4a18000(0000) knlGS:0000000000000000 [ 0.114077] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.114077] CR2: ffff88827ffff000 CR3: 0000000002c30001 CR4: 0000000000770ef0 [ 0.114077] PKRU: 55555554 [ 0.114077] Call Trace: [ 0.114077] <TASK> [ 0.114077] ? insn_get_sib+0x21/0x80 [ 0.114077] ? early_fixup_exception+0x85/0xa0 [ 0.114077] alternative_instructions+0x76/0x110 [ 0.114077] arch_cpu_finalize_init+0x113/0x170 [ 0.114077] start_kernel+0x794/0x820 [ 0.114077] x86_64_start_reservations+0x28/0x30 [ 0.114077] x86_64_start_kernel+0xdc/0xe0 [ 0.114077] common_startup_64+0x13e/0x158 [ 0.114077] RIP: 1f0f:0x2e66000000000084 [ 0.114077] Code: Unable to access opcode bytes at 0x2e6600000000005a. [ 0.114077] RSP: 0000:00841f0f2e660000 EFLAGS: 841f0f2e66 ORIG_RAX: 1f0f2e6600000000 [ 0.114077] RAX: 1f0f2e6600000000 RBX: 1f0f2e6600000000 RCX: 2e66000000000084 [ 0.114077] RDX: 0000000000841f0f RSI: 000000841f0f2e66 RDI: 00841f0f2e660000 [ 0.114077] RBP: 00841f0f2e660000 R08: 00841f0f2e660000 R09: 000000841f0f2e66 [ 0.114077] R10: 0000000000841f0f R11: 2e66000000000084 R12: 000000841f0f2e66 [ 0.114077] R13: 0000000000841f0f R14: 2e66000000000084 R15: 1f0f2e6600000000 [ 0.114077] </TASK> [ 0.114077] Modules linked in: [ 0.114078] ---[ end trace 0000000000000000 ]--- [ 0.114405] RIP: 0010:apply_alternatives+0x3a6/0x540 [ 0.115078] Code: 8d 04 80 89 95 d1 fe ff ff e9 dd fe ff ff 48 c7 c7 f8 88 9d 82 e8 ea 94 0d 00 90 0f 0b 48 c7 c7 50 89 9d 82 e8 db 94 0d 00 90 <0f> 0b 80 7d ce 00 75 0d 41 80 7e 0d 00 0f 84 14 ff ff ff eb 62 48 [ 0.116078] RSP: 0000:ffffffff82c03d60 EFLAGS: 00010246 [ 0.116456] RAX: 0000000000000049 RBX: ffffffff831dae1c RCX: 0000000000000003 [ 0.117077] RDX: 0000000000000000 RSI: ffffffff82d3cd08 RDI: 0000000000000001 [ 0.117589] RBP: ffffffff82c03ea8 R08: 0000000000000000 R09: 205d373238313131 [ 0.118077] R10: 7265746c6120504d R11: 65746c6120504d53 R12: ffffffff831e116c [ 0.118585] R13: ffffffff82ee2880 R14: ffffffff831dae0e R15: ffffffff831e1f58 [ 0.119077] FS: 0000000000000000(0000) GS:ffff8882f4a18000(0000) knlGS:0000000000000000 [ 0.119642] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.120077] CR2: ffff88827ffff000 CR3: 0000000002c30001 CR4: 0000000000770ef0 [ 0.120537] PKRU: 55555554 [ 0.121078] Kernel panic - not syncing: Attempted to kill the idle task! [ 0.121545] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]--- -- KISS == Keep it simple,stupid~:-) http://lizeliang.org ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-12 17:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CANd6bgL=v+uReoQznRGKunZQApwV5ESHAQn2_MOt-J-=cPkm9g@mail.gmail.com>
2026-08-11 11:50 ` [PATCH] x86/alternatives: gracefully skip unrecognized indirect call instructions Jürgen Groß
2026-08-12 9:22 ` 李则良
2026-08-12 11:00 ` Peter Zijlstra
2026-08-12 11:24 ` H. Peter Anvin
2026-08-12 15:30 ` Borislav Petkov
2026-08-12 17:14 ` 李则良
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.