LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH net 6/8] ipvs: fix shift-out-of-bounds in ip_vs_rht_desired_size

To: netfilter-devel@xxxxxxxxxxxxxxx
Subject: [PATCH net 6/8] ipvs: fix shift-out-of-bounds in ip_vs_rht_desired_size
Cc: davem@xxxxxxxxxxxxx, netdev@xxxxxxxxxxxxxxx, kuba@xxxxxxxxxx, pabeni@xxxxxxxxxx, edumazet@xxxxxxxxxx, fw@xxxxxxxxx, horms@xxxxxxxxxx, ja@xxxxxx, longman@xxxxxxxxxx, lvs-devel@xxxxxxxxxxxxxxx
From: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
Date: Tue, 5 May 2026 02:16:46 +0200
From: Julian Anastasov <ja@xxxxxx>

Calling roundup_pow_of_two() with 0 has undefined result:

UBSAN: shift-out-of-bounds in ./include/linux/log2.h:57:13
shift exponent 64 is too large for 64-bit type 'unsigned long'
CPU: 1 UID: 0 PID: 77 Comm: kworker/u8:4 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 
04/18/2026
Workqueue: events_unbound conn_resize_work_handler
Call Trace:
 <TASK>
 dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
 ubsan_epilogue+0xa/0x30 lib/ubsan.c:233
 __ubsan_handle_shift_out_of_bounds+0x385/0x410 lib/ubsan.c:494
 __roundup_pow_of_two include/linux/log2.h:57 [inline]
 ip_vs_rht_desired_size+0x2cf/0x410 net/netfilter/ipvs/ip_vs_core.c:240
 ip_vs_conn_desired_size net/netfilter/ipvs/ip_vs_conn.c:765 [inline]
 conn_resize_work_handler+0x1b6/0x14c0 net/netfilter/ipvs/ip_vs_conn.c:822
 process_one_work kernel/workqueue.c:3302 [inline]
 process_scheduled_works+0xb5d/0x1860 kernel/workqueue.c:3385
 worker_thread+0xa53/0xfc0 kernel/workqueue.c:3466
 kthread+0x388/0x470 kernel/kthread.c:436
 ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
 </TASK>

Reported-by: syzbot+217f1db9c791e27fe54a@xxxxxxxxxxxxxxxxxxxxxxxxx
Fixes: b655388111cf ("ipvs: add resizable hash tables")
Signed-off-by: Julian Anastasov <ja@xxxxxx>
Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 net/netfilter/ipvs/ip_vs_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index f5b7a2047291..d40b404c1bf6 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -237,7 +237,7 @@ int ip_vs_rht_desired_size(struct netns_ipvs *ipvs, struct 
ip_vs_rht *t, int n,
 {
        if (!t)
                return 1 << min_bits;
-       n = roundup_pow_of_two(n);
+       n = n > 0 ? roundup_pow_of_two(n) : 1;
        if (lfactor < 0) {
                int factor = min(-lfactor, max_bits);
 
-- 
2.47.3



<Prev in Thread] Current Thread [Next in Thread>