mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
perf: Satisfy the kernel's request to request PMU counters
The SELinux policy on Android doesn't provide the kernel-space with CAP_SYS_ADMIN capability. The perf-core checks for this capability before giving access to the callers to read the PMU counters. Hence, when the kernel drivers try to gain access to the PMU (via perf_event_create_kernel_counter()), it fails with -EACCES. To get past this, add another condition to check if the request is coming from kernel-space or user-space. If kernel-space, don't check for the capability any further and move on. Change-Id: Ie2ddc6b619fa0d60d4752994ea0c9cedf5b96b5c Signed-off-by: Raghavendra Rao Ananta <rananta@codeaurora.org>
This commit is contained in:
parent
333b4ccb21
commit
e5ac623a25
2 changed files with 18 additions and 11 deletions
|
|
@ -1253,6 +1253,13 @@ int perf_event_max_stack_handler(struct ctl_table *table, int write,
|
|||
#define PERF_SECURITY_KERNEL 2
|
||||
#define PERF_SECURITY_TRACEPOINT 3
|
||||
|
||||
#define TASK_TOMBSTONE ((void *)-1L)
|
||||
|
||||
static bool is_kernel_event(struct perf_event *event)
|
||||
{
|
||||
return READ_ONCE(event->owner) == TASK_TOMBSTONE;
|
||||
}
|
||||
|
||||
static inline bool perf_paranoid_any(void)
|
||||
{
|
||||
return sysctl_perf_event_paranoid > 2;
|
||||
|
|
@ -1271,12 +1278,19 @@ static inline int perf_allow_kernel(struct perf_event_attr *attr)
|
|||
return security_perf_event_open(attr, PERF_SECURITY_KERNEL);
|
||||
}
|
||||
|
||||
static inline int perf_allow_cpu(struct perf_event_attr *attr)
|
||||
static inline int perf_allow_cpu(struct perf_event *event)
|
||||
{
|
||||
if (sysctl_perf_event_paranoid > 0 && !capable(CAP_SYS_ADMIN))
|
||||
if (sysctl_perf_event_paranoid > 0 && !is_kernel_event(event) &&
|
||||
!capable(CAP_SYS_ADMIN)) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
return security_perf_event_open(attr, PERF_SECURITY_CPU);
|
||||
/*
|
||||
* Bypass the system call security check if the
|
||||
* event creation is from the kernel
|
||||
*/
|
||||
return is_kernel_event(event) ? 0 :
|
||||
security_perf_event_open(&event->attr, PERF_SECURITY_CPU);
|
||||
}
|
||||
|
||||
static inline int perf_allow_tracepoint(struct perf_event_attr *attr)
|
||||
|
|
|
|||
|
|
@ -164,13 +164,6 @@ static void perf_ctx_unlock(struct perf_cpu_context *cpuctx,
|
|||
raw_spin_unlock(&cpuctx->ctx.lock);
|
||||
}
|
||||
|
||||
#define TASK_TOMBSTONE ((void *)-1L)
|
||||
|
||||
static bool is_kernel_event(struct perf_event *event)
|
||||
{
|
||||
return READ_ONCE(event->owner) == TASK_TOMBSTONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* On task ctx scheduling...
|
||||
*
|
||||
|
|
@ -4234,7 +4227,7 @@ find_get_context(struct pmu *pmu, struct task_struct *task,
|
|||
|
||||
if (!task) {
|
||||
/* Must be root to operate on a CPU event: */
|
||||
err = perf_allow_cpu(&event->attr);
|
||||
err = perf_allow_cpu(event);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue