size is read directly from the input file as an unsigned int. When size == UINT_MAX, malloc(size + 1) overflows to malloc(0), so malloc(0) returns a minimal allocation while size itself remains UINT_MAX. do_read(buf, size) then attempts to read ~4 GiB into that tiny buffer, causing a heap buffer overflow.
This was previously masked by do_read()'s size parameter being 'int': passing UINT_MAX truncated it to -1, which the read() syscall rejected before any data was read. Widening do_read() to size_t is correct on its own, but it removes this accidental guard and exposes the pre-existing missing bounds check here. Fix it by rejecting size == UINT_MAX before the allocation. Signed-off-by: Tanushree Shah <[email protected]> --- tools/perf/util/trace-event-read.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 52ed496d92c3..147a3b95ce06 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -180,6 +180,11 @@ static int read_ftrace_printk(struct tep_handle *pevent) if (!size) return 0; + if (size == UINT_MAX) { + pr_debug("invalid ftrace printk size\n"); + return -1; + } + buf = malloc(size + 1); if (buf == NULL) return -1; -- 2.47.3
