]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: gro_cells: fix lock imbalance in gro_cells_receive()
authorEric Dumazet <edumazet@google.com>
Mon, 20 Oct 2025 16:11:14 +0000 (16:11 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 22 Oct 2025 00:41:09 +0000 (17:41 -0700)
syzbot found that the local_unlock_nested_bh() call was
missing in some cases.

WARNING: possible recursive locking detected
syzkaller #0 Not tainted
--------------------------------------------
syz.2.329/7421 is trying to acquire lock:
 ffffe8ffffd48888 ((&cell->bh_lock)){+...}-{3:3}, at: spin_lock include/linux/spinlock_rt.h:44 [inline]
 ffffe8ffffd48888 ((&cell->bh_lock)){+...}-{3:3}, at: gro_cells_receive+0x404/0x790 net/core/gro_cells.c:30

but task is already holding lock:
 ffffe8ffffd48888 ((&cell->bh_lock)){+...}-{3:3}, at: spin_lock include/linux/spinlock_rt.h:44 [inline]
 ffffe8ffffd48888 ((&cell->bh_lock)){+...}-{3:3}, at: gro_cells_receive+0x404/0x790 net/core/gro_cells.c:30

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock((&cell->bh_lock));
  lock((&cell->bh_lock));

 *** DEADLOCK ***

Given the introduction of @have_bh_lock variable, it seems the author
intent was to have the local_unlock_nested_bh() after the @unlock label.

Fixes: 25718fdcbdd2 ("net: gro_cells: Use nested-BH locking for gro_cell")
Reported-by: syzbot+f9651b9a8212e1c8906f@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/68f65eb9.a70a0220.205af.0034.GAE@google.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20251020161114.1891141-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/gro_cells.c

index b43911562f4d10aa3d05c60f343ff89c5d9ed58d..fd57b845de333ff0e397eeb95aa67926d4e4a730 100644 (file)
@@ -43,12 +43,11 @@ drop:
        if (skb_queue_len(&cell->napi_skbs) == 1)
                napi_schedule(&cell->napi);
 
-       if (have_bh_lock)
-               local_unlock_nested_bh(&gcells->cells->bh_lock);
-
        res = NET_RX_SUCCESS;
 
 unlock:
+       if (have_bh_lock)
+               local_unlock_nested_bh(&gcells->cells->bh_lock);
        rcu_read_unlock();
        return res;
 }