mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 00:35:00 -04:00
perf auxtrace: Fix queue grow overflow and old array leak
auxtrace_queues__grow() has two bugs:
1. When idx is UINT_MAX, the caller passes new_nr_queues = idx + 1 = 0.
The function skips growing (since any nr_queues >= 0), returns
success, and the caller accesses queue_array[UINT_MAX] — an OOB
heap write. Fix by rejecting new_nr_queues == 0 up front.
2. The function allocates a new queue_array via calloc and copies
elements from the old array, but never frees the old array. Fix
by saving the old pointer and freeing it after the copy.
Fixes: e502789302 ("perf auxtrace: Add helpers for queuing AUX area tracing data")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
committed by
Namhyung Kim
parent
ab9c84d1cd
commit
96fcc9ea5f
@@ -251,8 +251,12 @@ static int auxtrace_queues__grow(struct auxtrace_queues *queues,
|
||||
{
|
||||
unsigned int nr_queues = queues->nr_queues;
|
||||
struct auxtrace_queue *queue_array;
|
||||
struct auxtrace_queue *old_array = queues->queue_array;
|
||||
unsigned int i;
|
||||
|
||||
if (!new_nr_queues)
|
||||
return -EINVAL;
|
||||
|
||||
if (!nr_queues)
|
||||
nr_queues = AUXTRACE_INIT_NR_QUEUES;
|
||||
|
||||
@@ -267,16 +271,17 @@ static int auxtrace_queues__grow(struct auxtrace_queues *queues,
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < queues->nr_queues; i++) {
|
||||
list_splice_tail(&queues->queue_array[i].head,
|
||||
list_splice_tail(&old_array[i].head,
|
||||
&queue_array[i].head);
|
||||
queue_array[i].tid = queues->queue_array[i].tid;
|
||||
queue_array[i].cpu = queues->queue_array[i].cpu;
|
||||
queue_array[i].set = queues->queue_array[i].set;
|
||||
queue_array[i].priv = queues->queue_array[i].priv;
|
||||
queue_array[i].tid = old_array[i].tid;
|
||||
queue_array[i].cpu = old_array[i].cpu;
|
||||
queue_array[i].set = old_array[i].set;
|
||||
queue_array[i].priv = old_array[i].priv;
|
||||
}
|
||||
|
||||
queues->nr_queues = nr_queues;
|
||||
queues->queue_array = queue_array;
|
||||
free(old_array);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user