Skip to content

Commit 9d7a6c9

Browse files
melverPeter Zijlstra
authored andcommitted
perf: Fix required permissions if sigtrap is requested
If perf_event_open() is called with another task as target and perf_event_attr::sigtrap is set, and the target task's user does not match the calling user, also require the CAP_KILL capability or PTRACE_MODE_ATTACH permissions. Otherwise, with the CAP_PERFMON capability alone it would be possible for a user to send SIGTRAP signals via perf events to another user's tasks. This could potentially result in those tasks being terminated if they cannot handle SIGTRAP signals. Note: The check complements the existing capability check, but is not supposed to supersede the ptrace_may_access() check. At a high level we now have: capable of CAP_PERFMON and (CAP_KILL if sigtrap) OR ptrace_may_access(...) // also checks for same thread-group and uid Fixes: 97ba62b ("perf: Add support for SIGTRAP on perf events") Reported-by: Dmitry Vyukov <[email protected]> Signed-off-by: Marco Elver <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Dmitry Vyukov <[email protected]> Cc: <[email protected]> # 5.13+ Link: https://lore.kernel.org/r/[email protected]
1 parent 7fef2ed commit 9d7a6c9

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

kernel/events/core.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12158,10 +12158,33 @@ SYSCALL_DEFINE5(perf_event_open,
1215812158
}
1215912159

1216012160
if (task) {
12161+
unsigned int ptrace_mode = PTRACE_MODE_READ_REALCREDS;
12162+
bool is_capable;
12163+
1216112164
err = down_read_interruptible(&task->signal->exec_update_lock);
1216212165
if (err)
1216312166
goto err_file;
1216412167

12168+
is_capable = perfmon_capable();
12169+
if (attr.sigtrap) {
12170+
/*
12171+
* perf_event_attr::sigtrap sends signals to the other
12172+
* task. Require the current task to also have
12173+
* CAP_KILL.
12174+
*/
12175+
rcu_read_lock();
12176+
is_capable &= ns_capable(__task_cred(task)->user_ns, CAP_KILL);
12177+
rcu_read_unlock();
12178+
12179+
/*
12180+
* If the required capabilities aren't available, checks
12181+
* for ptrace permissions: upgrade to ATTACH, since
12182+
* sending signals can effectively change the target
12183+
* task.
12184+
*/
12185+
ptrace_mode = PTRACE_MODE_ATTACH_REALCREDS;
12186+
}
12187+
1216512188
/*
1216612189
* Preserve ptrace permission check for backwards compatibility.
1216712190
*
@@ -12171,7 +12194,7 @@ SYSCALL_DEFINE5(perf_event_open,
1217112194
* perf_event_exit_task() that could imply).
1217212195
*/
1217312196
err = -EACCES;
12174-
if (!perfmon_capable() && !ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
12197+
if (!is_capable && !ptrace_may_access(task, ptrace_mode))
1217512198
goto err_cred;
1217612199
}
1217712200

0 commit comments

Comments
 (0)