]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf hwmon: Fix parse_hwmon_filename() strlcpy buffer overflow
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 8 Jun 2026 01:39:53 +0000 (22:39 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 10 Jun 2026 21:56:01 +0000 (18:56 -0300)
parse_hwmon_filename() strips the "_alarm" suffix from event names
by copying into a 24-byte stack buffer:

    strlcpy(fn_type, fn_item, fn_item_len - 5);

The third argument is the source length minus the suffix, not the
destination buffer capacity.  A long event name ending in "_alarm"
can have fn_item_len - 5 > sizeof(fn_type), causing strlcpy() to
write past the 24-byte fn_type[] array.  The assert() only validates
that the longest *valid* hwmon item fits, but does not protect
against crafted input.

Clamp the strlcpy size to min(fn_item_len - 5, sizeof(fn_type)).

Fixes: 4810b761f812da3c ("perf hwmon_pmu: Add hwmon filename parser")
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>
tools/perf/util/hwmon_pmu.c

index fbfb872ceb1826d8e3873910bb970706b848ceb7..bdcbe887579a1f08ccb378068ee79c23b89d84c3 100644 (file)
@@ -202,7 +202,8 @@ bool parse_hwmon_filename(const char *filename,
        fn_item_len = strlen(fn_item);
        if (fn_item_len > 6 && !strcmp(&fn_item[fn_item_len - 6], "_alarm")) {
                assert(strlen(LONGEST_HWMON_ITEM_STR) < sizeof(fn_type));
-               strlcpy(fn_type, fn_item, fn_item_len - 5);
+               /* fn_item_len - 5 strips "_alarm"; clamp to buffer size */
+               strlcpy(fn_type, fn_item, min_t(size_t, fn_item_len - 5, sizeof(fn_type)));
                fn_item = fn_type;
                *alarm = true;
        }