From: Tvrtko Ursulin <tvrtko.ursu...@intel.com>

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 <tvrtko.ursu...@intel.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: "H. Peter Anvin" <h...@zytor.com>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Alexander Shishkin <alexander.shish...@linux.intel.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Madhavan Srinivasan <ma...@linux.vnet.ibm.com>
Cc: Andi Kleen <a...@linux.intel.com>
Cc: Alexey Budankov <alexey.budan...@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
Cc: x...@kernel.org
---
 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 f490caca9aa4..12de95b0472e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -10189,10 +10189,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) {
@@ -10409,11 +10405,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;
@@ -10427,11 +10418,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
@@ -10501,6 +10487,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

Reply via email to