Skip to content

Commit d22cc7f

Browse files
Qian CaiIngo Molnar
authored andcommitted
locking/percpu-rwsem: Fix a task_struct refcount
The following commit: 7f26482 ("locking/percpu-rwsem: Remove the embedded rwsem") introduced task_struct memory leaks due to messing up the task_struct refcount. At the beginning of percpu_rwsem_wake_function(), it calls get_task_struct(), but if the trylock failed, it will remain in the waitqueue. However, it will run percpu_rwsem_wake_function() again with get_task_struct() to increase the refcount but then only call put_task_struct() once the trylock succeeded. Fix it by adjusting percpu_rwsem_wake_function() a bit to guard against when percpu_rwsem_wait() observing !private, terminating the wait and doing a quick exit() while percpu_rwsem_wake_function() then doing wake_up_process(p) as a use-after-free. Fixes: 7f26482 ("locking/percpu-rwsem: Remove the embedded rwsem") Suggested-by: Peter Zijlstra <[email protected]> Signed-off-by: Qian Cai <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent f5e94d1 commit d22cc7f

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

kernel/locking/percpu-rwsem.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,15 @@ static int percpu_rwsem_wake_function(struct wait_queue_entry *wq_entry,
118118
unsigned int mode, int wake_flags,
119119
void *key)
120120
{
121-
struct task_struct *p = get_task_struct(wq_entry->private);
122121
bool reader = wq_entry->flags & WQ_FLAG_CUSTOM;
123122
struct percpu_rw_semaphore *sem = key;
123+
struct task_struct *p;
124124

125125
/* concurrent against percpu_down_write(), can get stolen */
126126
if (!__percpu_rwsem_trylock(sem, reader))
127127
return 1;
128128

129+
p = get_task_struct(wq_entry->private);
129130
list_del_init(&wq_entry->entry);
130131
smp_store_release(&wq_entry->private, NULL);
131132

0 commit comments

Comments
 (0)