diff options
author | Marco Elver <elver@google.com> | 2022-01-31 13:34:05 +0300 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2022-02-02 15:11:40 +0300 |
commit | 3c25fc97f5590060464cabfa25710970ecddbc96 (patch) | |
tree | 16a12a50cc2b3d8f07d543968e4145eb096f78e8 /kernel/events | |
parent | a01994f5e5c79d3a35e5e8cf4252c7f2147323c3 (diff) | |
download | linux-3c25fc97f5590060464cabfa25710970ecddbc96.tar.xz |
perf: Copy perf_event_attr::sig_data on modification
The intent has always been that perf_event_attr::sig_data should also be
modifiable along with PERF_EVENT_IOC_MODIFY_ATTRIBUTES, because it is
observable by user space if SIGTRAP on events is requested.
Currently only PERF_TYPE_BREAKPOINT is modifiable, and explicitly copies
relevant breakpoint-related attributes in hw_breakpoint_copy_attr().
This misses copying perf_event_attr::sig_data.
Since sig_data is not specific to PERF_TYPE_BREAKPOINT, introduce a
helper to copy generic event-type-independent attributes on
modification.
Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Link: https://lore.kernel.org/r/20220131103407.1971678-1-elver@google.com
Diffstat (limited to 'kernel/events')
-rw-r--r-- | kernel/events/core.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 76c754e45d01..57c7197838db 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3238,6 +3238,15 @@ static int perf_event_modify_breakpoint(struct perf_event *bp, return err; } +/* + * Copy event-type-independent attributes that may be modified. + */ +static void perf_event_modify_copy_attr(struct perf_event_attr *to, + const struct perf_event_attr *from) +{ + to->sig_data = from->sig_data; +} + static int perf_event_modify_attr(struct perf_event *event, struct perf_event_attr *attr) { @@ -3260,10 +3269,17 @@ static int perf_event_modify_attr(struct perf_event *event, WARN_ON_ONCE(event->ctx->parent_ctx); mutex_lock(&event->child_mutex); + /* + * Event-type-independent attributes must be copied before event-type + * modification, which will validate that final attributes match the + * source attributes after all relevant attributes have been copied. + */ + perf_event_modify_copy_attr(&event->attr, attr); err = func(event, attr); if (err) goto out; list_for_each_entry(child, &event->child_list, child_list) { + perf_event_modify_copy_attr(&child->attr, attr); err = func(child, attr); if (err) goto out; |