All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Clark <james.clark@arm.com>
To: Denis Nikitin <denik@chromium.org>,
	acme@kernel.org, linux-perf-users@vger.kernel.org
Cc: jolsa@kernel.org, alexey.budankov@linux.intel.com,
	alexander.shishkin@linux.intel.com, namhyung@kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] perf session: Remap buf if there is no space for event
Date: Thu, 31 Mar 2022 15:20:00 +0100	[thread overview]
Message-ID: <77fa14e8-6630-c0e9-21fc-2603f7383f5f@arm.com> (raw)
In-Reply-To: <20220330031130.2152327-1-denik@chromium.org>



On 30/03/2022 04:11, Denis Nikitin wrote:
> If a perf event doesn't fit into remaining buffer space return NULL to
> remap buf and fetch the event again.
> Keep the logic to error out on inadequate input from fuzzing.
> 
> This fixes perf failing on ChromeOS (with 32b userspace):
> 
>   $ perf report -v -i perf.data
>   ...
>   prefetch_event: head=0x1fffff8 event->header_size=0x30, mmap_size=0x2000000: fuzzed or compressed perf.data?
>   Error:
>   failed to process sample
> 
> Fixes: 57fc032ad643 ("perf session: Avoid infinite loop when seeing invalid header.size")
> Signed-off-by: Denis Nikitin <denik@chromium.org>
> ---
>  tools/perf/util/session.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 3b8dfe603e50..45a30040ec8d 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -2095,6 +2095,7 @@ prefetch_event(char *buf, u64 head, size_t mmap_size,
>  	       bool needs_swap, union perf_event *error)
>  {
>  	union perf_event *event;
> +	u16 event_size;
>  
>  	/*
>  	 * Ensure we have enough space remaining to read
> @@ -2107,15 +2108,23 @@ prefetch_event(char *buf, u64 head, size_t mmap_size,
>  	if (needs_swap)
>  		perf_event_header__bswap(&event->header);
>  
> -	if (head + event->header.size <= mmap_size)
> +	event_size = event->header.size;
> +	if (head + event_size <= mmap_size)
>  		return event;
>  
>  	/* We're not fetching the event so swap back again */
>  	if (needs_swap)
>  		perf_event_header__bswap(&event->header);
>  
> -	pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx:"
> -		 " fuzzed or compressed perf.data?\n",__func__, head, event->header.size, mmap_size);
> +	/* Check if the event fits into the next mmapped buf. */
> +	if (event_size <= mmap_size - head % page_size) {
> +		/* Remap buf and fetch again. */
> +		return NULL;

Hi Denis,

I tested this and it does fix the issue with a 32bit build. One concern is that the calculation to
see if it will fit in the next map is dependent on the implementation of reader__mmap(). I think it
would be possible for that to change slightly and then you could still get an infinite loop.

But I can't really see a better way to do it, and it's unlikely for reader__mmap() to be modified
to map data in a way to waste part of the buffer so it's probably fine.

Maybe you could extract a function to calculate where the new offset would be in the buffer and share
it between here and reader__mmap(). That would also make it more obvious what the 'head % page_size'
bit is for.

Either way:

Reviewed-by: James Clark <james.clark@arm.com>

> +	}
> +
> +	/* Invalid input. Event size should never exceed mmap_size. */
> +	pr_debug("%s: head=%#" PRIx64 " event->header.size=%#x, mmap_size=%#zx:"
> +		 " fuzzed or compressed perf.data?\n", __func__, head, event_size, mmap_size);
>  
>  	return error;
>  }

  parent reply	other threads:[~2022-03-31 14:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-30  3:11 [PATCH] perf session: Remap buf if there is no space for event Denis Nikitin
2022-03-31 11:44 ` Jiri Olsa
2022-04-09 15:30   ` Arnaldo Carvalho de Melo
2022-03-31 14:20 ` James Clark [this message]
2022-04-01  5:47   ` Denis Nikitin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=77fa14e8-6630-c0e9-21fc-2603f7383f5f@arm.com \
    --to=james.clark@arm.com \
    --cc=acme@kernel.org \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=alexey.budankov@linux.intel.com \
    --cc=denik@chromium.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=namhyung@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.