This is a standalone implementation of
fortify source
level 3, providing compile time security checks.
It is libc-agnostic and simply overlays the system headers by using the
#include_next
extension found in GCC, and
black magic
on Clang. It was initially intended to be used on
musl based
Linux distributions.
- It is portable, works on *BSD, Linux, Solaris and possibly others.
- It will only trap non-conformant programs. This means that fortify level 2 is treated in the same way as level 1.
- Avoids making function calls when undefined behaviour has already been
invoked. This is handled by using
__builtin_trap()
. - Support for out-of-bounds read interfaces, such as send(), write(), fwrite() etc.
- No ABI is enforced. All of the fortify check functions are inlined into the resulting binary.
- It has a comprehensive suite of tests, running both on Clang and on GCC for every commit, with significant coverage
- Defining
USE_NATIVE_CHK
will make use of compiler-provided builtin_chk
functions, which might be a bit better in term of diagnostics, but won't necessarily provide the same amount of security checks. - Defining
PEDANTIC_CHECKS
will enable pedantic checks, that while technically correct, might break some programs relying on widely accepted undefined-behaviours.
If you want to quickly test it, you can try something like the following:
cat > fgets.c <<EOF
#include <stdio.h>
int
main(void)
{
char buf[BUFSIZ];
fgets(buf, sizeof(buf) + 1, stdin);
return 0;
}
EOF
cc -I<path-to-fortify-include-dir> -D_FORTIFY_SOURCE=3 -O1 fgets.c
./a.out
At this point, the program will safely and loudly crash.
FD_CLR
FD_SET
asprintf
bcopy
bzero
calloc
confstr
fdopen
fgets
fgetws
fmemopen
fopen
fprintf
fread
fwrite
getcwd
getdomainname
getgroups
gethostname
getlogin_r
malloc
mbsnrtowcs
mbsrtowcs
mbstowcs
memchr
memcpy
memmove
mempcpy
memset
poll
popen
ppoll
pread
printf
pwrite
qsort
read
readlink
readlinkat
realloc
reallocarray
realpath
recv
recvfrom
select
send
sendto
snprintf
sprintf
stpcpy
stpncpy
strcat
strchr
strcpy
strlcat
strlcpy
strlen
strncat
strncpy
strrchr
tmpfile
ttyname_r
umask
vfprintf
vprintf
vasprintf
vsnprintf
vsprintf
wcrtomb
wcscat
wcscpy
wcsncat
wcsncpy
wcsnrtombs
wcsrtombs
wcstombs
wctomb
wmemcpy
wmemmove
wmemset
write