From: Huazhao Chen Date: Mon, 16 Sep 2025 10:00:00 +0800 Subject: [PATCH] ceph: Fix potential undefined behavior in crush_ln() with GCC 11.1.0 When compiled with GCC 11.1.0 and -march=x86-64-v3 -O1 optimization flags, __builtin_clz() may generate BSR instructions without proper zero handling. The BSR instruction has undefined behavior when the source operand is zero, which could occur when (x & 0x1FFFF) equals 0 in the crush_ln() function. This issue is documented in GCC bug 101175: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101175 The problematic code path occurs in crush_ln() when: - x is incremented from xin - (x & 0x18000) == 0 (condition for the optimization) - (x & 0x1FFFF) == 0 (zero argument to __builtin_clz) Add a zero check before calling __builtin_clz() to ensure defined behavior across all GCC versions and optimization levels. Signed-off-by: Huazhao Chen --- net/ceph/crush/mapper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c index 1234567..abcdef0 100644 --- a/net/ceph/crush/mapper.c +++ b/net/ceph/crush/mapper.c @@ -262,7 +262,8 @@ static __u64 crush_ln(unsigned int xin) * do it in one step instead of iteratively */ if (!(x & 0x18000)) { - int bits = __builtin_clz(x & 0x1FFFF) - 16; + u32 masked = x & 0x1FFFF; + int bits = masked ? __builtin_clz(masked) - 16 : 16; x <<= bits; iexpon = 15 - bits; } -- 2.40.1