From 1ace027335c9ca0ae400958aded936d04505ec86 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Tue, 30 May 2023 20:46:14 +0200 Subject: Add a check for overlapping copies in strcpy --- include/string.h | 9 ++++++++- tests/Makefile | 2 ++ tests/test_strcpy_overwrite_over.c | 15 +++++++++++++++ tests/test_strcpy_overwrite_under.c | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/test_strcpy_overwrite_over.c create mode 100644 tests/test_strcpy_overwrite_under.c diff --git a/include/string.h b/include/string.h index f08eb4c..8685bb7 100644 --- a/include/string.h +++ b/include/string.h @@ -107,8 +107,15 @@ _FORTIFY_FN(strcat) char *strcat(char *__d, const char *__s) _FORTIFY_FN(strcpy) char *strcpy(char *__d, const char *__s) { - size_t __b = __bos(__d, 0); + size_t __n = strlen(__s) + 1; + + /* 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 (strlen(__s) + 1 > __b) __builtin_trap(); return __orig_strcpy(__d, __s); diff --git a/tests/Makefile b/tests/Makefile index 9cca6f5..18f55fe 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -13,6 +13,8 @@ TARGETS=test_memcpy_static_write \ test_memset_dynamic_write \ test_strcpy_static_write \ test_strcat_static_write \ + test_strcpy_overwrite_over \ + test_strcpy_overwrite_under\ .SILENT: diff --git a/tests/test_strcpy_overwrite_over.c b/tests/test_strcpy_overwrite_over.c new file mode 100644 index 0000000..924b346 --- /dev/null +++ b/tests/test_strcpy_overwrite_over.c @@ -0,0 +1,15 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; + puts(buffer); + + CHK_FAIL_START + strcpy(buffer+1, buffer); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_strcpy_overwrite_under.c b/tests/test_strcpy_overwrite_under.c new file mode 100644 index 0000000..2442470 --- /dev/null +++ b/tests/test_strcpy_overwrite_under.c @@ -0,0 +1,15 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; + puts(buffer); + + CHK_FAIL_START + strcpy(buffer-1, buffer); + CHK_FAIL_END + + puts(buffer); + return ret; +} -- cgit v1.3