I'm trying to find information on what is required for implementing fortified functions in GCC for libc.
From what I understand the __builtin__*_chk variants are for compile-time checks but if GCC can't determine buffer sizes he will replace the call with the __*_chk version if they exist.
Is the above assertion correct? If so where can I find documentation on what is required by GCC in libc to tie together a function to it's runtime __*_chk version when FORTIFY_SOURCE=1|2?
Thanks
Fortification is mostly implemented in Glibc via GCC's __builtin_constant_p
and __builtin_object_size
intrinsics. E.g. here's definition of memset
from /usr/include/string.h
:
__fortify_function void *
__NTH (memset (void *__dest, int __ch, size_t __len))
{
if (__builtin_constant_p (__len) && __len == 0
&& (!__builtin_constant_p (__ch) || __ch != 0))
{
__warn_memset_zero_len ();
return __dest;
}
return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
}
__builtin___memset_chk
is simply expanded by GCC to a call to memset_chk
(also defined in libc.so).
GCC knows about *_chk
functions but only uses this knowledge to perform optimizations (dead code removal, folding, etc.), not for verification.