]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
libkmod: fix buffer-overflow in weakdep_to_char
authorJakub Ślepecki <jakub.slepecki@intel.com>
Fri, 21 Mar 2025 10:41:35 +0000 (10:41 +0000)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Tue, 25 Mar 2025 19:14:55 +0000 (14:14 -0500)
modprobe -c with any sample weakdep command in modprobe.d will overflow
memcpy due to size calculation not incorporating trailing null byte,
for example:

==462449==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50200000067b at pc 0x7a83fe6faf59 bp 0x7ffdf6c25060 sp 0x7ffdf6c24808
WRITE of size 12 at 0x50200000067b thread T0
    0 0x7b687e6faf58 in memcpy /usr/src/debug/gcc/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc:115
    1 0x5e22b821235f in weakdep_to_char ../libkmod/libkmod-config.c:623
    2 0x5e22b821235f in weakdep_get_plain_weakdep ../libkmod/libkmod-config.c:1166
    3 0x5e22b821d049 in kmod_config_iter_get_value ../libkmod/libkmod-config.c:1317
    4 0x5e22b81fd5ec in show_config ../tools/modprobe.c:187
    5 0x5e22b81fd5ec in do_modprobe ../tools/modprobe.c:946
    6 0x7b687d635487  (/usr/lib/libc.so.6+0x27487) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    7 0x7b687d63554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 0b707b217b15b106c25fe51df3724b25848310c0)
    8 0x5e22b81da114 in _start ($PWD/kmod+0xaa114) (BuildId: c36444aefc2ca73423765d4ebf017a24e55017ee)

May also appear as:

*** buffer overflow detected ***: terminated
Aborted (core dumped)

Signed-off-by: Jakub Ślepecki <jakub.slepecki@intel.com>
Link: https://github.com/kmod-project/kmod/pull/324
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Reviewed-by: Tobias Stoeckmann <tobias@stoeckmann.org>
(cherry picked from commit 92f8dc3526008510298bd9bb8c74e0356a9a6e9c)

libkmod/libkmod-config.c
testsuite/test-weakdep.c

index 77b93929881d2efd8efcd605999c0b0ed4afa2a5..e52aae77e0f2207c42c0c8a2dfc24495bcfeb1ef 100644 (file)
@@ -581,7 +581,7 @@ static char *weakdep_to_char(struct kmod_weakdep *dep)
        /* Rely on the fact that dep->weak[] is a strv that points to a contiguous buffer */
        if (dep->n_weak > 0) {
                start = dep->weak[0];
-               end = dep->weak[dep->n_weak - 1] + strlen(dep->weak[dep->n_weak - 1]);
+               end = dep->weak[dep->n_weak - 1] + strlen(dep->weak[dep->n_weak - 1]) + 1;
                sz = end - start;
        } else
                sz = 0;
@@ -594,8 +594,8 @@ static char *weakdep_to_char(struct kmod_weakdep *dep)
                char *p;
 
                /* include last '\0' */
-               memcpy(itr, dep->weak[0], sz + 1);
-               for (p = itr; p < itr + sz; p++) {
+               memcpy(itr, dep->weak[0], sz);
+               for (p = itr; p < itr + sz - 1; p++) {
                        if (*p == '\0')
                                *p = ' ';
                }
index 61938a00228bc1f816d3ec964ed91fb80761fdc3..c4de5cc6a3471b168b9cb863acc851d59207ee54 100644 (file)
@@ -96,7 +96,6 @@ static noreturn int modprobe_config(const struct test *t)
        exit(EXIT_FAILURE);
 }
 DEFINE_TEST(modprobe_config,
-       .expected_fail = true,
        .description = "check modprobe config parsing with weakdep",
        .config = {
                [TC_UNAME_R] = "4.4.4",