fortify-headers

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

commit 140cffbe84a08669d67c3257258d2bb70ff29c3b
parent 2f60f255af5d615ca31d554035fe8268ecc9825c
Author: jvoisin <julien.voisin@dustri.org>
Date:   Fri,  8 Mar 2024 16:07:57 +0100

Add some NULL-pointers checks

See:
- https://www.imperialviolet.org/2016/06/26/nonnull.html
- https://davidben.net/2024/01/15/empty-slices.html

Diffstat:
Minclude/string.h | 15+++++++++++++++
Mtests/Makefile | 6++++++
Atests/test_memchr_null.c | 13+++++++++++++
Atests/test_memcpy_null_dst.c | 16++++++++++++++++
Atests/test_memcpy_null_src.c | 16++++++++++++++++
Atests/test_memmove_null_dst.c | 16++++++++++++++++
Atests/test_memmove_null_src.c | 16++++++++++++++++
Atests/test_memset_null.c | 13+++++++++++++
8 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/include/string.h b/include/string.h @@ -51,6 +51,9 @@ __error_if((__fh_bos(__od, 0) < __n), "'memcpy' called with `n` bigger than the #if __has_builtin(__builtin___memcpy_chk) && USE_NATIVE_CHK return __builtin___memcpy_chk(__od, __os, __n, __fh_bos(__od, 0)); #else + if (!__od || !__os) + __builtin_trap(); + __fh_size_t __bd = __fh_bos(__od, 0); __fh_size_t __bs = __fh_bos(__os, 0); char *__d = (char *)__od; @@ -75,6 +78,9 @@ _FORTIFY_FN(memmove) void *memmove(void * _FORTIFY_POS0 __d, #if __has_builtin(__builtin___memmove_chk) && USE_NATIVE_CHK return __builtin___memmove_chk(__d, __s, __n, __fh_bos(__d, 0)); #else + if (!__d || !__s) + __builtin_trap(); + __fh_size_t __bd = __fh_bos(__d, 0); __fh_size_t __bs = __fh_bos(__s, 0); @@ -94,6 +100,9 @@ __warning_if(__c != 0 && __n == 0, "'memset' will set `0` bytes; did you invert #if __has_builtin(__builtin___memset_chk) && USE_NATIVE_CHK return __builtin___memset_chk(__d, __c, __n, __fh_bos(__d, 0)); #else + if (!__d) + __builtin_trap(); + __fh_size_t __b = __fh_bos(__d, 0); if (__n > __b) @@ -111,6 +120,9 @@ _FORTIFY_FN(memchr) void *memchr(const void * _FORTIFY_POS0 __d, int __c, size_t #if __has_builtin(__builtin___memchr_chk) && USE_NATIVE_CHK return __builtin___memchr_chk(__d, __c, __n, __fh_bos(__d, 0)); #else + if (!__d) + __builtin_trap(); + __fh_size_t __b = __fh_bos(__d, 0); if (__n > __b) @@ -322,6 +334,9 @@ _FORTIFY_FN(mempcpy) void *mempcpy(void * _FORTIFY_POS0 __d, #if __has_builtin(__builtin___mempcpy_chk) && USE_NATIVE_CHK return __builtin___mempcpy_chk(__d, __s, __n, __fh_bos(__d, 0)); #else + if (!__d || !__s) + __builtin_trap(); + __fh_size_t __bd = __fh_bos(__d, 0); __fh_size_t __bs = __fh_bos(__s, 0); diff --git a/tests/Makefile b/tests/Makefile @@ -48,10 +48,15 @@ RUNTIME_TARGETS= \ test_mbstowcs_static \ test_memchr_dynamic_read \ test_memchr_static_read \ + test_memchr_null \ test_memcpy_dynamic_read \ test_memcpy_dynamic_write \ test_memcpy_overwrite_over \ test_memcpy_static_read \ + test_memcpy_null_src \ + test_memcpy_null_dst \ + test_memmove_null_src \ + test_memmove_null_dst \ test_memmove_dynamic_read \ test_memmove_dynamic_write \ test_memmove_static_read \ @@ -62,6 +67,7 @@ RUNTIME_TARGETS= \ test_mempcpy_static_write \ test_memset_dynamic_write \ test_memset_static_write \ + test_memset_null \ test_poll_dynamic \ test_poll_static \ test_ppoll_dynamic \ diff --git a/tests/test_memchr_null.c b/tests/test_memchr_null.c @@ -0,0 +1,13 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { +#ifndef __GNUC__ + CHK_FAIL_START + memchr(NULL, (int)'A', 0); + CHK_FAIL_END +#endif + + return ret; +} diff --git a/tests/test_memcpy_null_dst.c b/tests/test_memcpy_null_dst.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { +#ifndef __GNUC__ + char buffer[12] = {0}; + + CHK_FAIL_START + memcpy(buffer, NULL, 0); + CHK_FAIL_END + + puts(buffer); +#endif + return ret; +} diff --git a/tests/test_memcpy_null_src.c b/tests/test_memcpy_null_src.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { +#ifndef __GNUC__ + char buffer[12] = {0}; + + CHK_FAIL_START + memcpy(NULL, buffer, 0); + CHK_FAIL_END + + puts(buffer); +#endif + return ret; +} diff --git a/tests/test_memmove_null_dst.c b/tests/test_memmove_null_dst.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { +#ifndef __GNUC__ + char buffer[12] = {0}; + + CHK_FAIL_START + memmove(buffer, NULL, 0); + CHK_FAIL_END + + puts(buffer); +#endif + return ret; +} diff --git a/tests/test_memmove_null_src.c b/tests/test_memmove_null_src.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { +#ifndef __GNUC__ + char buffer[12] = {0}; + + CHK_FAIL_START + memmove(NULL, buffer, 0); + CHK_FAIL_END + + puts(buffer); +#endif + return ret; +} diff --git a/tests/test_memset_null.c b/tests/test_memset_null.c @@ -0,0 +1,13 @@ +#include "common.h" + +#include <string.h> + +int main(int argc, char** argv) { +#ifndef __GNUC__ + CHK_FAIL_START + memset(NULL, 0, 0); + CHK_FAIL_END +#endif + + return ret; +}