Skip to content

Commit 2d8a50d

Browse files
leitaogregkh
authored andcommitted
workqueue: Fix wq->cpu_pwq leak in alloc_and_link_pwqs() WQ_UNBOUND path
commit 0143033 upstream. For WQ_UNBOUND workqueues, alloc_and_link_pwqs() allocates wq->cpu_pwq via alloc_percpu() and then calls apply_workqueue_attrs_locked(). On failure it returns the error directly, bypassing the enomem: label which holds the only free_percpu(wq->cpu_pwq) in this function. The caller's error path kfree()s wq without touching wq->cpu_pwq, leaking one percpu pointer table (nr_cpu_ids * sizeof(void *) bytes) per failed call. If kmemleak is enabled, we can see: unreferenced object (percpu) 0xc0fffa5b121048 (size 8): comm "insmod", pid 776, jiffies 4294682844 backtrace (crc 0): pcpu_alloc_noprof+0x665/0xac0 __alloc_workqueue+0x33f/0xa20 alloc_workqueue_noprof+0x60/0x100 Route the error through the existing enomem: cleanup and any error before this one. Cc: stable@kernel.org Fixes: 636b927 ("workqueue: Make unbound workqueues to use per-cpu pool_workqueues") Signed-off-by: Breno Leitao <leitao@debian.org> Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a275432 commit 2d8a50d

1 file changed

Lines changed: 3 additions & 1 deletion

File tree

kernel/workqueue.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5568,7 +5568,9 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq)
55685568
ret = apply_workqueue_attrs_locked(wq, unbound_std_wq_attrs[highpri]);
55695569
}
55705570

5571-
return ret;
5571+
if (ret)
5572+
goto enomem;
5573+
return 0;
55725574

55735575
enomem:
55745576
if (wq->cpu_pwq) {

0 commit comments

Comments
 (0)