fortify-headers

standalone fortify-source implementation
git clone git://git.2f30.org/fortify-headers
Log | Files | Refs | README | LICENSE

commit af7480d0190cb5dcf279a7ddfab320ff084a3471
parent cb1ce9e1815a492de0f13c2b046b8472024b9f6d
Author: jvoisin <julien.voisin@dustri.org>
Date:   Thu, 22 Jun 2023 17:58:58 +0200

Add tests for stpcpy

Diffstat:
Minclude/string.h | 13++++++++++---
Mtests/Makefile | 7+++++--
Atests/test_stpcpy_overwrite_over.c | 15+++++++++++++++
Atests/test_stpcpy_overwrite_under.c | 15+++++++++++++++
Atests/test_stpcpy_static_write.c | 16++++++++++++++++
5 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/include/string.h b/include/string.h @@ -85,9 +85,16 @@ __access(write_only, 1) __access(read_only, 2) _FORTIFY_FN(stpcpy) char *stpcpy(char *__d, const char *__s) { - size_t __b = __bos(__d, 0); + size_t __n = strlen(__s) + 1; - if (strlen(__s) + 1 > __b) + /* 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_stpcpy(__d, __s); } @@ -129,7 +136,7 @@ _FORTIFY_FN(strcpy) char *strcpy(char *__d, const char *__s) __builtin_trap(); size_t __b = __bos(__d, 0); - if (strlen(__s) + 1 > __b) + if (__n > __b) __builtin_trap(); return __orig_strcpy(__d, __s); } diff --git a/tests/Makefile b/tests/Makefile @@ -12,13 +12,16 @@ TARGETS=test_memcpy_static_write \ test_memmove_dynamic_read \ test_memset_static_write \ test_memset_dynamic_write \ - test_strcpy_static_write \ + test_stpcpy_overwrite_over \ + test_stpcpy_overwrite_under \ + test_stpcpy_static_write \ test_strcat_static_write \ test_strcpy_overwrite_over \ test_strcpy_overwrite_under \ - test_strncpy_static_write \ + test_strcpy_static_write \ test_strncpy_overwrite_over \ test_strncpy_overwrite_under \ + test_strncpy_static_write \ test_getcwd \ .SILENT: diff --git a/tests/test_stpcpy_overwrite_over.c b/tests/test_stpcpy_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 + stpcpy(buffer+1, buffer); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_stpcpy_overwrite_under.c b/tests/test_stpcpy_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 + stpcpy(buffer-1, buffer); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_stpcpy_static_write.c b/tests/test_stpcpy_static_write.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { + char buffer[8] = {0}; + strcpy(buffer, "1234567"); + puts(buffer); + + CHK_FAIL_START + stpcpy(buffer, "1234567890"); + CHK_FAIL_END + + puts(buffer); + return ret; +}