]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf tools: Use scnprintf() in build_id__snprintf() and hwmon read_events()
authorArnaldo Carvalho de Melo <acme@redhat.com>
Sun, 7 Jun 2026 17:36:57 +0000 (14:36 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 10 Jun 2026 18:23:53 +0000 (15:23 -0300)
build_id__snprintf() and hwmon_pmu__read_events() accumulate formatted
output via snprintf(), which returns the would-have-been-written count
on truncation.  In build_id__snprintf(), this inflates the return
value beyond the buffer size.  In hwmon_pmu__read_events(), len
overshoots out_buf_len and the next 'out_buf_len - len' underflows.

Switch both to scnprintf() which returns actual bytes written.

In build_id__snprintf(), also tighten the loop guard from
'offs < bf_size' to 'offs + 1 < bf_size': since scnprintf() returns
at most size-1, offs never reaches bf_size, and the original condition
would spin doing zero-byte writes once the buffer fills.

Fixes: fccaaf6fbbc59910 ("perf build-id: Change sprintf functions to snprintf")
Fixes: 53cc0b351ec99278 ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/build-id.c
tools/perf/util/hwmon_pmu.c

index 8c0a9ae932aa5798a7554f911e40dd3f9f045a62..eb95ab90f9741d5f85c04dd789a2890b66bccd11 100644 (file)
@@ -93,8 +93,11 @@ int build_id__snprintf(const struct build_id *build_id, char *bf, size_t bf_size
                return 0;
        }
 
-       for (size_t i = 0; i < build_id->size && offs < bf_size; ++i)
-               offs += snprintf(bf + offs, bf_size - offs, "%02x", build_id->data[i]);
+       if (bf_size > 0)
+               bf[0] = '\0';
+
+       for (size_t i = 0; i < build_id->size && offs + 1 < bf_size; ++i)
+               offs += scnprintf(bf + offs, bf_size - offs, "%02x", build_id->data[i]);
 
        return offs;
 }
index fb3ffa8d32ad2a93ae1a355e1247ccc1b74e09ee..dbf6a71af47f9a42d4c5e4f86c10635efcb0e83f 100644 (file)
@@ -442,12 +442,12 @@ static size_t hwmon_pmu__describe_items(struct hwmon_pmu *hwm, char *out_buf, si
 
                                buf[read_len] = '\0';
                                val = strtoll(buf, /*endptr=*/NULL, 10);
-                               len += snprintf(out_buf + len, out_buf_len - len, "%s%s%s=%g%s",
-                                               len == 0 ? " " : ", ",
-                                               hwmon_item_strs[bit],
-                                               is_alarm ? "_alarm" : "",
-                                               (double)val / 1000.0,
-                                               hwmon_units[key.type]);
+                               len += scnprintf(out_buf + len, out_buf_len - len, "%s%s%s=%g%s",
+                                                len == 0 ? " " : ", ",
+                                                hwmon_item_strs[bit],
+                                                is_alarm ? "_alarm" : "",
+                                                (double)val / 1000.0,
+                                                hwmon_units[key.type]);
                        }
                        close(fd);
                }