Andrea Arcangeli
8bae439855
userfaultfd: use RCU to free the task struct when fork fails
...
commit c3f3ce049f7d97cc7ec9c01cb51d9ec74e0f37c2 upstream.
The task structure is freed while get_mem_cgroup_from_mm() holds
rcu_read_lock() and dereferences mm->owner.
get_mem_cgroup_from_mm() failing fork()
---- ---
task = mm->owner
mm->owner = NULL;
free(task)
if (task) *task; /* use after free */
The fix consists in freeing the task with RCU also in the fork failure
case, exactly like it always happens for the regular exit(2) path. That
is enough to make the rcu_read_lock hold in get_mem_cgroup_from_mm()
(left side above) effective to avoid a use after free when dereferencing
the task structure.
An alternate possible fix would be to defer the delivery of the
userfaultfd contexts to the monitor until after fork() is guaranteed to
succeed. Such a change would require more changes because it would
create a strict ordering dependency where the uffd methods would need to
be called beyond the last potentially failing branch in order to be
safe. This solution as opposed only adds the dependency to common code
to set mm->owner to NULL and to free the task struct that was pointed by
mm->owner with RCU, if fork ends up failing. The userfaultfd methods
can still be called anywhere during the fork runtime and the monitor
will keep discarding orphaned "mm" coming from failed forks in userland.
This race condition couldn't trigger if CONFIG_MEMCG was set =n at build
time.
[aarcange@redhat.com: improve changelog, reduce #ifdefs per Michal]
Link: http://lkml.kernel.org/r/20190429035752.4508-1-aarcange@redhat.com
Link: http://lkml.kernel.org/r/20190325225636.11635-2-aarcange@redhat.com
Fixes: 893e26e61d ("userfaultfd: non-cooperative: Add fork() event")
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Tested-by: zhong jiang <zhongjiang@huawei.com>
Reported-by: syzbot+cbb52e396df3e565ab02@syzkaller.appspotmail.com
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Jann Horn <jannh@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Jason Gunthorpe <jgg@mellanox.com>
Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: zhong jiang <zhongjiang@huawei.com>
Cc: syzbot+cbb52e396df3e565ab02@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-22 07:37:41 +02:00
..
bpf
bpf: fix use after free in bpf_evict_inode
2019-04-20 09:16:05 +02:00
cgroup
cgroup/pids: turn cgroup_subsys->free() into cgroup_subsys->release() to fix the accounting
2019-04-05 22:33:13 +02:00
configs
kconfig: tinyconfig: remove stale stack protector fixups
2018-06-15 07:15:28 +09:00
debug
kdb: Don't back trace on a cpu that didn't round up
2019-02-12 19:47:19 +01:00
dma
dma-direct: do not include SME mask in the DMA supported check
2019-01-13 09:51:05 +01:00
events
perf/core: Fix perf_event_disable_inatomic() race
2019-05-10 17:54:09 +02:00
gcov
gcov: remove CONFIG_GCOV_FORMAT_AUTODETECT
2018-06-08 18:56:02 +09:00
irq
genirq: Prevent use-after-free and work list corruption
2019-05-10 17:54:10 +02:00
livepatch
Merge branch 'for-4.19/upstream' into for-linus
2018-08-20 18:33:50 +02:00
locking
locking/rwsem: Prevent decrement of reader count before increment
2019-05-22 07:37:34 +02:00
power
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
2018-10-12 12:35:02 +02:00
printk
printk: Fix panic caused by passing log_buf_len to command line
2018-11-13 11:08:48 -08:00
rcu
kprobes: Prohibit probing on RCU debug routine
2019-04-05 22:33:08 +02:00
sched
sched/deadline: Correctly handle active 0-lag timers
2019-05-02 09:58:56 +02:00
time
timers/sched_clock: Prevent generic sched_clock wrap caused by tick_freeze()
2019-04-27 09:36:38 +02:00
trace
fs: prevent page refcount overflow in pipe_buf_get
2019-05-04 09:20:11 +02:00
.gitignore
acct.c
async.c
audit.c
audit: use ktime_get_coarse_real_ts64() for timestamps
2018-07-17 14:45:08 -04:00
audit.h
audit: track the owner of the command mutex ourselves
2018-02-23 11:22:22 -05:00
audit_fsnotify.c
fsnotify: add fsnotify_add_inode_mark() wrappers
2018-05-18 14:58:22 +02:00
audit_tree.c
\n
2018-08-17 09:41:28 -07:00
audit_watch.c
audit: fix use-after-free in audit_add_watch
2018-07-18 11:43:36 -04:00
auditfilter.c
audit: rename FILTER_TYPE to FILTER_EXCLUDE
2018-06-19 10:39:54 -04:00
auditsc.c
audit/stable-4.18 PR 20180814
2018-08-15 10:46:54 -07:00
backtracetest.c
bounds.c
kbuild: fix kernel/bounds.c 'W=1' warning
2018-11-13 11:08:47 -08:00
capability.c
compat.c
time: Enable get/put_compat_itimerspec64 always
2018-06-24 14:39:47 +02:00
configs.c
context_tracking.c
cpu.c
cpu/speculation: Add 'mitigations=' cmdline option
2019-05-14 19:17:59 +02:00
cpu_pm.c
crash_core.c
kernel/crash_core.c: print timestamp using time64_t
2018-08-22 10:52:47 -07:00
crash_dump.c
cred.c
delayacct.c
delayacct: Use raw_spinlocks
2018-04-27 14:34:51 +02:00
dma.c
proc: introduce proc_create_single{,_data}
2018-05-16 07:23:35 +02:00
elfcore.c
exec_domain.c
proc: introduce proc_create_single{,_data}
2018-05-16 07:23:35 +02:00
exit.c
cgroup/pids: turn cgroup_subsys->free() into cgroup_subsys->release() to fix the accounting
2019-04-05 22:33:13 +02:00
extable.c
extable: Make init_kernel_text() global
2018-02-21 16:54:06 +01:00
fail_function.c
bpf/error-inject/kprobes: Clear current_kprobe and enable preempt in kprobe
2018-06-21 12:33:19 +02:00
fork.c
userfaultfd: use RCU to free the task struct when fork fails
2019-05-22 07:37:41 +02:00
freezer.c
PM / reboot: Eliminate race between reboot and suspend
2018-08-06 12:35:20 +02:00
futex.c
locking/futex: Allow low-level atomic operations to return -EAGAIN
2019-05-10 17:54:11 +02:00
futex_compat.c
groups.c
hung_task.c
kernel: hung_task.c: disable on suspend
2019-04-20 09:16:02 +02:00
iomem.c
memremap: split devm_memremap_pages() and memremap() infrastructure
2018-05-15 23:08:33 -07:00
irq_work.c
jump_label.c
jump_label: Fix typo in warning message
2018-09-10 10:15:48 +02:00
kallsyms.c
kallsyms, x86: Export addresses of PTI entry trampolines
2018-08-14 19:12:29 -03:00
kcmp.c
Kconfig.freezer
Kconfig.hz
Kconfig.locks
Kconfig.preempt
kconfig: include kernel/Kconfig.preempt from init/Kconfig
2018-08-02 08:06:54 +09:00
kcov.c
kernel/kcov.c: mark write_comp_data() as notrace
2019-02-12 19:47:20 +01:00
kexec.c
kexec: add call to LSM hook in original kexec_load syscall
2018-07-16 12:31:57 -07:00
kexec_core.c
kexec: yield to scheduler when loading kimage segments
2018-06-15 07:55:24 +09:00
kexec_file.c
treewide: Use array_size() in vzalloc()
2018-06-12 16:19:22 -07:00
kexec_internal.h
kmod.c
kprobes.c
kprobes: Fix error check when reusing optimized probes
2019-04-27 09:36:37 +02:00
ksysfs.c
kthread.c
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
2018-08-13 11:25:07 -07:00
latencytop.c
Makefile
kbuild: move bin2c back to scripts/ from scripts/basic/
2018-07-18 01:18:05 +09:00
memremap.c
mm, devm_memremap_pages: add MEMORY_DEVICE_PRIVATE support
2019-01-13 09:51:04 +01:00
module-internal.h
modsign: log module name in the event of an error
2018-07-02 11:36:17 +02:00
module.c
kobject: return error code if writing /sys/.../uevent fails
2019-02-12 19:47:06 +01:00
module_signing.c
modsign: log module name in the event of an error
2018-07-02 11:36:17 +02:00
notifier.c
nsproxy.c
padata.c
panic.c
panic: avoid deadlocks in re-entrant console drivers
2018-12-29 13:37:57 +01:00
params.c
kernel/params.c: downgrade warning for unsafe parameters
2018-04-11 10:28:37 -07:00
pid.c
Fix failure path in alloc_pid()
2019-01-13 09:51:06 +01:00
pid_namespace.c
Merge branch 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
2018-04-03 19:15:32 -07:00
profile.c
ptrace.c
ptrace: take into account saved_sigmask in PTRACE{GET,SET}SIGMASK
2019-05-04 09:20:22 +02:00
range.c
reboot.c
PM / reboot: Eliminate race between reboot and suspend
2018-08-06 12:35:20 +02:00
relay.c
relay: check return of create_buf_file() properly
2019-03-13 14:02:35 -07:00
resource.c
libnvdimm for 4.18
2018-06-08 17:21:52 -07:00
rseq.c
rseq: uapi: Declare rseq_cs field as union, update includes
2018-07-10 22:18:52 +02:00
seccomp.c
audit/stable-4.18 PR 20180605
2018-06-06 16:34:00 -07:00
signal.c
signal: Restore the stop PTRACE_EVENT_EXIT
2019-02-20 10:25:48 +01:00
smp.c
cpu/hotplug: Fix "SMT disabled by BIOS" detection for KVM
2019-02-12 19:47:25 +01:00
smpboot.c
smpboot: Remove cpumask from the API
2018-07-03 09:20:44 +02:00
smpboot.h
softirq.c
nohz: Fix missing tick reprogram when interrupting an inline softirq
2018-08-03 15:52:10 +02:00
stacktrace.c
stop_machine.c
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
2018-08-13 11:25:07 -07:00
sys.c
kernel/sys.c: remove duplicated include
2018-09-20 22:01:11 +02:00
sys_ni.c
Merge branch 'core-rseq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
2018-06-10 10:17:09 -07:00
sysctl.c
kernel/sysctl.c: fix out-of-bounds access when setting file-max
2019-04-27 09:36:41 +02:00
sysctl_binary.c
staging: irda: remove remaining remants of irda code removal
2018-04-16 11:26:49 +02:00
task_work.c
taskstats.c
test_kprobes.c
kprobes: Remove jprobe API implementation
2018-06-21 12:33:05 +02:00
torture.c
torture: Keep old-school dmesg format
2018-06-25 11:30:10 -07:00
tracepoint.c
tracepoint: Fix tracepoint array element size mismatch
2018-10-17 15:35:29 -04:00
tsacct.c
ucount.c
headers: untangle kmemleak.h from mm.h
2018-04-05 21:36:27 -07:00
uid16.c
fs: add do_fchownat(), ksys_fchown() helpers and ksys_{,l}chown() wrappers
2018-04-02 20:15:59 +02:00
uid16.h
kernel: provide ksys_*() wrappers for syscalls called by kernel/uid16.c
2018-04-02 20:15:30 +02:00
umh.c
umh: fix race condition
2018-06-07 16:56:28 -04:00
up.c
user-return-notifier.c
user.c
userns: use irqsave variant of refcount_dec_and_lock()
2018-08-22 10:52:47 -07:00
user_namespace.c
userns: also map extents in the reverse map to kernel IDs
2018-11-13 11:09:00 -08:00
utsname.c
uts: create "struct uts_namespace" from kmem_cache
2018-04-11 10:28:35 -07:00
utsname_sysctl.c
sys: don't hold uts_sem while accessing userspace memory
2018-08-11 02:05:53 -05:00
watchdog.c
watchdog: Respect watchdog cpumask on CPU hotplug
2019-04-03 06:26:29 +02:00
watchdog_hld.c
watchdog: Mark watchdog touch functions as notrace
2018-08-30 12:56:40 +02:00
workqueue.c
workqueue: Try to catch flush_work() without INIT_WORK().
2019-05-02 09:58:56 +02:00
workqueue_internal.h
workqueue: Set worker->desc to workqueue name by default
2018-05-18 08:47:13 -07:00