perf: fix WARNING in perf_event_open

Message ID tencent_7FC26D7C2FA56EF89584E89EEE52CD20790A@qq.com
State New
Headers
Series perf: fix WARNING in perf_event_open |

Commit Message

Edward Adam Davis Dec. 26, 2023, 7:25 a.m. UTC
  The new version of __perf_event_read_size() only has a read action and does not
require a mutex, so the mutex assertion in the original loop is removed.

Fixes: 382c27f4ed28 ("perf: Fix perf_event_validate_size()")
Reported-and-tested-by: syzbot+07144c543a5c002c7305@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
 kernel/events/core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
  

Comments

Mark Rutland Jan. 5, 2024, 11:30 a.m. UTC | #1
On Wed, Dec 27, 2023 at 08:34:57AM +0100, Jiri Olsa wrote:
> On Tue, Dec 26, 2023 at 03:25:15PM +0800, Edward Adam Davis wrote:
> > The new version of __perf_event_read_size() only has a read action and does not
> > require a mutex, so the mutex assertion in the original loop is removed.
> > 
> > Fixes: 382c27f4ed28 ("perf: Fix perf_event_validate_size()")
> > Reported-and-tested-by: syzbot+07144c543a5c002c7305@syzkaller.appspotmail.com
> > Signed-off-by: Edward Adam Davis <eadavis@qq.com>
> 
> hi,
> Mark suggested another fix earlier [1], but I haven't seen the formal patch yet
> 
> jirka
> 
> 
> [1] https://lore.kernel.org/linux-perf-users/ZXwubNIxKH9s7DWt@FVFF77S0Q05N/

For the sake of the archive, that went out as:

  https://lore.kernel.org/lkml/20231215112450.3972309-1-mark.rutland@arm.com/

... was picked up in the tip branch:

  https://lore.kernel.org/lkml/170264057897.398.420625380438569608.tip-bot2@tip-bot2/

... was sent to Linus:

  https://lore.kernel.org/lkml/20231217202613.GAZX9ZZWMM%2FytA74VC@fat_crate.local/

... was merged in v6.7-rc6:
  
  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v6.7-rc6&id=177c2ffe69555dde28fad5ddb62a6d806982e53f

... and can be found at:

  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v6.7-rc6&id=7e2c1e4b34f07d9aa8937fab88359d4a0fce468e

Mark.

> 
> > ---
> >  kernel/events/core.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/kernel/events/core.c b/kernel/events/core.c
> > index 9efd0d7775e7..e71e61b46416 100644
> > --- a/kernel/events/core.c
> > +++ b/kernel/events/core.c
> > @@ -1924,6 +1924,10 @@ static void perf_event__id_header_size(struct perf_event *event)
> >  	event->id_header_size = size;
> >  }
> >  
> > +#define read_for_each_sibling_event(sibling, event)		\
> > +	if ((event)->group_leader == (event))			\
> > +		list_for_each_entry((sibling), &(event)->sibling_list, sibling_list)
> > +
> >  /*
> >   * Check that adding an event to the group does not result in anybody
> >   * overflowing the 64k event limit imposed by the output buffer.
> > @@ -1957,7 +1961,7 @@ static bool perf_event_validate_size(struct perf_event *event)
> >  	if (event == group_leader)
> >  		return true;
> >  
> > -	for_each_sibling_event(sibling, group_leader) {
> > +	read_for_each_sibling_event(sibling, group_leader) {
> >  		if (__perf_event_read_size(sibling->attr.read_format,
> >  					   group_leader->nr_siblings + 1) > 16*1024)
> >  			return false;
> > -- 
> > 2.43.0
> >
  
Mark Rutland Jan. 5, 2024, 11:32 a.m. UTC | #2
On Tue, Dec 26, 2023 at 03:25:15PM +0800, Edward Adam Davis wrote:
> The new version of __perf_event_read_size() only has a read action and does not
> require a mutex, so the mutex assertion in the original loop is removed.
> 
> Fixes: 382c27f4ed28 ("perf: Fix perf_event_validate_size()")
> Reported-and-tested-by: syzbot+07144c543a5c002c7305@syzkaller.appspotmail.com
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>
> ---
>  kernel/events/core.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

Thanks for the patch; this should be fixed by:

  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v6.7-rc6&id=7e2c1e4b34f07d9aa8937fab88359d4a0fce468e

... which is in v6.7-rc6.

Mark.

> 
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 9efd0d7775e7..e71e61b46416 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -1924,6 +1924,10 @@ static void perf_event__id_header_size(struct perf_event *event)
>  	event->id_header_size = size;
>  }
>  
> +#define read_for_each_sibling_event(sibling, event)		\
> +	if ((event)->group_leader == (event))			\
> +		list_for_each_entry((sibling), &(event)->sibling_list, sibling_list)
> +
>  /*
>   * Check that adding an event to the group does not result in anybody
>   * overflowing the 64k event limit imposed by the output buffer.
> @@ -1957,7 +1961,7 @@ static bool perf_event_validate_size(struct perf_event *event)
>  	if (event == group_leader)
>  		return true;
>  
> -	for_each_sibling_event(sibling, group_leader) {
> +	read_for_each_sibling_event(sibling, group_leader) {
>  		if (__perf_event_read_size(sibling->attr.read_format,
>  					   group_leader->nr_siblings + 1) > 16*1024)
>  			return false;
> -- 
> 2.43.0
>
  

Patch

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 9efd0d7775e7..e71e61b46416 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1924,6 +1924,10 @@  static void perf_event__id_header_size(struct perf_event *event)
 	event->id_header_size = size;
 }
 
+#define read_for_each_sibling_event(sibling, event)		\
+	if ((event)->group_leader == (event))			\
+		list_for_each_entry((sibling), &(event)->sibling_list, sibling_list)
+
 /*
  * Check that adding an event to the group does not result in anybody
  * overflowing the 64k event limit imposed by the output buffer.
@@ -1957,7 +1961,7 @@  static bool perf_event_validate_size(struct perf_event *event)
 	if (event == group_leader)
 		return true;
 
-	for_each_sibling_event(sibling, group_leader) {
+	read_for_each_sibling_event(sibling, group_leader) {
 		if (__perf_event_read_size(sibling->attr.read_format,
 					   group_leader->nr_siblings + 1) > 16*1024)
 			return false;