diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-11-18 20:07:12 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-11-18 20:07:12 +0100 |
commit | ae51ce9061b1ddc0fde363913c932bee5b9bc5fd (patch) | |
tree | 40fd3d633714d2a53fdbd2bdd172fb61232d999a /kernel | |
parent | 072b198a4ad48bd722ec6d203d65422a4698eae7 (diff) | |
parent | 423478cde453eebdfcfebf4b8d378d8f5d49b853 (diff) |
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into perf/core
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/perf_event.c | 9 | ||||
-rw-r--r-- | kernel/trace/trace_event_perf.c | 31 |
2 files changed, 30 insertions, 10 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index cb6c0d2af68..40c3aab648a 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -4773,15 +4773,6 @@ static int perf_tp_event_init(struct perf_event *event) if (event->attr.type != PERF_TYPE_TRACEPOINT) return -ENOENT; - /* - * Raw tracepoint data is a severe data leak, only allow root to - * have these. - */ - if ((event->attr.sample_type & PERF_SAMPLE_RAW) && - perf_paranoid_tracepoint_raw() && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - err = perf_trace_init(event); if (err) return err; diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 39c059ca670..19a359d5e6d 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -21,17 +21,46 @@ typedef typeof(unsigned long [PERF_MAX_TRACE_SIZE / sizeof(unsigned long)]) /* Count the events in use (per event id, not per instance) */ static int total_ref_count; +static int perf_trace_event_perm(struct ftrace_event_call *tp_event, + struct perf_event *p_event) +{ + /* No tracing, just counting, so no obvious leak */ + if (!(p_event->attr.sample_type & PERF_SAMPLE_RAW)) + return 0; + + /* Some events are ok to be traced by non-root users... */ + if (p_event->attach_state == PERF_ATTACH_TASK) { + if (tp_event->flags & TRACE_EVENT_FL_CAP_ANY) + return 0; + } + + /* + * ...otherwise raw tracepoint data can be a severe data leak, + * only allow root to have these. + */ + if (perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + return 0; +} + static int perf_trace_event_init(struct ftrace_event_call *tp_event, struct perf_event *p_event) { struct hlist_head __percpu *list; - int ret = -ENOMEM; + int ret; int cpu; + ret = perf_trace_event_perm(tp_event, p_event); + if (ret) + return ret; + p_event->tp_event = tp_event; if (tp_event->perf_refcount++ > 0) return 0; + ret = -ENOMEM; + list = alloc_percpu(struct hlist_head); if (!list) goto fail; |