Messages in this thread Patch in this message | | | Date | Mon, 12 Mar 2018 23:20:47 -0700 | From | tip-bot for Jiri Olsa <> | Subject | [tip:perf/core] hw_breakpoint: Add perf_event_attr fields check in __modify_user_hw_breakpoint() |
| |
Commit-ID: 705feaf321c37e4dca3637fd5cb3b275f17a06c9 Gitweb: https://git.kernel.org/tip/705feaf321c37e4dca3637fd5cb3b275f17a06c9 Author: Jiri Olsa <jolsa@kernel.org> AuthorDate: Mon, 12 Mar 2018 14:45:45 +0100 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Tue, 13 Mar 2018 06:56:08 +0100
hw_breakpoint: Add perf_event_attr fields check in __modify_user_hw_breakpoint()
And rename it to modify_user_hw_breakpoint_check().
We are about to use modify_user_hw_breakpoint_check() for user space breakpoints modification, we must be very strict to check only the fields we can change have changed. As Peter explained:
"Suppose someone does:
attr = malloc(sizeof(*attr)); // uninitialized memory attr->type = BP; attr->bp_addr = new_addr; attr->bp_type = bp_type; attr->bp_len = bp_len; ioctl(fd, PERF_IOC_MOD_ATTR, &attr);
And feeds absolute shite for the rest of the fields. Then we later want to extend IOC_MOD_ATTR to allow changing attr::sample_type but we can't, because that would break the above application."
I'm making this check optional because we already export modify_user_hw_breakpoint() and with this check we could break existing users.
Suggested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hari Bathini <hbathini@linux.vnet.ibm.com> Cc: Jin Yao <yao.jin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Milind Chabbi <chabbi.milind@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Oleg Nesterov <onestero@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will.deacon@arm.com> Link: http://lkml.kernel.org/r/20180312134548.31532-6-jolsa@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- kernel/events/hw_breakpoint.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index a556aba223da..0c82663395f7 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -456,7 +456,9 @@ register_user_hw_breakpoint(struct perf_event_attr *attr, } EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); -static int __modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) +static int +modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr, + bool check) { u64 old_addr = bp->attr.bp_addr; u64 old_len = bp->attr.bp_len; @@ -468,6 +470,9 @@ static int __modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_ bp->attr.bp_type = attr->bp_type; bp->attr.bp_len = attr->bp_len; + if (check && memcmp(&bp->attr, attr, sizeof(*attr))) + return -EINVAL; + err = validate_hw_breakpoint(bp); if (!err && modify) err = modify_bp_slot(bp, old_type); @@ -505,7 +510,7 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att else perf_event_disable(bp); - err = __modify_user_hw_breakpoint(bp, attr); + err = modify_user_hw_breakpoint_check(bp, attr, false); if (err) { if (!bp->attr.disabled)
| |