fortify-headers

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

commit 22a8094b41b2606084dc0c0c70487e5ed0fcb652
parent f3c0bfdb96ec00aaefdb75024059aa33895726c5
Author: jvoisin <julien.voisin@dustri.org>
Date:   Wed, 27 Dec 2023 17:07:32 +0100

Re-enable previously disabled overlap checks

They were previously disabled in 80a83a5

Diffstat:
Minclude/string.h | 29++++++++++++-----------------
Mtests/test_stpncpy_dynamic_write.c | 5+++--
Mtests/test_stpncpy_overwrite_over.c | 5+++--
Mtests/test_stpncpy_overwrite_under.c | 10++++++----
Mtests/test_strncpy_overwrite_over.c | 13+++++++++----
Mtests/test_strncpy_overwrite_under.c | 2--
6 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/include/string.h b/include/string.h @@ -189,19 +189,17 @@ _FORTIFY_FN(stpncpy) char *stpncpy(char * _FORTIFY_POS0 __d, const char *__s, #if __has_builtin(__builtin___stpncpy_chk) && USE_NATIVE_CHK return __builtin___stpncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); #else -#if 0 - // They check overlap across the whole range of the given length, but - // the given length is not what will actually be copied, rather it's - // the maximum length (if src is shorter, only length of src will be - // copied). This triggers false positives and traps where it shouldn't - // (e.g. in ICU tests). - if (__fh_overlap(__d, __s, __n)) + __fh_size_t max_len_s = strnlen(__s, __n); + if (__fh_overlap(__d, max_len_s, __s, max_len_s)) __builtin_trap(); -#endif + // 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') __fh_size_t __b = __fh_bos(__d, 0); - if (__n > __b && strlen(__s) + 1 > __b) + if (__n > __b) __builtin_trap(); + return __orig_stpncpy(__d, __s, __n); #endif } @@ -297,19 +295,16 @@ _FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d, #if __has_builtin(__builtin___strncpy_chk) && USE_NATIVE_CHK return __builtin___strncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); #else -#if 0 - // They check overlap across the whole range of the given length, but - // the given length is not what will actually be copied, rather it's - // the maximum length (if src is shorter, only length of src will be - // copied). This triggers false positives and traps where it shouldn't - // (e.g. in ICU tests). - if (__fh_overlap(__d, __s, __n)) + __fh_size_t max_len_s = strnlen(__s, __n); + if (__fh_overlap(__d, max_len_s, __s, max_len_s)) __builtin_trap(); -#endif + // 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); if (__n > __b) __builtin_trap(); + return __orig_strncpy(__d, __s, __n); #endif } diff --git a/tests/test_stpncpy_dynamic_write.c b/tests/test_stpncpy_dynamic_write.c @@ -3,8 +3,9 @@ #include <string.h> int main(int argc, char** argv) { - char buffer[8] = {0}; - stpncpy(buffer, "1234567", 5); + char buffer[] = {'A', 'B', 'C', 'D', 'E', 'F', '\0'}; + + stpncpy(buffer, "1234567", 3); puts(buffer); CHK_FAIL_START diff --git a/tests/test_stpncpy_overwrite_over.c b/tests/test_stpncpy_overwrite_over.c @@ -3,15 +3,16 @@ #include <string.h> int main(int argc, char** argv) { -#if 0 char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; puts(buffer); + stpncpy(buffer, buffer+5, 2); + puts(buffer); + CHK_FAIL_START stpncpy(buffer+1, buffer, 5); CHK_FAIL_END puts(buffer); -#endif return ret; } diff --git a/tests/test_stpncpy_overwrite_under.c b/tests/test_stpncpy_overwrite_under.c @@ -3,15 +3,17 @@ #include <string.h> int main(int argc, char** argv) { -#if 0 char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; puts(buffer); + stpncpy(buffer+5, buffer, 2); + puts(buffer); + + char buffer2[] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; CHK_FAIL_START - stpncpy(buffer-1, buffer, 5); + stpncpy(buffer2-1, buffer2, 5); CHK_FAIL_END - puts(buffer); -#endif + puts(buffer2); return ret; } diff --git a/tests/test_strncpy_overwrite_over.c b/tests/test_strncpy_overwrite_over.c @@ -3,15 +3,20 @@ #include <string.h> int main(int argc, char** argv) { -#if 0 char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; puts(buffer); + strncpy(buffer, buffer+4, 1); + puts(buffer); + + strncpy(buffer+6, buffer, 1); + puts(buffer); + + char buffer2[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; CHK_FAIL_START - strncpy(buffer+1, buffer, 5); + strncpy(buffer2+1, buffer2, 5); CHK_FAIL_END - puts(buffer); -#endif + puts(buffer2); return ret; } diff --git a/tests/test_strncpy_overwrite_under.c b/tests/test_strncpy_overwrite_under.c @@ -3,7 +3,6 @@ #include <string.h> int main(int argc, char** argv) { -#if 0 char buffer[9] = {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', '\0'}; puts(buffer); @@ -12,6 +11,5 @@ int main(int argc, char** argv) { CHK_FAIL_END puts(buffer); -#endif return ret; }