[PATCH] perf cpumap: Use scnprintf instead of snprintf

From: Christophe JAILLET
Date: Sun Mar 22 2020 - 13:25:42 EST


'scnprintf' returns the number of characters written in the output buffer
excluding the trailing '\0', instead of the number of characters which
would be generated for the given input.

Both function return a number of characters, excluding the trailing '\0'.
So comparaison to check if it overflows, should be done against max_size-1.
Comparaison against max_size can never match.

Fixes: 7780c25bae59f ("perf tools: Allow ability to map cpus to nodes easily")
Fixes: a24020e6b7cf6 ("perf tools: Change cpu_map__fprintf output")
Fixes: 92a7e1278005b ("perf cpumap: Add cpu__max_present_cpu()")
Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx>
---
tools/perf/util/cpumap.c | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 983b7388f22b..b87e7ef4d130 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -316,8 +316,8 @@ static void set_max_cpu_num(void)
goto out;

/* get the highest possible cpu number for a sparse allocation */
- ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/possible", mnt);
- if (ret == PATH_MAX) {
+ ret = scnprintf(path, PATH_MAX, "%s/devices/system/cpu/possible", mnt);
+ if (ret == PATH_MAX-1) {
pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
goto out;
}
@@ -327,8 +327,8 @@ static void set_max_cpu_num(void)
goto out;

/* get the highest present cpu number for a sparse allocation */
- ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/present", mnt);
- if (ret == PATH_MAX) {
+ ret = scnprintf(path, PATH_MAX, "%s/devices/system/cpu/present", mnt);
+ if (ret == PATH_MAX-1) {
pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
goto out;
}
@@ -355,8 +355,8 @@ static void set_max_node_num(void)
goto out;

/* get the highest possible cpu number for a sparse allocation */
- ret = snprintf(path, PATH_MAX, "%s/devices/system/node/possible", mnt);
- if (ret == PATH_MAX) {
+ ret = scnprintf(path, PATH_MAX, "%s/devices/system/node/possible", mnt);
+ if (ret == PATH_MAX-1) {
pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
goto out;
}
@@ -440,8 +440,8 @@ int cpu__setup_cpunode_map(void)
if (!mnt)
return 0;

- n = snprintf(path, PATH_MAX, "%s/devices/system/node", mnt);
- if (n == PATH_MAX) {
+ n = scnprintf(path, PATH_MAX, "%s/devices/system/node", mnt);
+ if (n == PATH_MAX-1) {
pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
return -1;
}
@@ -455,8 +455,8 @@ int cpu__setup_cpunode_map(void)
if (dent1->d_type != DT_DIR || sscanf(dent1->d_name, "node%u", &mem) < 1)
continue;

- n = snprintf(buf, PATH_MAX, "%s/%s", path, dent1->d_name);
- if (n == PATH_MAX) {
+ n = scnprintf(buf, PATH_MAX, "%s/%s", path, dent1->d_name);
+ if (n == PATH_MAX-1) {
pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
continue;
}
@@ -501,21 +501,22 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size)
if (start == -1) {
start = i;
if (last) {
- ret += snprintf(buf + ret, size - ret,
- "%s%d", COMMA,
- map->map[i]);
+ ret += scnprintf(buf + ret, size - ret,
+ "%s%d", COMMA,
+ map->map[i]);
}
} else if (((i - start) != (cpu - map->map[start])) || last) {
int end = i - 1;

if (start == end) {
- ret += snprintf(buf + ret, size - ret,
- "%s%d", COMMA,
- map->map[start]);
+ ret += scnprintf(buf + ret, size - ret,
+ "%s%d", COMMA,
+ map->map[start]);
} else {
- ret += snprintf(buf + ret, size - ret,
- "%s%d-%d", COMMA,
- map->map[start], map->map[end]);
+ ret += scnprintf(buf + ret, size - ret,
+ "%s%d-%d", COMMA,
+ map->map[start],
+ map->map[end]);
}
first = false;
start = i;
--
2.20.1