diff options
| author | Thomas Gleixner <[email protected]> | 2025-01-18 23:55:32 +0000 |
|---|---|---|
| committer | Thomas Gleixner <[email protected]> | 2025-01-29 14:21:31 +0000 |
| commit | b9a49520679e98700d3d89689cc91c08a1c88c1d (patch) | |
| tree | 7591e6d0c813f180f4277640562467df0cd970c7 /net/unix/sysctl_net_unix.c | |
| parent | futex: Pass in task to futex_queue() (diff) | |
| download | kernel-b9a49520679e98700d3d89689cc91c08a1c88c1d.tar.gz kernel-b9a49520679e98700d3d89689cc91c08a1c88c1d.zip | |
rcuref: Plug slowpath race in rcuref_put()
Kernel test robot reported an "imbalanced put" in the rcuref_put() slow
path, which turned out to be a false positive. Consider the following race:
ref = 0 (via rcuref_init(ref, 1))
T1 T2
rcuref_put(ref)
-> atomic_add_negative_release(-1, ref) # ref -> 0xffffffff
-> rcuref_put_slowpath(ref)
rcuref_get(ref)
-> atomic_add_negative_relaxed(1, &ref->refcnt)
-> return true; # ref -> 0
rcuref_put(ref)
-> atomic_add_negative_release(-1, ref) # ref -> 0xffffffff
-> rcuref_put_slowpath()
-> cnt = atomic_read(&ref->refcnt); # cnt -> 0xffffffff / RCUREF_NOREF
-> atomic_try_cmpxchg_release(&ref->refcnt, &cnt, RCUREF_DEAD)) # ref -> 0xe0000000 / RCUREF_DEAD
-> return true
-> cnt = atomic_read(&ref->refcnt); # cnt -> 0xe0000000 / RCUREF_DEAD
-> if (cnt > RCUREF_RELEASED) # 0xe0000000 > 0xc0000000
-> WARN_ONCE(cnt >= RCUREF_RELEASED, "rcuref - imbalanced put()")
The problem is the additional read in the slow path (after it
decremented to RCUREF_NOREF) which can happen after the counter has been
marked RCUREF_DEAD.
Prevent this by reusing the return value of the decrement. Now every "final"
put uses RCUREF_NOREF in the slow path and attempts the final cmpxchg() to
RCUREF_DEAD.
[ bigeasy: Add changelog ]
Fixes: ee1ee6db07795 ("atomics: Provide rcuref - scalable reference counting")
Reported-by: kernel test robot <[email protected]>
Debugged-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
Cc: [email protected]
Closes: https://lore.kernel.org/oe-lkp/[email protected]
Diffstat (limited to 'net/unix/sysctl_net_unix.c')
0 files changed, 0 insertions, 0 deletions
