Yang Yingliang
1f63eec1c8
workqueue: fix UAF in pwq_unbound_release_workfn()
commit b42b0bddcbc87b4c66f6497f66fc72d52b712aa7 upstream.
I got a UAF report when doing fuzz test:
[ 152.880091][ T8030] ==================================================================
[ 152.881240][ T8030] BUG: KASAN: use-after-free in pwq_unbound_release_workfn+0x50/0x190
[ 152.882442][ T8030] Read of size 4 at addr ffff88810d31bd00 by task kworker/3:2/8030
[ 152.883578][ T8030]
[ 152.883932][ T8030] CPU: 3 PID: 8030 Comm: kworker/3:2 Not tainted 5.13.0+ #249
[ 152.885014][ T8030] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 152.886442][ T8030] Workqueue: events pwq_unbound_release_workfn
[ 152.887358][ T8030] Call Trace:
[ 152.887837][ T8030] dump_stack_lvl+0x75/0x9b
[ 152.888525][ T8030] ? pwq_unbound_release_workfn+0x50/0x190
[ 152.889371][ T8030] print_address_description.constprop.10+0x48/0x70
[ 152.890326][ T8030] ? pwq_unbound_release_workfn+0x50/0x190
[ 152.891163][ T8030] ? pwq_unbound_release_workfn+0x50/0x190
[ 152.891999][ T8030] kasan_report.cold.15+0x82/0xdb
[ 152.892740][ T8030] ? pwq_unbound_release_workfn+0x50/0x190
[ 152.893594][ T8030] __asan_load4+0x69/0x90
[ 152.894243][ T8030] pwq_unbound_release_workfn+0x50/0x190
[ 152.895057][ T8030] process_one_work+0x47b/0x890
[ 152.895778][ T8030] worker_thread+0x5c/0x790
[ 152.896439][ T8030] ? process_one_work+0x890/0x890
[ 152.897163][ T8030] kthread+0x223/0x250
[ 152.897747][ T8030] ? set_kthread_struct+0xb0/0xb0
[ 152.898471][ T8030] ret_from_fork+0x1f/0x30
[ 152.899114][ T8030]
[ 152.899446][ T8030] Allocated by task 8884:
[ 152.900084][ T8030] kasan_save_stack+0x21/0x50
[ 152.900769][ T8030] __kasan_kmalloc+0x88/0xb0
[ 152.901416][ T8030] __kmalloc+0x29c/0x460
[ 152.902014][ T8030] alloc_workqueue+0x111/0x8e0
[ 152.902690][ T8030] __btrfs_alloc_workqueue+0x11e/0x2a0
[ 152.903459][ T8030] btrfs_alloc_workqueue+0x6d/0x1d0
[ 152.904198][ T8030] scrub_workers_get+0x1e8/0x490
[ 152.904929][ T8030] btrfs_scrub_dev+0x1b9/0x9c0
[ 152.905599][ T8030] btrfs_ioctl+0x122c/0x4e50
[ 152.906247][ T8030] __x64_sys_ioctl+0x137/0x190
[ 152.906916][ T8030] do_syscall_64+0x34/0xb0
[ 152.907535][ T8030] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 152.908365][ T8030]
[ 152.908688][ T8030] Freed by task 8884:
[ 152.909243][ T8030] kasan_save_stack+0x21/0x50
[ 152.909893][ T8030] kasan_set_track+0x20/0x30
[ 152.910541][ T8030] kasan_set_free_info+0x24/0x40
[ 152.911265][ T8030] __kasan_slab_free+0xf7/0x140
[ 152.911964][ T8030] kfree+0x9e/0x3d0
[ 152.912501][ T8030] alloc_workqueue+0x7d7/0x8e0
[ 152.913182][ T8030] __btrfs_alloc_workqueue+0x11e/0x2a0
[ 152.913949][ T8030] btrfs_alloc_workqueue+0x6d/0x1d0
[ 152.914703][ T8030] scrub_workers_get+0x1e8/0x490
[ 152.915402][ T8030] btrfs_scrub_dev+0x1b9/0x9c0
[ 152.916077][ T8030] btrfs_ioctl+0x122c/0x4e50
[ 152.916729][ T8030] __x64_sys_ioctl+0x137/0x190
[ 152.917414][ T8030] do_syscall_64+0x34/0xb0
[ 152.918034][ T8030] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 152.918872][ T8030]
[ 152.919203][ T8030] The buggy address belongs to the object at ffff88810d31bc00
[ 152.919203][ T8030] which belongs to the cache kmalloc-512 of size 512
[ 152.921155][ T8030] The buggy address is located 256 bytes inside of
[ 152.921155][ T8030] 512-byte region [ffff88810d31bc00, ffff88810d31be00)
[ 152.922993][ T8030] The buggy address belongs to the page:
[ 152.923800][ T8030] page:ffffea000434c600 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10d318
[ 152.925249][ T8030] head:ffffea000434c600 order:2 compound_mapcount:0 compound_pincount:0
[ 152.926399][ T8030] flags: 0x57ff00000010200(slab|head|node=1|zone=2|lastcpupid=0x7ff)
[ 152.927515][ T8030] raw: 057ff00000010200 dead000000000100 dead000000000122 ffff888009c42c80
[ 152.928716][ T8030] raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000
[ 152.929890][ T8030] page dumped because: kasan: bad access detected
[ 152.930759][ T8030]
[ 152.931076][ T8030] Memory state around the buggy address:
[ 152.931851][ T8030] ffff88810d31bc00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 152.932967][ T8030] ffff88810d31bc80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 152.934068][ T8030] >ffff88810d31bd00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 152.935189][ T8030] ^
[ 152.935763][ T8030] ffff88810d31bd80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 152.936847][ T8030] ffff88810d31be00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 152.937940][ T8030] ==================================================================
If apply_wqattrs_prepare() fails in alloc_workqueue(), it will call put_pwq()
which invoke a work queue to call pwq_unbound_release_workfn() and use the 'wq'.
The 'wq' allocated in alloc_workqueue() will be freed in error path when
apply_wqattrs_prepare() fails. So it will lead a UAF.
CPU0 CPU1
alloc_workqueue()
alloc_and_link_pwqs()
apply_wqattrs_prepare() fails
apply_wqattrs_cleanup()
schedule_work(&pwq->unbound_release_work)
kfree(wq)
worker_thread()
pwq_unbound_release_workfn() <- trigger uaf here
If apply_wqattrs_prepare() fails, the new pwq are not linked, it doesn't
hold any reference to the 'wq', 'wq' is invalid to access in the worker,
so add check pwq if linked to fix this.
Fixes: 2d5f0764b5 ("workqueue: split apply_workqueue_attrs() into 3 stages")
Cc: stable@vger.kernel.org # v4.2+
Reported-by: Hulk Robot <hulkci@huawei.com>
Suggested-by: Lai Jiangshan <jiangshanlai@gmail.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>
Tested-by: Pavel Skripkin <paskripkin@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
2021-08-04 11:58:01 +02:00 |
| .. |
|
bpf
|
bpf: Check for integer overflow when using roundup_pow_of_two()
|
2021-02-23 13:59:16 +01:00 |
|
configs
|
config: android: enable CONFIG_SECCOMP
|
2016-10-11 15:06:32 -07:00 |
|
debug
|
kdb: Make memory allocations more robust
|
2021-03-03 17:44:31 +01:00 |
|
events
|
perf: Fix data race between pin_count increment/decrement
|
2021-06-16 11:36:35 +02:00 |
|
gcov
|
gcov: add support for GCC 10.1
|
2020-09-23 08:46:14 +02:00 |
|
irq
|
genirq: Disable interrupts for force threaded handlers
|
2021-03-24 10:59:26 +01:00 |
|
livepatch
|
livepatch/module: make TAINT_LIVEPATCH module-specific
|
2016-08-26 14:42:08 +02:00 |
|
locking
|
futex: Handle early deadlock return correctly
|
2021-03-30 14:41:42 +02:00 |
|
power
|
PM: hibernate: remove the bogus call to get_gendisk() in software_resume()
|
2020-10-29 09:05:43 +01:00 |
|
printk
|
printk: fix deadlock when kernel panic
|
2021-03-07 11:25:56 +01:00 |
|
rcu
|
rcuperf: Fix cleanup path for invalid perf_type strings
|
2019-05-31 06:48:30 -07:00 |
|
sched
|
sched/fair: Fix CFS bandwidth hrtimer expiry type
|
2021-07-28 09:14:25 +02:00 |
|
time
|
kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data()
|
2021-03-24 10:59:25 +01:00 |
|
trace
|
tracing: Fix bug in rb_per_cpu_empty() that might cause deadloop.
|
2021-07-28 09:14:28 +02:00 |
|
.gitignore
|
|
|
|
acct.c
|
kernel/acct.c: fix the acct->needcheck check in check_free_space()
|
2018-01-10 09:29:51 +01:00 |
|
async.c
|
kernel/async.c: revert "async: simplify lowest_in_progress()"
|
2018-02-17 13:21:18 +01:00 |
|
audit.c
|
audit: fix a net reference leak in audit_list_rules_send()
|
2021-04-07 12:05:41 +02:00 |
|
audit.h
|
audit: fix a net reference leak in audit_list_rules_send()
|
2021-04-07 12:05:41 +02:00 |
|
audit_fsnotify.c
|
|
|
|
audit_tree.c
|
|
|
|
audit_watch.c
|
audit: CONFIG_CHANGE don't log internal bookkeeping as an event
|
2020-10-01 20:40:07 +02:00 |
|
auditfilter.c
|
audit: fix a net reference leak in audit_list_rules_send()
|
2021-04-07 12:05:41 +02:00 |
|
auditsc.c
|
audit: print empty EXECVE args
|
2019-11-28 18:28:55 +01:00 |
|
backtracetest.c
|
|
|
|
bounds.c
|
kbuild: fix kernel/bounds.c 'W=1' warning
|
2018-11-13 11:16:57 -08:00 |
|
capability.c
|
ptrace: Capture the ptracer's creds not PT_PTRACE_CAP
|
2017-01-06 10:40:13 +01:00 |
|
cgroup.c
|
cgroup1: don't allow '\n' in renaming
|
2021-06-16 11:36:34 +02:00 |
|
cgroup_freezer.c
|
|
|
|
cgroup_pids.c
|
cgroup: pids: use atomic64_t for pids->limit
|
2019-12-21 10:42:02 +01:00 |
|
compat.c
|
|
|
|
configs.c
|
|
|
|
context_tracking.c
|
|
|
|
cpu.c
|
kernel/cpu: add arch override for clear_tasks_mm_cpumask() mm handling
|
2020-12-29 13:44:50 +01:00 |
|
cpu_pm.c
|
kernel/cpu_pm: Fix uninitted local in cpu_pm
|
2020-06-20 10:24:21 +02:00 |
|
cpuset.c
|
sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs
|
2017-10-12 11:51:25 +02:00 |
|
crash_dump.c
|
|
|
|
cred.c
|
memcg: account security cred as well to kmemcg
|
2020-01-12 11:24:13 +01:00 |
|
delayacct.c
|
|
|
|
dma.c
|
|
|
|
exec_domain.c
|
|
|
|
exit.c
|
futex: Mark the begin of futex exit explicitly
|
2021-02-03 23:19:49 +01:00 |
|
extable.c
|
kernel/extable.c: mark core_kernel_text notrace
|
2017-07-21 07:42:21 +02:00 |
|
fork.c
|
futex: Split futex_mm_release() for exit/exec
|
2021-02-03 23:19:49 +01:00 |
|
freezer.c
|
freezer, oom: check TIF_MEMDIE on the correct task
|
2016-07-28 16:07:41 -07:00 |
|
futex.c
|
mm, futex: fix shared futex pgoff on shmem huge page
|
2021-07-11 12:46:40 +02:00 |
|
groups.c
|
kernel: make groups_sort calling a responsibility group_info allocators
|
2018-01-10 09:29:52 +01:00 |
|
hung_task.c
|
kernel: hung_task.c: disable on suspend
|
2019-04-20 09:07:52 +02:00 |
|
irq_work.c
|
|
|
|
jump_label.c
|
jump_label: Invoke jump_label_test() via early_initcall()
|
2017-12-14 09:28:24 +01:00 |
|
kallsyms.c
|
|
|
|
kcmp.c
|
|
|
|
Kconfig.freezer
|
|
|
|
Kconfig.hz
|
|
|
|
Kconfig.locks
|
|
|
|
Kconfig.preempt
|
|
|
|
kcov.c
|
kcov: ensure irq code sees a valid area
|
2018-08-03 07:55:12 +02:00 |
|
kexec.c
|
kexec: allow architectures to override boot mapping
|
2016-08-02 19:35:27 -04:00 |
|
kexec_core.c
|
objtool, x86: Add several functions and files to the objtool whitelist
|
2018-06-05 10:28:57 +02:00 |
|
kexec_file.c
|
kernel: kexec_file: fix error return code of kexec_calculate_store_digests()
|
2021-05-22 10:40:31 +02:00 |
|
kexec_internal.h
|
|
|
|
kmod.c
|
usermodehelper: reset umask to default before executing user process
|
2020-10-14 09:48:14 +02:00 |
|
kprobes.c
|
kretprobe: Avoid re-registration of the same kretprobe earlier
|
2021-02-10 09:09:25 +01:00 |
|
ksysfs.c
|
kexec: add a kexec_crash_loaded() function
|
2016-08-02 19:35:30 -04:00 |
|
kthread.c
|
kthread: prevent deadlock when kthread_mod_delayed_work() races with kthread_cancel_delayed_work_sync()
|
2021-07-11 12:46:41 +02:00 |
|
latencytop.c
|
|
|
|
Makefile
|
elfcore: fix building with clang
|
2021-02-10 09:09:25 +01:00 |
|
membarrier.c
|
Fix: Disable sys_membarrier when nohz_full is enabled
|
2017-03-12 06:41:45 +01:00 |
|
memremap.c
|
mm, devm_memremap_pages: kill mapping "System RAM" support
|
2019-01-13 10:03:51 +01:00 |
|
module-internal.h
|
|
|
|
module.c
|
module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols
|
2021-03-03 17:44:44 +01:00 |
|
module_signing.c
|
|
|
|
notifier.c
|
x86/mm: split vmalloc_sync_all()
|
2020-04-02 17:20:26 +02:00 |
|
nsproxy.c
|
|
|
|
padata.c
|
padata: purge get_cpu and reorder_via_wq from padata_do_serial
|
2020-05-27 16:41:53 +02:00 |
|
panic.c
|
panic: ensure preemption is disabled during panic()
|
2019-10-17 13:42:25 -07:00 |
|
params.c
|
|
|
|
pid.c
|
pidns: disable pid allocation if pid_ns_prepare_proc() is failed in alloc_pid()
|
2018-04-13 19:47:53 +02:00 |
|
pid_namespace.c
|
signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig
|
2019-08-04 09:33:16 +02:00 |
|
profile.c
|
profile: Convert to hotplug state machine
|
2016-07-15 10:41:42 +02:00 |
|
ptrace.c
|
ptrace: make ptrace() fail if the tracee changed its pid unexpectedly
|
2021-05-26 11:29:06 +02:00 |
|
range.c
|
|
|
|
reboot.c
|
reboot: fix overflow parsing reboot cpu number
|
2020-11-18 18:26:32 +01:00 |
|
relay.c
|
kernel/relay.c: fix memleak on destroy relay channel
|
2020-08-26 10:29:03 +02:00 |
|
resource.c
|
resource: fix integer overflow at reallocation
|
2018-04-24 09:34:09 +02:00 |
|
seccomp.c
|
seccomp: Add missing return in non-void function
|
2021-03-03 17:44:43 +01:00 |
|
signal.c
|
signal: Extend exec_id to 64bits
|
2020-04-24 07:58:54 +02:00 |
|
smp.c
|
cpu/hotplug: Fix SMT supported evaluation
|
2018-08-15 18:14:53 +02:00 |
|
smpboot.c
|
kthread/smpboot: do not park in kthread_create_on_cpu()
|
2016-10-11 15:06:33 -07:00 |
|
smpboot.h
|
|
|
|
softirq.c
|
Mark HI and TASKLET softirq synchronous
|
2018-08-15 18:14:42 +02:00 |
|
stacktrace.c
|
stacktrace, lockdep: Fix address, newline ugliness
|
2017-02-14 15:25:42 -08:00 |
|
stop_machine.c
|
stop_machine: Use raw spinlocks
|
2018-08-03 07:55:24 +02:00 |
|
sys.c
|
kernel/sys.c: avoid copying possible padding bytes in copy_to_user
|
2020-10-01 20:40:04 +02:00 |
|
sys_ni.c
|
x86/pkeys: Fix pkeys build breakage for some non-x86 arches
|
2016-09-13 14:41:36 +02:00 |
|
sysctl.c
|
sched/rt: Show the 'sched_rr_timeslice' SCHED_RR timeslice tuning knob in milliseconds
|
2020-07-09 09:35:55 +02:00 |
|
sysctl_binary.c
|
|
|
|
task_work.c
|
task_work: use READ_ONCE/lockless_dereference, avoid pi_lock if !task_works
|
2016-08-02 19:35:02 -04:00 |
|
taskstats.c
|
taskstats: fix data-race
|
2020-01-12 11:24:12 +01:00 |
|
test_kprobes.c
|
|
|
|
torture.c
|
torture: Convert torture_shutdown() to hrtimer
|
2016-08-22 10:01:49 -07:00 |
|
tracepoint.c
|
tracepoint: Do not fail unregistering a probe due to memory failure
|
2021-03-03 17:44:38 +01:00 |
|
tsacct.c
|
|
|
|
ucount.c
|
kernel/ucount.c: mark user_header with kmemleak_ignore()
|
2017-06-17 06:41:51 +02:00 |
|
uid16.c
|
kernel: make groups_sort calling a responsibility group_info allocators
|
2018-01-10 09:29:52 +01:00 |
|
up.c
|
smp: Add function to execute a function synchronously on a CPU
|
2016-09-05 13:52:39 +02:00 |
|
user-return-notifier.c
|
|
|
|
user.c
|
|
|
|
user_namespace.c
|
userns: move user access out of the mutex
|
2018-09-09 20:01:24 +02:00 |
|
utsname.c
|
Merge branch 'nsfs-ioctls' into HEAD
|
2016-09-22 20:00:36 -05:00 |
|
utsname_sysctl.c
|
sys: don't hold uts_sem while accessing userspace memory
|
2018-09-09 20:01:24 +02:00 |
|
watchdog.c
|
kernel/watchdog: prevent false hardlockup on overloaded system
|
2017-06-17 06:41:57 +02:00 |
|
watchdog_hld.c
|
kernel/watchdog: prevent false hardlockup on overloaded system
|
2017-06-17 06:41:57 +02:00 |
|
workqueue.c
|
workqueue: fix UAF in pwq_unbound_release_workfn()
|
2021-08-04 11:58:01 +02:00 |
|
workqueue_internal.h
|
workqueue: Fix NULL pointer dereference
|
2017-11-15 15:53:17 +01:00 |