From: Linus Torvalds Date: Wed, 16 Dec 2020 03:36:48 +0000 (-0800) Subject: Merge branch 'exec-update-lock-for-v5.11' of git://git.kernel.org/pub/scm/linux/kerne... X-Git-Tag: accepted/tizen/unified/20230118.172025~8286 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d01e7f10dae29eba0f9ada82b65d24e035d5b2f9;p=platform%2Fkernel%2Flinux-rpi.git Merge branch 'exec-update-lock-for-v5.11' of git://git./linux/kernel/git/ebiederm/user-namespace Pull exec-update-lock update from Eric Biederman: "The key point of this is to transform exec_update_mutex into a rw_semaphore so readers can be separated from writers. This makes it easier to understand what the holders of the lock are doing, and makes it harder to contend or deadlock on the lock. The real deadlock fix wound up in perf_event_open" * 'exec-update-lock-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: exec: Transform exec_update_mutex into a rw_semaphore --- d01e7f10dae29eba0f9ada82b65d24e035d5b2f9 diff --cc kernel/events/core.c index 19ae6c9,55b2330..55d1879 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@@ -11958,24 -11864,6 +11958,24 @@@ SYSCALL_DEFINE5(perf_event_open goto err_context; } + if (task) { - err = mutex_lock_interruptible(&task->signal->exec_update_mutex); ++ err = down_read_interruptible(&task->signal->exec_update_lock); + if (err) + goto err_file; + + /* + * Preserve ptrace permission check for backwards compatibility. + * - * We must hold exec_update_mutex across this and any potential ++ * We must hold exec_update_lock across this and any potential + * perf_install_in_context() call for this new event to + * serialize against exec() altering our credentials (and the + * perf_event_exit_task() that could imply). + */ + err = -EACCES; + if (!perfmon_capable() && !ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) + goto err_cred; + } + if (move_group) { gctx = __perf_event_ctx_lock_double(group_leader, ctx); @@@ -12151,10 -12039,7 +12151,10 @@@ err_locked if (move_group) perf_event_ctx_unlock(group_leader, gctx); mutex_unlock(&ctx->mutex); -/* err_file: */ +err_cred: + if (task) - mutex_unlock(&task->signal->exec_update_mutex); ++ up_read(&task->signal->exec_update_lock); +err_file: fput(event_file); err_context: perf_unpin_context(ctx);