commit cb1ce9e1815a492de0f13c2b046b8472024b9f6d
parent 58168afc8b2328c24137820c5fbe7c9775901944
Author: jvoisin <julien.voisin@dustri.org>
Date: Wed, 14 Jun 2023 14:59:11 +0200
Add tests for strncpy and handle overlapping buffers there
Diffstat:
5 files changed, 70 insertions(+), 16 deletions(-)
diff --git a/include/string.h b/include/string.h
@@ -156,8 +156,13 @@ __access (write_only, 1)
__access (read_only, 2, 3)
_FORTIFY_FN(strncpy) char *strncpy(char *__d, const char *__s, size_t __n)
{
- size_t __b = __bos(__d, 0);
+ /* trap if pointers are overlapping but not if dst == src.
+ * gcc seems to like to generate code that relies on dst == src */
+ if ((__d < __s && __d + __n > __s) ||
+ (__s < __d && __s + __n > __d))
+ __builtin_trap();
+ size_t __b = __bos(__d, 0);
if (__n > __b)
__builtin_trap();
return __orig_strncpy(__d, __s, __n);
diff --git a/tests/Makefile b/tests/Makefile
@@ -2,21 +2,24 @@ CC=../x86_64-linux-musl-native/bin/gcc
GCOV=../x86_64-linux-musl-native/bin/gcov
CFLAGS=-I../include/ -D_FORTIFY_SOURCE=3 -static -O2
-TARGETS=test_memcpy_static_write \
- test_memcpy_dynamic_write \
- test_memcpy_static_read \
- test_memcpy_dynamic_read \
- test_memmove_static_write \
- test_memmove_dynamic_write \
- test_memmove_static_read \
- test_memmove_dynamic_read \
- test_memset_static_write \
- test_memset_dynamic_write \
- test_strcpy_static_write \
- test_strcat_static_write \
- test_strcpy_overwrite_over \
- test_strcpy_overwrite_under\
- test_getcwd \
+TARGETS=test_memcpy_static_write \
+ test_memcpy_dynamic_write \
+ test_memcpy_static_read \
+ test_memcpy_dynamic_read \
+ test_memmove_static_write \
+ test_memmove_dynamic_write \
+ test_memmove_static_read \
+ test_memmove_dynamic_read \
+ test_memset_static_write \
+ test_memset_dynamic_write \
+ test_strcpy_static_write \
+ test_strcat_static_write \
+ test_strcpy_overwrite_over \
+ test_strcpy_overwrite_under \
+ test_strncpy_static_write \
+ test_strncpy_overwrite_over \
+ test_strncpy_overwrite_under \
+ test_getcwd \
.SILENT:
diff --git a/tests/test_strncpy_overwrite_over.c b/tests/test_strncpy_overwrite_over.c
@@ -0,0 +1,15 @@
+#include "common.h"
+
+#include <string.h>
+
+int main(int argc, char** argv) {
+ char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'};
+ puts(buffer);
+
+ CHK_FAIL_START
+ strncpy(buffer+1, buffer, 5);
+ CHK_FAIL_END
+
+ puts(buffer);
+ return ret;
+}
diff --git a/tests/test_strncpy_overwrite_under.c b/tests/test_strncpy_overwrite_under.c
@@ -0,0 +1,15 @@
+#include "common.h"
+
+#include <string.h>
+
+int main(int argc, char** argv) {
+ char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'};
+ puts(buffer);
+
+ CHK_FAIL_START
+ strncpy(buffer-1, buffer, 5);
+ CHK_FAIL_END
+
+ puts(buffer);
+ return ret;
+}
diff --git a/tests/test_strncpy_static_write.c b/tests/test_strncpy_static_write.c
@@ -0,0 +1,16 @@
+#include "common.h"
+
+#include <string.h>
+
+int main(int argc, char** argv) {
+ char buffer[8] = {0};
+ strncpy(buffer, "1234567", 5);
+ puts(buffer);
+
+ CHK_FAIL_START
+ strncpy(buffer, "1234567890", 10);
+ CHK_FAIL_END
+
+ puts(buffer);
+ return ret;
+}