diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-08-27 17:43:20 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-08-27 17:43:20 +0300 |
| commit | ceb9515524046252c522b16f38881e8837ec0d91 (patch) | |
| tree | 4fdf9fce70085fc267ea45c4982a6f101685766d /include | |
| parent | 9448ccd853368582efa9db05db344f8bb9dffe0f (diff) | |
| parent | da9c9c877597170b929a6121a68dcd3dd9a80f45 (diff) | |
| download | linux-ceb9515524046252c522b16f38881e8837ec0d91.tar.xz | |
Merge branch 'introduce-refcount_t-for-reference-counting-of-rose_neigh'
Takamitsu Iwai says:
====================
Introduce refcount_t for reference counting of rose_neigh
The current implementation of rose_neigh uses 'use' and 'count' field of
type unsigned short as a reference count. This approach lacks atomicity,
leading to potential race conditions. As a result, syzbot has reported
slab-use-after-free errors due to unintended removals.
This series introduces refcount_t for reference counting to ensure
atomicity and prevent race conditions. The patches are structured as
follows:
1. Refactor rose_remove_neigh() to separate removal and freeing operations
2. Convert 'use' field to refcount_t for appropriate reference counting
3. Include references from rose_node to 'use' field
These changes should resolve the reported slab-use-after-free issues and
improve the overall stability of the ROSE network layer.
v1: https://lore.kernel.org/20250820174707.83372-1-takamitz@amazon.co.jp
====================
Link: https://patch.msgid.link/20250823085857.47674-1-takamitz@amazon.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/rose.h | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/include/net/rose.h b/include/net/rose.h index 23267b4efcfa..2b5491bbf39a 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -8,6 +8,7 @@ #ifndef _ROSE_H #define _ROSE_H +#include <linux/refcount.h> #include <linux/rose.h> #include <net/ax25.h> #include <net/sock.h> @@ -96,7 +97,7 @@ struct rose_neigh { ax25_cb *ax25; struct net_device *dev; unsigned short count; - unsigned short use; + refcount_t use; unsigned int number; char restarted; char dce_mode; @@ -151,6 +152,21 @@ struct rose_sock { #define rose_sk(sk) ((struct rose_sock *)(sk)) +static inline void rose_neigh_hold(struct rose_neigh *rose_neigh) +{ + refcount_inc(&rose_neigh->use); +} + +static inline void rose_neigh_put(struct rose_neigh *rose_neigh) +{ + if (refcount_dec_and_test(&rose_neigh->use)) { + if (rose_neigh->ax25) + ax25_cb_put(rose_neigh->ax25); + kfree(rose_neigh->digipeat); + kfree(rose_neigh); + } +} + /* af_rose.c */ extern ax25_address rose_callsign; extern int sysctl_rose_restart_request_timeout; |
