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.
This commit is contained in:
Siddhesh Poyarekar 2020-12-30 11:54:00 +05:30
parent 2a08b6e833
commit c43c579612
4 changed files with 22 additions and 1 deletions

6
NEWS
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) \