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

perf ordered_events: Prevent crossing max_alloc_size

Stephane reported a possible issue in the ordered events code, which
could lead to allocating more memory than guarded by max_alloc_size.

He also suggested the fix to properly check that the new size is below
the max_alloc_size limit.

Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180907102455.7030-2-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
53da12e0 d5ceb62b

+4 -4
+4 -4
tools/perf/util/ordered-events.c
··· 101 101 struct list_head *cache = &oe->cache; 102 102 struct ordered_event *new = NULL; 103 103 union perf_event *new_event; 104 + size_t size; 104 105 105 106 new_event = dup_event(oe, event); 106 107 if (!new_event) ··· 134 133 * Removal of ordered event object moves it from events to 135 134 * the cache list. 136 135 */ 136 + size = sizeof(*oe->buffer) + MAX_SAMPLE_BUFFER * sizeof(*new); 137 + 137 138 if (!list_empty(cache)) { 138 139 new = list_entry(cache->next, struct ordered_event, list); 139 140 list_del(&new->list); ··· 143 140 new = &oe->buffer->event[oe->buffer_idx]; 144 141 if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) 145 142 oe->buffer = NULL; 146 - } else if (oe->cur_alloc_size < oe->max_alloc_size) { 147 - size_t size = sizeof(*oe->buffer) + 148 - MAX_SAMPLE_BUFFER * sizeof(*new); 149 - 143 + } else if ((oe->cur_alloc_size + size) < oe->max_alloc_size) { 150 144 oe->buffer = malloc(size); 151 145 if (!oe->buffer) { 152 146 free_dup_event(oe, new_event);