Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Validate perf event header size

The 'size' variable includes the header so must be at least
'sizeof(struct perf_event_header)'. Error out immediately if that is
not the case. Also don't byte-swap the header until it is actually
"fetched" from the mmap region.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1372944040-32690-9-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
27389d78 93edcbd9

+10 -4
+10 -4
tools/perf/util/session.c
··· 1094 1094 perf_event_header__bswap(&event->header); 1095 1095 1096 1096 size = event->header.size; 1097 - if (size == 0) 1098 - size = 8; 1097 + if (size < sizeof(struct perf_event_header)) { 1098 + pr_err("bad event header size\n"); 1099 + goto out_err; 1100 + } 1099 1101 1100 1102 if (size > cur_size) { 1101 1103 void *new = realloc(buf, size); ··· 1166 1164 if (session->header.needs_swap) 1167 1165 perf_event_header__bswap(&event->header); 1168 1166 1169 - if (head + event->header.size > mmap_size) 1167 + if (head + event->header.size > mmap_size) { 1168 + /* We're not fetching the event so swap back again */ 1169 + if (session->header.needs_swap) 1170 + perf_event_header__bswap(&event->header); 1170 1171 return NULL; 1172 + } 1171 1173 1172 1174 return event; 1173 1175 } ··· 1251 1245 1252 1246 size = event->header.size; 1253 1247 1254 - if (size == 0 || 1248 + if (size < sizeof(struct perf_event_header) || 1255 1249 perf_session__process_event(session, event, tool, file_pos) < 0) { 1256 1250 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", 1257 1251 file_offset + head, event->header.size,