diff options
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 8b89b40bd0f0..63f1987c1c1c 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -43,7 +43,23 @@ static atomic_t nr_counters __read_mostly; | |||
43 | static atomic_t nr_mmap_counters __read_mostly; | 43 | static atomic_t nr_mmap_counters __read_mostly; |
44 | static atomic_t nr_comm_counters __read_mostly; | 44 | static atomic_t nr_comm_counters __read_mostly; |
45 | 45 | ||
46 | int sysctl_perf_counter_priv __read_mostly; /* do we need to be privileged */ | 46 | /* |
47 | * 0 - not paranoid | ||
48 | * 1 - disallow cpu counters to unpriv | ||
49 | * 2 - disallow kernel profiling to unpriv | ||
50 | */ | ||
51 | int sysctl_perf_counter_paranoid __read_mostly; /* do we need to be privileged */ | ||
52 | |||
53 | static inline bool perf_paranoid_cpu(void) | ||
54 | { | ||
55 | return sysctl_perf_counter_paranoid > 0; | ||
56 | } | ||
57 | |||
58 | static inline bool perf_paranoid_kernel(void) | ||
59 | { | ||
60 | return sysctl_perf_counter_paranoid > 1; | ||
61 | } | ||
62 | |||
47 | int sysctl_perf_counter_mlock __read_mostly = 512; /* 'free' kb per user */ | 63 | int sysctl_perf_counter_mlock __read_mostly = 512; /* 'free' kb per user */ |
48 | int sysctl_perf_counter_limit __read_mostly = 100000; /* max NMIs per second */ | 64 | int sysctl_perf_counter_limit __read_mostly = 100000; /* max NMIs per second */ |
49 | 65 | ||
@@ -1385,7 +1401,7 @@ static struct perf_counter_context *find_get_context(pid_t pid, int cpu) | |||
1385 | */ | 1401 | */ |
1386 | if (cpu != -1) { | 1402 | if (cpu != -1) { |
1387 | /* Must be root to operate on a CPU counter: */ | 1403 | /* Must be root to operate on a CPU counter: */ |
1388 | if (sysctl_perf_counter_priv && !capable(CAP_SYS_ADMIN)) | 1404 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) |
1389 | return ERR_PTR(-EACCES); | 1405 | return ERR_PTR(-EACCES); |
1390 | 1406 | ||
1391 | if (cpu < 0 || cpu > num_possible_cpus()) | 1407 | if (cpu < 0 || cpu > num_possible_cpus()) |
@@ -3618,6 +3634,11 @@ SYSCALL_DEFINE5(perf_counter_open, | |||
3618 | if (copy_from_user(&attr, attr_uptr, sizeof(attr)) != 0) | 3634 | if (copy_from_user(&attr, attr_uptr, sizeof(attr)) != 0) |
3619 | return -EFAULT; | 3635 | return -EFAULT; |
3620 | 3636 | ||
3637 | if (!attr.exclude_kernel) { | ||
3638 | if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) | ||
3639 | return -EACCES; | ||
3640 | } | ||
3641 | |||
3621 | /* | 3642 | /* |
3622 | * Get the target context (task or percpu): | 3643 | * Get the target context (task or percpu): |
3623 | */ | 3644 | */ |