perf tools: Use scnprintf() in build_id__snprintf() and hwmon read_events()

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: fccaaf6fbb ("perf build-id: Change sprintf functions to snprintf")
Fixes: 53cc0b351e ("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>
This commit is contained in:
Arnaldo Carvalho de Melo 2026-06-07 14:36:57 -03:00
parent 227a874874
commit e33711d5e7
2 changed files with 11 additions and 8 deletions

View 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;
}

View 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);
}