diff options
| author | Bernard Pidoux <bernard.f6bvp@gmail.com> | 2026-05-28 19:11:55 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-06-27 11:07:40 +0100 |
| commit | 4f9aa720a80f1a23b26a04d8bc9d403f96770d09 (patch) | |
| tree | 1ccc81db894e5c0f87aa802d62dc5ad1adeb4e10 | |
| parent | 35ed67c5f66dcfba53a184263bafc7c5bd542558 (diff) | |
| download | linux-stable-4f9aa720a80f1a23b26a04d8bc9d403f96770d09.tar.gz linux-stable-4f9aa720a80f1a23b26a04d8bc9d403f96770d09.zip | |
rose: fix netdev double-hold in rose_make_new()
commit b9fb21ceb4f0d043767a1eba60786ec84809033b upstream.
rose_make_new() copies orose->device from the listener socket and calls
netdev_hold(), storing the tracker in rose->dev_tracker. The only
caller, rose_rx_call_request(), then overwrites both make_rose->device
and make_rose->dev_tracker with a fresh netdev_hold() for the actual
incoming-call device.
This orphans the tracker allocated by rose_make_new(): it remains in
the device's refcount_tracker list but no pointer exists to free it
via netdev_put(). The result is one spurious outstanding reference per
accepted CALL_REQUEST, visible at rmmod time as:
ref_tracker: netdev@X has 2/2 users at
rose_rx_call_request+0xba3/0x1d50 [rose]
rose_loopback_timer+0x3eb/0x670 [rose]
The second entry is the orphaned tracker from rose_make_new(); the
first is the correctly-managed socket reference from rose_rx_call_request().
Fix: initialise rose->device to NULL in rose_make_new() and let
rose_rx_call_request() -- the sole caller -- assign the correct device
and take the sole netdev_hold() as it already does.
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | net/rose/af_rose.c | 4 |
1 files changed, 1 insertions, 3 deletions
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 35099cd6ee19..1f641516e03e 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -631,9 +631,7 @@ static struct sock *rose_make_new(struct sock *osk) rose->hb = orose->hb; rose->idle = orose->idle; rose->defer = orose->defer; - rose->device = orose->device; - if (rose->device) - netdev_hold(rose->device, &rose->dev_tracker, GFP_ATOMIC); + rose->device = NULL; /* rose_rx_call_request() sets this */ rose->qbitincl = orose->qbitincl; return sk; |
