From: Tvrtko Ursulin <[email protected]> To enable per-PMU access controls in a following patch first move all call sites of perf_paranoid_kernel() to after the event has been created.
Signed-off-by: Tvrtko Ursulin <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Madhavan Srinivasan <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Alexey Budankov <[email protected]> Cc: [email protected] Cc: [email protected] --- kernel/events/core.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index bccce538f51d..adcd9eae13fb 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -10194,10 +10194,6 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, */ attr->branch_sample_type = mask; } - /* privileged levels capture (kernel, hv): check permissions */ - if ((mask & PERF_SAMPLE_BRANCH_PERM_PLM) - && perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) - return -EACCES; } if (attr->sample_type & PERF_SAMPLE_REGS_USER) { @@ -10414,11 +10410,6 @@ SYSCALL_DEFINE5(perf_event_open, if (err) return err; - if (!attr.exclude_kernel) { - if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) - return -EACCES; - } - if (attr.namespaces) { if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -10432,11 +10423,6 @@ SYSCALL_DEFINE5(perf_event_open, return -EINVAL; } - /* Only privileged users can get physical addresses */ - if ((attr.sample_type & PERF_SAMPLE_PHYS_ADDR) && - perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) - return -EACCES; - /* * In cgroup mode, the pid argument is used to pass the fd * opened to the cgroup directory in cgroupfs. The cpu argument @@ -10506,6 +10492,28 @@ SYSCALL_DEFINE5(perf_event_open, goto err_cred; } + if (!attr.exclude_kernel) { + if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto err_alloc; + } + } + + /* Only privileged users can get physical addresses */ + if ((attr.sample_type & PERF_SAMPLE_PHYS_ADDR) && + perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto err_alloc; + } + + /* privileged levels capture (kernel, hv): check permissions */ + if ((attr.sample_type & PERF_SAMPLE_BRANCH_STACK) && + (attr.branch_sample_type & PERF_SAMPLE_BRANCH_PERM_PLM) && + perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto err_alloc; + } + if (is_sampling_event(event)) { if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) { err = -EOPNOTSUPP; -- 2.17.1

