Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1217737 > unrolled thread

perf: bug, kernel ignores the buffer size on large read

Started byVince Weaver <vincent.weaver@maine.edu>
First post2015-09-02 18:30 +0200
Last post2015-09-03 04:30 +0200
Articles 3 — 2 participants

Back to article view | Back to linux.kernel


Contents

  perf: bug, kernel ignores the buffer size on large read Vince Weaver <vincent.weaver@maine.edu> - 2015-09-02 18:30 +0200
    Re: perf: bug, kernel ignores the buffer size on large read Peter Zijlstra <peterz@infradead.org> - 2015-09-03 01:10 +0200
      Re: perf: bug, kernel ignores the buffer size on large read Vince Weaver <vincent.weaver@maine.edu> - 2015-09-03 04:30 +0200

#1217737 — perf: bug, kernel ignores the buffer size on large read

FromVince Weaver <vincent.weaver@maine.edu>
Date2015-09-02 18:30 +0200
Subjectperf: bug, kernel ignores the buffer size on large read
Message-ID<q4j58-1TL-19@gated-at.bofh.it>
OK, this time I found the actual bug.

event->read_size is declared as a u16 in include/linux/perf_event.h

but it is very easy to get event->read_size larger than 64k
(in my case, create 10000 events in a group).

Because we wrap around the u16, the 
	 if (count < event->read_size) return -ENOSPC;
in perf_read_hw() doesn't trigger reliably and so if you do a read
on a large group event the kernel will quite happily copy_to_user()
beyond the bounds of the value set in the read syscall.  

In my case it completely smashed the stack and caused the program to 
segfault.

I'm not sure what the solution is here.  Change read_size to be larger?
Ban events whose read size would be larger than 64k?  Although that gets 
tricky because the related header_size is also only a u16.

Vince

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1217905

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-03 01:10 +0200
Message-ID<q4pke-2vb-9@gated-at.bofh.it>
In reply to#1217737
On Wed, Sep 02, 2015 at 12:34:41PM -0400, Vince Weaver wrote:
> 
> OK, this time I found the actual bug.
> 
> event->read_size is declared as a u16 in include/linux/perf_event.h
> 
> but it is very easy to get event->read_size larger than 64k
> (in my case, create 10000 events in a group).
> 
> Because we wrap around the u16, the 
> 	 if (count < event->read_size) return -ENOSPC;
> in perf_read_hw() doesn't trigger reliably and so if you do a read
> on a large group event the kernel will quite happily copy_to_user()
> beyond the bounds of the value set in the read syscall.  
> 
> In my case it completely smashed the stack and caused the program to 
> segfault.
> 
> I'm not sure what the solution is here.  Change read_size to be larger?
> Ban events whose read size would be larger than 64k?  Although that gets 
> tricky because the related header_size is also only a u16.

I think we should try and just ban events with a read_size > 64k; that's
one _large_ group -- there's other issues with that as well I imagine.

If we really want to allow something larger, we _could_ fudge something
for cases where we do not have PERF_SAMPLE_READ set, but that's not
particularly nice either.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1218007

FromVince Weaver <vincent.weaver@maine.edu>
Date2015-09-03 04:30 +0200
Message-ID<q4srM-6VH-7@gated-at.bofh.it>
In reply to#1217905
On Thu, 3 Sep 2015, Peter Zijlstra wrote:

> I think we should try and just ban events with a read_size > 64k; that's
> one _large_ group -- there's other issues with that as well I imagine.

yes, I don't really have a use case for this, I just noticed the problem 
because Debian apparently bumped the default file descriptor limit from
1k to 64k and suddenly some of my perf_event_test suite started failing
in interesting ways.

The limit for read() would come down to about 4k events per group assuming 
you also have ID enabled.

The complication is that header_size is calculated similarly and lots of 
other things get added in, and a lot of it is done with u16 math.  So I 
have no idea if there's a possibility for creating sampled events that can 
corrupt the mmap buffer.

Vince
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web