From e2cfd2879a15db00dfa9a42eeb1baaef6a930aff Mon Sep 17 00:00:00 2001 From: jvoisin Date: Thu, 10 Oct 2024 15:50:40 +0200 Subject: Fix a crash in strncpy/stpncpy ``` Core was generated by `scripts/mod/modpost -M -m -o Module.symvers -n -T modules.order vmlinux.o'. Program terminated with signal SIGSEGV, Segmentation fault. warning: 17 src/string/strlen.c: No such file or directory (gdb) bt ``` > I think strncpy logic is broken: `__fh_size_t max_len_s = strlen(__s);` may try read past `size_t __n`. > Create a buf without any trailing `\0`, do `strncpy(dest, buf, sizeof(buf));`, it should work, since `strncpy` will stop at `sizeof buf` > but the current fority-headers implementation will do `strlen(buf)`, which will go boom when it is not terminated with \0 Reported-by: ncopa --- include/string.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include/string.h') diff --git a/include/string.h b/include/string.h index 9df99fc..89bf25e 100644 --- a/include/string.h +++ b/include/string.h @@ -208,12 +208,6 @@ _FORTIFY_FN(stpncpy) char *stpncpy(char * _FORTIFY_POS0 __d, const char *__s, #if __has_builtin(__builtin___stpncpy_chk) && FORTIFY_USE_NATIVE_CHK return __builtin___stpncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); #else - __fh_size_t max_len_s = strlen(__s); - if (max_len_s > __n) - max_len_s = __n; - if (__fh_overlap(__d, max_len_s, __s, max_len_s)) - __builtin_trap(); - // If the length strlen(src) is smaller than n, the remaining // characters in the array pointed to by dest are filled with null // bytes ('\0') @@ -318,12 +312,6 @@ _FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d, #if __has_builtin(__builtin___strncpy_chk) && FORTIFY_USE_NATIVE_CHK return __builtin___strncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); #else - __fh_size_t max_len_s = strlen(__s); - if (max_len_s > __n) - max_len_s = __n; - if (__fh_overlap(__d, max_len_s, __s, max_len_s)) - __builtin_trap(); - // If the length of src is less than n, strncpy() writes additional // null bytes to dest to ensure that a total of n bytes are written. __fh_size_t __b = __fh_bos(__d, 0); -- cgit v1.3