diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/perf_counter.c | 25 | ||||
-rw-r--r-- | kernel/sysctl.c | 6 |
2 files changed, 26 insertions, 5 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 | */ |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 0c4bf863afa3..344a65981dee 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -916,9 +916,9 @@ static struct ctl_table kern_table[] = { | |||
916 | #ifdef CONFIG_PERF_COUNTERS | 916 | #ifdef CONFIG_PERF_COUNTERS |
917 | { | 917 | { |
918 | .ctl_name = CTL_UNNUMBERED, | 918 | .ctl_name = CTL_UNNUMBERED, |
919 | .procname = "perf_counter_privileged", | 919 | .procname = "perf_counter_paranoid", |
920 | .data = &sysctl_perf_counter_priv, | 920 | .data = &sysctl_perf_counter_paranoid, |
921 | .maxlen = sizeof(sysctl_perf_counter_priv), | 921 | .maxlen = sizeof(sysctl_perf_counter_paranoid), |
922 | .mode = 0644, | 922 | .mode = 0644, |
923 | .proc_handler = &proc_dointvec, | 923 | .proc_handler = &proc_dointvec, |
924 | }, | 924 | }, |