2022-02-01 16:23:00

by Marco Elver

[permalink] [raw]
Subject: [PATCH 1/3] 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 <[email protected]>
Signed-off-by: Marco Elver <[email protected]>
---
kernel/events/core.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index fc18664f49b0..db0d85a85f1b 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3197,6 +3197,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)
{
@@ -3219,10 +3228,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;
--
2.35.0.rc2.247.g8bbb082509-goog


2022-02-01 16:23:00

by Marco Elver

[permalink] [raw]
Subject: [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures

Due to the alignment requirements of siginfo_t, as described in
3ddb3fd8cdb0 ("signal, perf: Fix siginfo_t by avoiding u64 on 32-bit
architectures"), siginfo_t::si_perf_data is limited to an unsigned long.

However, perf_event_attr::sig_data is an u64, to avoid having to deal
with compat conversions. Due to being an u64, it may not immediately be
clear to users that sig_data is truncated on 32 bit architectures.

Add a comment to explicitly point this out, and hopefully help some
users save time by not having to deduce themselves what's happening.

Reported-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Marco Elver <[email protected]>
---
include/uapi/linux/perf_event.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 1b65042ab1db..82858b697c05 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -465,6 +465,8 @@ struct perf_event_attr {
/*
* User provided data if sigtrap=1, passed back to user via
* siginfo_t::si_perf_data, e.g. to permit user to identify the event.
+ * Note, siginfo_t::si_perf_data is long-sized, and sig_data will be
+ * truncated accordingly on 32 bit architectures.
*/
__u64 sig_data;
};
--
2.35.0.rc2.247.g8bbb082509-goog

2022-02-02 06:53:12

by Dmitry Vyukov

[permalink] [raw]
Subject: Re: [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification

On Mon, 31 Jan 2022 at 11:34, Marco Elver <[email protected]> wrote:
>
> 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 <[email protected]>
> Signed-off-by: Marco Elver <[email protected]>

Reviewed-by: Dmitry Vyukov <[email protected]>

Thanks for the quick fix.

> ---
> kernel/events/core.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index fc18664f49b0..db0d85a85f1b 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -3197,6 +3197,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)
> {
> @@ -3219,10 +3228,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;
> --
> 2.35.0.rc2.247.g8bbb082509-goog
>

2022-02-02 10:42:01

by Dmitry Vyukov

[permalink] [raw]
Subject: Re: [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures

On Mon, 31 Jan 2022 at 11:34, Marco Elver <[email protected]> wrote:
>
> Due to the alignment requirements of siginfo_t, as described in
> 3ddb3fd8cdb0 ("signal, perf: Fix siginfo_t by avoiding u64 on 32-bit
> architectures"), siginfo_t::si_perf_data is limited to an unsigned long.
>
> However, perf_event_attr::sig_data is an u64, to avoid having to deal
> with compat conversions. Due to being an u64, it may not immediately be
> clear to users that sig_data is truncated on 32 bit architectures.
>
> Add a comment to explicitly point this out, and hopefully help some
> users save time by not having to deduce themselves what's happening.
>
> Reported-by: Dmitry Vyukov <[email protected]>
> Signed-off-by: Marco Elver <[email protected]>

Reviewed-by: Dmitry Vyukov <[email protected]>


> ---
> include/uapi/linux/perf_event.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index 1b65042ab1db..82858b697c05 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -465,6 +465,8 @@ struct perf_event_attr {
> /*
> * User provided data if sigtrap=1, passed back to user via
> * siginfo_t::si_perf_data, e.g. to permit user to identify the event.
> + * Note, siginfo_t::si_perf_data is long-sized, and sig_data will be
> + * truncated accordingly on 32 bit architectures.
> */
> __u64 sig_data;
> };
> --
> 2.35.0.rc2.247.g8bbb082509-goog
>

2022-02-02 14:04:13

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification

On Tue, Feb 01, 2022 at 08:32:45AM +0100, Dmitry Vyukov wrote:
> On Mon, 31 Jan 2022 at 11:34, Marco Elver <[email protected]> wrote:
> >
> > 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 <[email protected]>
> > Signed-off-by: Marco Elver <[email protected]>
>
> Reviewed-by: Dmitry Vyukov <[email protected]>

Thanks guys! Queued for perf/urgent

Subject: [tip: perf/urgent] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID: ddecd22878601a606d160680fa85802b75d92eb6
Gitweb: https://git.kernel.org/tip/ddecd22878601a606d160680fa85802b75d92eb6
Author: Marco Elver <[email protected]>
AuthorDate: Mon, 31 Jan 2022 11:34:07 +01:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Wed, 02 Feb 2022 13:11:40 +01:00

perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures

Due to the alignment requirements of siginfo_t, as described in
3ddb3fd8cdb0 ("signal, perf: Fix siginfo_t by avoiding u64 on 32-bit
architectures"), siginfo_t::si_perf_data is limited to an unsigned long.

However, perf_event_attr::sig_data is an u64, to avoid having to deal
with compat conversions. Due to being an u64, it may not immediately be
clear to users that sig_data is truncated on 32 bit architectures.

Add a comment to explicitly point this out, and hopefully help some
users save time by not having to deduce themselves what's happening.

Reported-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Marco Elver <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Dmitry Vyukov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
include/uapi/linux/perf_event.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 1b65042..82858b6 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -465,6 +465,8 @@ struct perf_event_attr {
/*
* User provided data if sigtrap=1, passed back to user via
* siginfo_t::si_perf_data, e.g. to permit user to identify the event.
+ * Note, siginfo_t::si_perf_data is long-sized, and sig_data will be
+ * truncated accordingly on 32 bit architectures.
*/
__u64 sig_data;
};

Subject: [tip: perf/urgent] perf: Copy perf_event_attr::sig_data on modification

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID: 3c25fc97f5590060464cabfa25710970ecddbc96
Gitweb: https://git.kernel.org/tip/3c25fc97f5590060464cabfa25710970ecddbc96
Author: Marco Elver <[email protected]>
AuthorDate: Mon, 31 Jan 2022 11:34:05 +01:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Wed, 02 Feb 2022 13:11:40 +01:00

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 <[email protected]>
Signed-off-by: Marco Elver <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Dmitry Vyukov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
kernel/events/core.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 76c754e..57c7197 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;