fortify-headers

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

commit fd4332dbcd5227fde96e7bc128418d834b5b910f
parent d2594298b89d0fb8989cae3ebc8900e77b6aa478
Author: jvoisin <julien.voisin@dustri.org>
Date:   Wed, 20 Sep 2023 18:05:27 +0200

Add tests for compile-time errors

Diffstat:
M.github/workflows/testsuite.yaml | 9++++++---
Minclude/fortify-headers.h | 6+++---
Minclude/string.h | 3++-
Mtests/Makefile | 34+++++++++++++++++++++-------------
4 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/.github/workflows/testsuite.yaml b/.github/workflows/testsuite.yaml @@ -35,7 +35,7 @@ jobs: run: make -C tests gcc - name: Running the testsuite shell: bash - run: make -C tests run | grep -zqv FAIL + run: make -C tests run clang: runs-on: ubuntu-latest @@ -64,6 +64,9 @@ jobs: - name: Build shell: bash run: make -C tests clang - - name: Running the testsuite + - name: Running the compile-time testsuite + shell: bash + run: make -C tests clang + - name: Running the run-time testsuite shell: bash - run: make -C tests run | grep -zqv FAIL + run: make -C tests run diff --git a/include/fortify-headers.h b/include/fortify-headers.h @@ -106,9 +106,9 @@ #define __diagnose_as_builtin(...) #endif -#if __has_attribute (__diagnose_if) -#define __warning_if(cond, msg) __attribute__ ((__diagnose_if (cond, msg, "warning"))) -#define __error_if(cond, msg) __attribute__ ((__diagnose_if (cond, msg, "error"))) +#if __has_attribute (diagnose_if) +#define __warning_if(cond, msg) __attribute__ ((diagnose_if (cond, msg, "warning"))) +#define __error_if(cond, msg) __attribute__ ((diagnose_if (cond, msg, "error"))) #else #define __warning_if(cond, msg) #define __error_if(cond, msg) diff --git a/include/string.h b/include/string.h @@ -43,6 +43,7 @@ __access(read_only, 2, 3) __diagnose_as_builtin(__builtin_memcpy, 1, 2, 3) _FORTIFY_FN(memcpy) void *memcpy(void * _FORTIFY_POS0 __od, const void * _FORTIFY_POS0 __os, size_t __n) +__error_if((__bos(__od, 0) < __n), "'memcpy' called with `n` bigger than the size of `d`.") { size_t __bd = __bos(__od, 0); size_t __bs = __bos(__os, 0); @@ -72,8 +73,8 @@ _FORTIFY_FN(memmove) void *memmove(void * _FORTIFY_POS0 __d, __access(write_only, 1, 3) __diagnose_as_builtin(__builtin_memset, 1, 2, 3) -__warning_if(__c != 0 && __n == 0, "'memset' will set `0` bytes; did you invert the arguments?") _FORTIFY_FN(memset) void *memset(void * _FORTIFY_POS0 __d, int __c, size_t __n) +__warning_if(__c != 0 && __n == 0, "'memset' will set `0` bytes; did you invert the arguments?") { size_t __b = __bos(__d, 0); diff --git a/tests/Makefile b/tests/Makefile @@ -1,6 +1,11 @@ CFLAGS=-I../include/ -D_FORTIFY_SOURCE=3 -static -O2 -TARGETS= \ +COMPTIME_TARGETS= \ + test_memcpy_overwrite_under \ + test_memcpy_static_write \ + + +RUNTIME_TARGETS= \ test_FD_CLR_SETSIZE \ test_FD_CLR_negative \ test_FD_SET_SETSIZE \ @@ -42,9 +47,7 @@ TARGETS= \ test_memcpy_dynamic_read \ test_memcpy_dynamic_write \ test_memcpy_overwrite_over \ - test_memcpy_overwrite_under \ test_memcpy_static_read \ - test_memcpy_static_write \ test_memmove_dynamic_read \ test_memmove_dynamic_write \ test_memmove_static_read \ @@ -124,37 +127,42 @@ TARGETS= \ .SILENT: gcc: CC=../x86_64-linux-musl-native/bin/gcc -gcc: $(TARGETS) +gcc: $(RUNTIME_TARGETS) clang: CC=clang -clang: GCOV=gcov clang: CFLAGS+=-I/usr/include/x86_64-linux-musl clang: CFLAGS+=-I../x86_64-linux-musl-native/include/ clang: CFLAGS+=-Ix86_64-linux-musl-native/include/ clang: CFLAGS+=-nostdinc -clang: $(TARGETS) - -all: gcc +clang: comptime $(RUNTIME_TARGETS) coverage: CFLAGS += -fprofile-arcs -ftest-coverage coverage: CC=../x86_64-linux-musl-native/bin/gcc coverage: GCOV=../x86_64-linux-musl-native/bin/gcov -coverage: $(TARGETS) run +coverage: $(RUNTIME_TARGETS) run $(GCOV) *.c lcov --capture --directory . --output-file coverage.info lcov --remove ./coverage.info "*/tests/*" --output-file cleaned-coverage.info genhtml cleaned-coverage.info --output-directory coverage -$(TARGETS): %: %.c +all: gcc + + +$(RUNTIME_TARGETS): %: %.c $(CC) $(CFLAGS) -o $@ $< -run: $(TARGETS) - $(foreach EXE, $(TARGETS), \ +run: $(RUNTIME_TARGETS) + $(foreach EXE, $(RUNTIME_TARGETS), \ timeout 1s ./$(EXE) 1234567890 2 3 4 5 6 7 8 9 0 >/dev/null && echo "$(EXE) OK" || echo "$(EXE) FAIL"; \ ) +comptime: # only works on clang, as gcc doesn't have the diagnose_if attribute + $(foreach EXE, $(COMPTIME_TARGETS), \ + ($(CC) $(CFLAGS) -o ./$(EXE) ./$(EXE).c 1>/dev/null 2>/dev/null && echo "$(EXE) FAIL" || echo "$(EXE) OK") || true ;\ + ) + clean: - $(foreach EXE, $(TARGETS), \ + $(foreach EXE, $(RUNTIME_TARGETS) $(COMPTIME_TARGETS), \ rm -f ./$(EXE) \ ) rm -rf ./*.gcno ./*.gcda ./*.gcov ./coverage.info ./coverage