diff --git a/kernel/events/core.c b/kernel/events/core.c index 5a123ff103fa..3a7bb69e9d6e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11036,6 +11036,24 @@ SYSCALL_DEFINE5(perf_event_open, goto err_task; } + if (task) { + err = mutex_lock_interruptible(&task->signal->exec_update_mutex); + if (err) + goto err_task; + + /* + * Reuse ptrace permission checks for now. + * + * We must hold exec_update_mutex 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 (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) + goto err_cred; + } + if (flags & PERF_FLAG_PID_CGROUP) cgroup_fd = pid; @@ -11043,7 +11061,7 @@ SYSCALL_DEFINE5(perf_event_open, NULL, NULL, cgroup_fd); if (IS_ERR(event)) { err = PTR_ERR(event); - goto err_task; + goto err_cred; } if (is_sampling_event(event)) { @@ -11162,24 +11180,6 @@ SYSCALL_DEFINE5(perf_event_open, goto err_context; } - if (task) { - err = mutex_lock_interruptible(&task->signal->exec_update_mutex); - if (err) - goto err_file; - - /* - * Preserve ptrace permission check for backwards compatibility. - * - * We must hold exec_update_mutex 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 (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) - goto err_cred; - } - if (move_group) { gctx = __perf_event_ctx_lock_double(group_leader, ctx); @@ -11355,10 +11355,7 @@ err_locked: if (move_group) perf_event_ctx_unlock(group_leader, gctx); mutex_unlock(&ctx->mutex); -err_cred: - if (task) - mutex_unlock(&task->signal->exec_update_mutex); -err_file: +/* err_file: */ fput(event_file); err_context: perf_unpin_context(ctx); @@ -11370,6 +11367,9 @@ err_alloc: */ if (!event_file) free_event(event); +err_cred: + if (task) + mutex_unlock(&task->signal->exec_update_mutex); err_task: if (task) put_task_struct(task);