summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2024-10-10 15:50:40 +0200
committerjvoisin2024-10-10 15:50:40 +0200
commite2cfd2879a15db00dfa9a42eeb1baaef6a930aff (patch)
tree45c61bbdde9a510ba7125e00399781a98dc39cc5
parentc3b48c6b0bf501802295c85b1cf54275d6b74883 (diff)
Fix a crash in strncpy/stpncpystrn
``` 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
Diffstat (limited to '')
-rw-r--r--include/string.h12
-rw-r--r--tests/test_stpncpy_dynamic_write.c2
-rw-r--r--tests/test_stpncpy_overwrite_over.c2
-rw-r--r--tests/test_stpncpy_overwrite_under.c2
-rw-r--r--tests/test_strncpy_dynamic_write.c4
-rw-r--r--tests/test_strncpy_overwrite_over.c2
-rw-r--r--tests/test_strncpy_overwrite_under.c2
-rw-r--r--tests/test_strncpy_static_write.c6
8 files changed, 16 insertions, 16 deletions
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,
208#if __has_builtin(__builtin___stpncpy_chk) && FORTIFY_USE_NATIVE_CHK 208#if __has_builtin(__builtin___stpncpy_chk) && FORTIFY_USE_NATIVE_CHK
209 return __builtin___stpncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); 209 return __builtin___stpncpy_chk(__d, __s, __n, __fh_bos(__d, 0));
210#else 210#else
211 __fh_size_t max_len_s = strlen(__s);
212 if (max_len_s > __n)
213 max_len_s = __n;
214 if (__fh_overlap(__d, max_len_s, __s, max_len_s))
215 __builtin_trap();
216
217 // If the length strlen(src) is smaller than n, the remaining 211 // If the length strlen(src) is smaller than n, the remaining
218 // characters in the array pointed to by dest are filled with null 212 // characters in the array pointed to by dest are filled with null
219 // bytes ('\0') 213 // bytes ('\0')
@@ -318,12 +312,6 @@ _FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d,
318#if __has_builtin(__builtin___strncpy_chk) && FORTIFY_USE_NATIVE_CHK 312#if __has_builtin(__builtin___strncpy_chk) && FORTIFY_USE_NATIVE_CHK
319 return __builtin___strncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); 313 return __builtin___strncpy_chk(__d, __s, __n, __fh_bos(__d, 0));
320#else 314#else
321 __fh_size_t max_len_s = strlen(__s);
322 if (max_len_s > __n)
323 max_len_s = __n;
324 if (__fh_overlap(__d, max_len_s, __s, max_len_s))
325 __builtin_trap();
326
327 // If the length of src is less than n, strncpy() writes additional 315 // If the length of src is less than n, strncpy() writes additional
328 // null bytes to dest to ensure that a total of n bytes are written. 316 // null bytes to dest to ensure that a total of n bytes are written.
329 __fh_size_t __b = __fh_bos(__d, 0); 317 __fh_size_t __b = __fh_bos(__d, 0);
diff --git a/tests/test_stpncpy_dynamic_write.c b/tests/test_stpncpy_dynamic_write.c
index 14f6fd9..d315ee8 100644
--- a/tests/test_stpncpy_dynamic_write.c
+++ b/tests/test_stpncpy_dynamic_write.c
@@ -3,7 +3,7 @@
3#include <string.h> 3#include <string.h>
4 4
5int main(int argc, char** argv) { 5int main(int argc, char** argv) {
6 char buffer[] = {'A', 'B', 'C', 'D', 'E', 'F', '\0'}; 6 char buffer[] = {'A', 'B', 'C', 'D', 'E', 'F'};
7 7
8 stpncpy(buffer, "1234567", 3); 8 stpncpy(buffer, "1234567", 3);
9 puts(buffer); 9 puts(buffer);
diff --git a/tests/test_stpncpy_overwrite_over.c b/tests/test_stpncpy_overwrite_over.c
index 21c88ce..c6c5307 100644
--- a/tests/test_stpncpy_overwrite_over.c
+++ b/tests/test_stpncpy_overwrite_over.c
@@ -9,9 +9,11 @@ int main(int argc, char** argv) {
9 stpncpy(buffer, buffer+5, 2); 9 stpncpy(buffer, buffer+5, 2);
10 puts(buffer); 10 puts(buffer);
11 11
12#if 0
12 CHK_FAIL_START 13 CHK_FAIL_START
13 stpncpy(buffer+1, buffer, 5); 14 stpncpy(buffer+1, buffer, 5);
14 CHK_FAIL_END 15 CHK_FAIL_END
16#endif
15 17
16 puts(buffer); 18 puts(buffer);
17 return ret; 19 return ret;
diff --git a/tests/test_stpncpy_overwrite_under.c b/tests/test_stpncpy_overwrite_under.c
index 3b435de..d35d083 100644
--- a/tests/test_stpncpy_overwrite_under.c
+++ b/tests/test_stpncpy_overwrite_under.c
@@ -10,9 +10,11 @@ int main(int argc, char** argv) {
10 puts(buffer); 10 puts(buffer);
11 11
12 char buffer2[] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; 12 char buffer2[] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'};
13#if 0
13 CHK_FAIL_START 14 CHK_FAIL_START
14 stpncpy(buffer2-1, buffer2, 5); 15 stpncpy(buffer2-1, buffer2, 5);
15 CHK_FAIL_END 16 CHK_FAIL_END
17#endif
16 18
17 puts(buffer2); 19 puts(buffer2);
18 return ret; 20 return ret;
diff --git a/tests/test_strncpy_dynamic_write.c b/tests/test_strncpy_dynamic_write.c
index 6af18a7..c779267 100644
--- a/tests/test_strncpy_dynamic_write.c
+++ b/tests/test_strncpy_dynamic_write.c
@@ -4,7 +4,9 @@
4 4
5int main(int argc, char** argv) { 5int main(int argc, char** argv) {
6 char buffer[8] = {0}; 6 char buffer[8] = {0};
7 strncpy(buffer, "1234567", 5); 7 char src[] = {'A', 'B', 'C', 'D', 'E', 'F'};
8
9 strncpy(buffer, src, 5);
8 puts(buffer); 10 puts(buffer);
9 11
10 CHK_FAIL_START 12 CHK_FAIL_START
diff --git a/tests/test_strncpy_overwrite_over.c b/tests/test_strncpy_overwrite_over.c
index d99d270..90897b6 100644
--- a/tests/test_strncpy_overwrite_over.c
+++ b/tests/test_strncpy_overwrite_over.c
@@ -13,9 +13,11 @@ int main(int argc, char** argv) {
13 puts(buffer); 13 puts(buffer);
14 14
15 char buffer2[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; 15 char buffer2[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'};
16#if 0
16 CHK_FAIL_START 17 CHK_FAIL_START
17 strncpy(buffer2+1, buffer2, 5); 18 strncpy(buffer2+1, buffer2, 5);
18 CHK_FAIL_END 19 CHK_FAIL_END
20#endif
19 21
20 puts(buffer2); 22 puts(buffer2);
21 return ret; 23 return ret;
diff --git a/tests/test_strncpy_overwrite_under.c b/tests/test_strncpy_overwrite_under.c
index f554b28..568f414 100644
--- a/tests/test_strncpy_overwrite_under.c
+++ b/tests/test_strncpy_overwrite_under.c
@@ -6,9 +6,11 @@ int main(int argc, char** argv) {
6 char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; 6 char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'};
7 puts(buffer); 7 puts(buffer);
8 8
9#if 0
9 CHK_FAIL_START 10 CHK_FAIL_START
10 strncpy(buffer-1, buffer, 5); 11 strncpy(buffer-1, buffer, 5);
11 CHK_FAIL_END 12 CHK_FAIL_END
13#endif
12 14
13 puts(buffer); 15 puts(buffer);
14 return ret; 16 return ret;
diff --git a/tests/test_strncpy_static_write.c b/tests/test_strncpy_static_write.c
index e619288..29905ac 100644
--- a/tests/test_strncpy_static_write.c
+++ b/tests/test_strncpy_static_write.c
@@ -4,11 +4,13 @@
4 4
5int main(int argc, char** argv) { 5int main(int argc, char** argv) {
6 char buffer[8] = {0}; 6 char buffer[8] = {0};
7 strncpy(buffer, "1234567", 5); 7 char src[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'};
8
9 strncpy(buffer, src, 5);
8 puts(buffer); 10 puts(buffer);
9 11
10 CHK_FAIL_START 12 CHK_FAIL_START
11 strncpy(buffer, "1234567890", 10); 13 strncpy(buffer, src, 10);
12 CHK_FAIL_END 14 CHK_FAIL_END
13 15
14 puts(buffer); 16 puts(buffer);