From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751992AbdK2IjX (ORCPT ); Wed, 29 Nov 2017 03:39:23 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48430 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753584AbdK2IjU (ORCPT ); Wed, 29 Nov 2017 03:39:20 -0500 From: Jiri Olsa To: Ingo Molnar , Peter Zijlstra , Arnaldo Carvalho de Melo Cc: lkml , Namhyung Kim , David Ahern , Andi Kleen , Milind Chabbi , Alexander Shishkin , Michael Ellerman , Hari Bathini , Jin Yao , Kan Liang , Sukadev Bhattiprolu , Oleg Nesterov , Will Deacon Subject: [PATCH 5/8] hw_breakpoint: Add perf_event_attr fields check in __modify_user_hw_breakpoint Date: Wed, 29 Nov 2017 09:38:50 +0100 Message-Id: <20171129083853.28022-6-jolsa@kernel.org> In-Reply-To: <20171129083853.28022-1-jolsa@kernel.org> References: <20171129083853.28022-1-jolsa@kernel.org> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 29 Nov 2017 08:39:20 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Signed-off-by: Jiri Olsa --- 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) -- 2.13.6