mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
perf tools: Fix int16_t truncation of max_cpu_num in set_max_cpu_num()
set_max_cpu_num() assigns the sysfs "possible" CPU count to max_cpu_num.cpu which is int16_t (struct perf_cpu). On systems with >32767 possible CPUs the value silently truncates, potentially wrapping negative. This causes cpunode_map to be underallocated and subsequent cpu__get_node() calls to read out of bounds. The matching check for max_present_cpu_num was added by commitc760174401("perf cpumap: Reduce cpu size from int to int16_t") but max_cpu_num was missed. Add the same INT16_MAX guard. Fixes:c760174401("perf cpumap: Reduce cpu size from int to int16_t") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Cc: Ian Rogers <irogers@google.com> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e2496db45b
commit
33fa2bf560
|
|
@ -494,6 +494,16 @@ static void set_max_cpu_num(void)
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* struct perf_cpu.cpu is int16_t (libperf ABI) — clamp to avoid
|
||||
* truncation to negative. See tools/lib/perf/TODO for the ABI
|
||||
* widening plan.
|
||||
*/
|
||||
if (max > INT16_MAX) {
|
||||
pr_warning("WARNING: max possible cpus %d exceeds int16_t, clamping to %d\n",
|
||||
max, INT16_MAX);
|
||||
max = INT16_MAX;
|
||||
}
|
||||
max_cpu_num.cpu = max;
|
||||
|
||||
/* get the highest present cpu number for a sparse allocation */
|
||||
|
|
@ -506,11 +516,12 @@ static void set_max_cpu_num(void)
|
|||
ret = get_max_num(path, &max);
|
||||
|
||||
if (!ret && max > INT16_MAX) {
|
||||
pr_err("Read out of bounds max cpus of %d\n", max);
|
||||
ret = -1;
|
||||
pr_warning("WARNING: max present cpus %d exceeds int16_t, clamping to %d\n",
|
||||
max, INT16_MAX);
|
||||
max = INT16_MAX;
|
||||
}
|
||||
if (!ret)
|
||||
max_present_cpu_num.cpu = (int16_t)max;
|
||||
max_present_cpu_num.cpu = max;
|
||||
out:
|
||||
if (ret)
|
||||
pr_err("Failed to read max cpus, using default of %d\n", max_cpu_num.cpu);
|
||||
|
|
@ -647,7 +658,9 @@ int cpu__setup_cpunode_map(void)
|
|||
while ((dent2 = readdir(dir2)) != NULL) {
|
||||
if (dent2->d_type != DT_LNK || sscanf(dent2->d_name, "cpu%u", &cpu) < 1)
|
||||
continue;
|
||||
cpunode_map[cpu] = mem;
|
||||
/* cpunode_map allocated for max_cpu_num entries */
|
||||
if (cpu < (unsigned int)max_cpu_num.cpu)
|
||||
cpunode_map[cpu] = mem;
|
||||
}
|
||||
closedir(dir2);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user