From c43c5796121bc5bcc0867f02e5536874aa8196c1 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 30 Dec 2020 11:54:00 +0530 Subject: Introduce _FORTIFY_SOURCE=3 Introduce a new _FORTIFY_SOURCE level of 3 to enable additional fortifications that may have a noticeable performance impact, allowing more fortification coverage at the cost of some performance. With llvm 9.0 or later, this will replace the use of __builtin_object_size with __builtin_dynamic_object_size. __builtin_dynamic_object_size ----------------------------- __builtin_dynamic_object_size is an LLVM builtin that is similar to __builtin_object_size. In addition to what __builtin_object_size does, i.e. replace the builtin call with a constant object size, __builtin_dynamic_object_size will replace the call site with an expression that evaluates to the object size, thus expanding its applicability. In practice, __builtin_dynamic_object_size evaluates these expressions through malloc/calloc calls that it can associate with the object being evaluated. A simple motivating example is below; -D_FORTIFY_SOURCE=2 would miss this and emit memcpy, but -D_FORTIFY_SOURCE=3 with the help of __builtin_dynamic_object_size is able to emit __memcpy_chk with the allocation size expression passed into the function: void *copy_obj (const void *src, size_t alloc, size_t copysize) { void *obj = malloc (alloc); memcpy (obj, src, copysize); return obj; } Limitations ----------- If the object was allocated elsewhere that the compiler cannot see, or if it was allocated in the function with a function that the compiler does not recognize as an allocator then __builtin_dynamic_object_size also returns -1. Further, the expression used to compute object size may be non-trivial and may potentially incur a noticeable performance impact. These fortifications are hence enabled at a new _FORTIFY_SOURCE level to allow developers to make a choice on the tradeoff according to their environment. --- NEWS | 6 ++++++ include/features.h | 5 +++++ manual/creature.texi | 3 ++- misc/sys/cdefs.h | 9 +++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 86e05fb023..8e02dbd0f7 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,12 @@ Major new features: The 32-bit RISC-V port requires at least Linux 5.4, GCC 7.1 and binutils 2.28. +* A new fortification level _FORTIFY_SOURCE=3 is available. At this level, + glibc may use additional checks that may have an additional performance + overhead. At present these checks are available only on LLVM 9 and later. + The latest GCC available at this time (10.2) does not support this level of + fortification. + Deprecated and removed features, and other changes affecting compatibility: * The mallinfo function is marked deprecated. Callers should call diff --git a/include/features.h b/include/features.h index 540230b90b..066eb0eecd 100644 --- a/include/features.h +++ b/include/features.h @@ -397,6 +397,11 @@ # warning _FORTIFY_SOURCE requires compiling with optimization (-O) # elif !__GNUC_PREREQ (4, 1) # warning _FORTIFY_SOURCE requires GCC 4.1 or later +# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0) +# if _FORTIFY_SOURCE > 3 +# warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform +# endif +# define __USE_FORTIFY_LEVEL 3 # elif _FORTIFY_SOURCE > 1 # if _FORTIFY_SOURCE > 2 # warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform diff --git a/manual/creature.texi b/manual/creature.texi index be5050468b..31208ccb2b 100644 --- a/manual/creature.texi +++ b/manual/creature.texi @@ -254,7 +254,8 @@ included. @standards{GNU, (none)} If this macro is defined to @math{1}, security hardening is added to various library functions. If defined to @math{2}, even stricter -checks are applied. +checks are applied. If defined to @math{3}, @theglibc{} may also use +checks that may have an additional performance overhead. @end defvr @defvr Macro _REENTRANT diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index a06f1cfd91..5fb6e309be 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -127,6 +127,15 @@ #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) #define __bos0(ptr) __builtin_object_size (ptr, 0) +/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ +#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0) +# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) +# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) +#else +# define __glibc_objsize0(__o) __bos0 (__o) +# define __glibc_objsize(__o) __bos (__o) +#endif + #if __GNUC_PREREQ (4,3) # define __warnattr(msg) __attribute__((__warning__ (msg))) # define __errordecl(name, msg) \ -- cgit 1.4.1