From: Jakub Ślepecki Date: Fri, 21 Mar 2025 10:41:35 +0000 (+0000) Subject: libkmod: fix buffer-overflow in weakdep_to_char X-Git-Tag: v34.2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d8a0745ab0f32aec9ad3665b981719d031a5611;p=thirdparty%2Fkmod.git libkmod: fix buffer-overflow in weakdep_to_char 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 Link: https://github.com/kmod-project/kmod/pull/324 Signed-off-by: Lucas De Marchi Reviewed-by: Tobias Stoeckmann (cherry picked from commit 92f8dc3526008510298bd9bb8c74e0356a9a6e9c) --- diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c index 77b93929..e52aae77 100644 --- a/libkmod/libkmod-config.c +++ b/libkmod/libkmod-config.c @@ -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 = ' '; } diff --git a/testsuite/test-weakdep.c b/testsuite/test-weakdep.c index 61938a00..c4de5cc6 100644 --- a/testsuite/test-weakdep.c +++ b/testsuite/test-weakdep.c @@ -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",