* [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit
@ 2022-10-31 11:36 Gaosheng Cui
2022-10-31 17:42 ` Sean Christopherson
0 siblings, 1 reply; 7+ messages in thread
From: Gaosheng Cui @ 2022-10-31 11:36 UTC (permalink / raw)
To: seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa,
cuigaosheng1; +Cc: kvm
Shifting signed 32-bit value by 31 bits is undefined, so changing
significant bit to unsigned. The UBSAN warning calltrace like below:
UBSAN: shift-out-of-bounds in arch/x86/kvm/reverse_cpuid.h:101:11
left shift of 1 by 31 places cannot be represented in type 'int'
Call Trace:
<TASK>
dump_stack_lvl+0x7d/0xa5
dump_stack+0x15/0x1b
ubsan_epilogue+0xe/0x4e
__ubsan_handle_shift_out_of_bounds+0x1e7/0x20c
kvm_set_cpu_caps+0x15a/0x770 [kvm]
hardware_setup+0xa6f/0xdfe [kvm_intel]
kvm_arch_hardware_setup+0x100/0x1e80 [kvm]
kvm_init+0xdb/0x560 [kvm]
vmx_init+0x161/0x2b4 [kvm_intel]
do_one_initcall+0x76/0x430
do_init_module+0x61/0x28a
load_module+0x1f82/0x2e50
__do_sys_finit_module+0xf8/0x190
__x64_sys_finit_module+0x23/0x30
do_syscall_64+0x58/0x80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
</TASK>
Fixes: a7c48c3f56db ("KVM: x86: Expand build-time assertion on reverse CPUID usage")
Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
---
arch/x86/kvm/reverse_cpuid.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h
index a19d473d0184..ebd6b621d3b8 100644
--- a/arch/x86/kvm/reverse_cpuid.h
+++ b/arch/x86/kvm/reverse_cpuid.h
@@ -98,7 +98,7 @@ static __always_inline u32 __feature_bit(int x86_feature)
x86_feature = __feature_translate(x86_feature);
reverse_cpuid_check(x86_feature / 32);
- return 1 << (x86_feature & 31);
+ return 1U << (x86_feature & 31);
}
#define feature_bit(name) __feature_bit(X86_FEATURE_##name)
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit 2022-10-31 11:36 [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit Gaosheng Cui @ 2022-10-31 17:42 ` Sean Christopherson 2022-10-31 20:27 ` H. Peter Anvin 2022-10-31 20:54 ` Peter Zijlstra 0 siblings, 2 replies; 7+ messages in thread From: Sean Christopherson @ 2022-10-31 17:42 UTC (permalink / raw) To: Gaosheng Cui; +Cc: pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa, kvm On Mon, Oct 31, 2022, Gaosheng Cui wrote: > Shifting signed 32-bit value by 31 bits is undefined, so changing > significant bit to unsigned. The UBSAN warning calltrace like below: > > UBSAN: shift-out-of-bounds in arch/x86/kvm/reverse_cpuid.h:101:11 > left shift of 1 by 31 places cannot be represented in type 'int' PeterZ is contending that this isn't actually undefined behavior given how the kernel is compiled[*]. That said, I would be in favor of replacing the open-coded shift with BIT() to make the code a bit more self-documenting, and that would naturally fix this maybe-undefined-behavior issue. [*] https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net > --- > arch/x86/kvm/reverse_cpuid.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h > index a19d473d0184..ebd6b621d3b8 100644 > --- a/arch/x86/kvm/reverse_cpuid.h > +++ b/arch/x86/kvm/reverse_cpuid.h > @@ -98,7 +98,7 @@ static __always_inline u32 __feature_bit(int x86_feature) > x86_feature = __feature_translate(x86_feature); > > reverse_cpuid_check(x86_feature / 32); > - return 1 << (x86_feature & 31); > + return 1U << (x86_feature & 31); > } > > #define feature_bit(name) __feature_bit(X86_FEATURE_##name) > -- > 2.25.1 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit 2022-10-31 17:42 ` Sean Christopherson @ 2022-10-31 20:27 ` H. Peter Anvin 2022-11-01 2:37 ` cuigaosheng 2022-10-31 20:54 ` Peter Zijlstra 1 sibling, 1 reply; 7+ messages in thread From: H. Peter Anvin @ 2022-10-31 20:27 UTC (permalink / raw) To: Sean Christopherson, Gaosheng Cui Cc: pbonzini, tglx, mingo, bp, dave.hansen, x86, kvm On October 31, 2022 10:42:56 AM PDT, Sean Christopherson <seanjc@google.com> wrote: >On Mon, Oct 31, 2022, Gaosheng Cui wrote: >> Shifting signed 32-bit value by 31 bits is undefined, so changing >> significant bit to unsigned. The UBSAN warning calltrace like below: >> >> UBSAN: shift-out-of-bounds in arch/x86/kvm/reverse_cpuid.h:101:11 >> left shift of 1 by 31 places cannot be represented in type 'int' > >PeterZ is contending that this isn't actually undefined behavior given how the >kernel is compiled[*]. That said, I would be in favor of replacing the open-coded >shift with BIT() to make the code a bit more self-documenting, and that would >naturally fix this maybe-undefined-behavior issue. > >[*] https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net > >> --- >> arch/x86/kvm/reverse_cpuid.h | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h >> index a19d473d0184..ebd6b621d3b8 100644 >> --- a/arch/x86/kvm/reverse_cpuid.h >> +++ b/arch/x86/kvm/reverse_cpuid.h >> @@ -98,7 +98,7 @@ static __always_inline u32 __feature_bit(int x86_feature) >> x86_feature = __feature_translate(x86_feature); >> >> reverse_cpuid_check(x86_feature / 32); >> - return 1 << (x86_feature & 31); >> + return 1U << (x86_feature & 31); >> } >> >> #define feature_bit(name) __feature_bit(X86_FEATURE_##name) >> -- >> 2.25.1 >> One really ought to change the input to unsigned, though, and I would argue >> 5 would be more idiomatic than / 32; / goes with % whereas >> goes with &; a mishmash is just ugly AF. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit 2022-10-31 20:27 ` H. Peter Anvin @ 2022-11-01 2:37 ` cuigaosheng 0 siblings, 0 replies; 7+ messages in thread From: cuigaosheng @ 2022-11-01 2:37 UTC (permalink / raw) To: H. Peter Anvin, Sean Christopherson, peterz Cc: pbonzini, tglx, mingo, bp, dave.hansen, x86, kvm Thanks for taking time to review the patch! > PeterZ is contending that this isn't actually undefined behavior given how the > kernel is compiled[*]. That said, I would be in favor of replacing the open-coded > shift with BIT() to make the code a bit more self-documenting, and that would > naturally fix this maybe-undefined-behavior issue. > > [*]https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net I have made a patch v2 and submitted it, replacing the open-coded shift with BIT(). > One really ought to change the input to unsigned, though, and I would argue >> 5 would be more idiomatic than / 32; / goes with % whereas >> goes with &; a mishmash is just ugly AF. > . I have changed the input to unsigned in patch v2, and replaced "/ 32" with "argue >> 5". On 2022/11/1 4:27, H. Peter Anvin wrote: > On October 31, 2022 10:42:56 AM PDT, Sean Christopherson <seanjc@google.com> wrote: >> On Mon, Oct 31, 2022, Gaosheng Cui wrote: >>> Shifting signed 32-bit value by 31 bits is undefined, so changing >>> significant bit to unsigned. The UBSAN warning calltrace like below: >>> >>> UBSAN: shift-out-of-bounds in arch/x86/kvm/reverse_cpuid.h:101:11 >>> left shift of 1 by 31 places cannot be represented in type 'int' >> PeterZ is contending that this isn't actually undefined behavior given how the >> kernel is compiled[*]. That said, I would be in favor of replacing the open-coded >> shift with BIT() to make the code a bit more self-documenting, and that would >> naturally fix this maybe-undefined-behavior issue. >> >> [*] https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net >> >>> --- >>> arch/x86/kvm/reverse_cpuid.h | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h >>> index a19d473d0184..ebd6b621d3b8 100644 >>> --- a/arch/x86/kvm/reverse_cpuid.h >>> +++ b/arch/x86/kvm/reverse_cpuid.h >>> @@ -98,7 +98,7 @@ static __always_inline u32 __feature_bit(int x86_feature) >>> x86_feature = __feature_translate(x86_feature); >>> >>> reverse_cpuid_check(x86_feature / 32); >>> - return 1 << (x86_feature & 31); >>> + return 1U << (x86_feature & 31); >>> } >>> >>> #define feature_bit(name) __feature_bit(X86_FEATURE_##name) >>> -- >>> 2.25.1 >>> > One really ought to change the input to unsigned, though, and I would argue >> 5 would be more idiomatic than / 32; / goes with % whereas >> goes with &; a mishmash is just ugly AF. > . ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit 2022-10-31 17:42 ` Sean Christopherson 2022-10-31 20:27 ` H. Peter Anvin @ 2022-10-31 20:54 ` Peter Zijlstra 2022-11-02 17:54 ` Paolo Bonzini 1 sibling, 1 reply; 7+ messages in thread From: Peter Zijlstra @ 2022-10-31 20:54 UTC (permalink / raw) To: Sean Christopherson Cc: Gaosheng Cui, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa, kvm On Mon, Oct 31, 2022 at 05:42:56PM +0000, Sean Christopherson wrote: > On Mon, Oct 31, 2022, Gaosheng Cui wrote: > > Shifting signed 32-bit value by 31 bits is undefined, so changing > > significant bit to unsigned. The UBSAN warning calltrace like below: > > > > UBSAN: shift-out-of-bounds in arch/x86/kvm/reverse_cpuid.h:101:11 > > left shift of 1 by 31 places cannot be represented in type 'int' > > PeterZ is contending that this isn't actually undefined behavior given how the > kernel is compiled[*]. That said, I would be in favor of replacing the open-coded > shift with BIT() to make the code a bit more self-documenting, and that would > naturally fix this maybe-undefined-behavior issue. > > [*] https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net I'm definitely in favour of updating this code; both your suggestion and hpa's suggestion look like sane changes. But I do feel that whatever UBSAN thing generated this warning needs to be fixed too. I'm fine with the compiler warning about this code -- but it must not claim undefined behaviour given the compiler flags we use. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit 2022-10-31 20:54 ` Peter Zijlstra @ 2022-11-02 17:54 ` Paolo Bonzini 2022-11-02 20:56 ` Peter Zijlstra 0 siblings, 1 reply; 7+ messages in thread From: Paolo Bonzini @ 2022-11-02 17:54 UTC (permalink / raw) To: Peter Zijlstra, Sean Christopherson Cc: Gaosheng Cui, tglx, mingo, bp, dave.hansen, x86, hpa, kvm On 10/31/22 21:54, Peter Zijlstra wrote: >> PeterZ is contending that this isn't actually undefined behavior given how the >> kernel is compiled[*]. That said, I would be in favor of replacing the open-coded >> shift with BIT() to make the code a bit more self-documenting, and that would >> naturally fix this maybe-undefined-behavior issue. >> >> [*]https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net > I'm definitely in favour of updating this code; both your suggestion and > hpa's suggestion look like sane changes. But I do feel that whatever > UBSAN thing generated this warning needs to be fixed too. > > I'm fine with the compiler warning about this code -- but it must not > claim undefined behaviour given the compiler flags we use. Yes, the compiler is buggy here (see old bug report for GCC, now fixed, at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68418). I cannot even reproduce the problem with the simple userspace testcase #include <stdlib.h> int main(int argc) { int i = argc << 31; exit(i < 0); } on either GCC 12 or clang 15. Paolo ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit 2022-11-02 17:54 ` Paolo Bonzini @ 2022-11-02 20:56 ` Peter Zijlstra 0 siblings, 0 replies; 7+ messages in thread From: Peter Zijlstra @ 2022-11-02 20:56 UTC (permalink / raw) To: Paolo Bonzini Cc: Sean Christopherson, Gaosheng Cui, tglx, mingo, bp, dave.hansen, x86, hpa, kvm On Wed, Nov 02, 2022 at 06:54:22PM +0100, Paolo Bonzini wrote: > On 10/31/22 21:54, Peter Zijlstra wrote: > > > PeterZ is contending that this isn't actually undefined behavior given how the > > > kernel is compiled[*]. That said, I would be in favor of replacing the open-coded > > > shift with BIT() to make the code a bit more self-documenting, and that would > > > naturally fix this maybe-undefined-behavior issue. > > > > > > [*]https://lore.kernel.org/all/Y1%2FAaJOcgIc%2FINtv@hirez.programming.kicks-ass.net > > I'm definitely in favour of updating this code; both your suggestion and > > hpa's suggestion look like sane changes. But I do feel that whatever > > UBSAN thing generated this warning needs to be fixed too. > > > > I'm fine with the compiler warning about this code -- but it must not > > claim undefined behaviour given the compiler flags we use. > > Yes, the compiler is buggy here (see old bug report for GCC, now fixed, at > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68418). > > I cannot even reproduce the problem with the simple userspace testcase > > #include <stdlib.h> > int main(int argc) { > int i = argc << 31; > exit(i < 0); > } > > on either GCC 12 or clang 15. Perhaps we should have the UBSAN splat include the compiler-version used... because clearly someone is using ancient crap here. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-11-02 20:56 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-10-31 11:36 [PATCH] KVM: x86: fix undefined behavior in bit shift for __feature_bit Gaosheng Cui 2022-10-31 17:42 ` Sean Christopherson 2022-10-31 20:27 ` H. Peter Anvin 2022-11-01 2:37 ` cuigaosheng 2022-10-31 20:54 ` Peter Zijlstra 2022-11-02 17:54 ` Paolo Bonzini 2022-11-02 20:56 ` Peter Zijlstra
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox