00c0d4
commit c43c5796121bc5bcc0867f02e5536874aa8196c1
00c0d4
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
00c0d4
Date:   Wed Dec 30 11:54:00 2020 +0530
00c0d4
00c0d4
    Introduce _FORTIFY_SOURCE=3
00c0d4
    
00c0d4
    Introduce a new _FORTIFY_SOURCE level of 3 to enable additional
00c0d4
    fortifications that may have a noticeable performance impact, allowing
00c0d4
    more fortification coverage at the cost of some performance.
00c0d4
    
00c0d4
    With llvm 9.0 or later, this will replace the use of
00c0d4
    __builtin_object_size with __builtin_dynamic_object_size.
00c0d4
    
00c0d4
    __builtin_dynamic_object_size
00c0d4
    -----------------------------
00c0d4
    
00c0d4
    __builtin_dynamic_object_size is an LLVM builtin that is similar to
00c0d4
    __builtin_object_size.  In addition to what __builtin_object_size
00c0d4
    does, i.e. replace the builtin call with a constant object size,
00c0d4
    __builtin_dynamic_object_size will replace the call site with an
00c0d4
    expression that evaluates to the object size, thus expanding its
00c0d4
    applicability.  In practice, __builtin_dynamic_object_size evaluates
00c0d4
    these expressions through malloc/calloc calls that it can associate
00c0d4
    with the object being evaluated.
00c0d4
    
00c0d4
    A simple motivating example is below; -D_FORTIFY_SOURCE=2 would miss
00c0d4
    this and emit memcpy, but -D_FORTIFY_SOURCE=3 with the help of
00c0d4
    __builtin_dynamic_object_size is able to emit __memcpy_chk with the
00c0d4
    allocation size expression passed into the function:
00c0d4
    
00c0d4
    void *copy_obj (const void *src, size_t alloc, size_t copysize)
00c0d4
    {
00c0d4
      void *obj = malloc (alloc);
00c0d4
      memcpy (obj, src, copysize);
00c0d4
      return obj;
00c0d4
    }
00c0d4
    
00c0d4
    Limitations
00c0d4
    -----------
00c0d4
    
00c0d4
    If the object was allocated elsewhere that the compiler cannot see, or
00c0d4
    if it was allocated in the function with a function that the compiler
00c0d4
    does not recognize as an allocator then __builtin_dynamic_object_size
00c0d4
    also returns -1.
00c0d4
    
00c0d4
    Further, the expression used to compute object size may be non-trivial
00c0d4
    and may potentially incur a noticeable performance impact.  These
00c0d4
    fortifications are hence enabled at a new _FORTIFY_SOURCE level to
00c0d4
    allow developers to make a choice on the tradeoff according to their
00c0d4
    environment.
00c0d4
00c0d4
diff --git a/include/features.h b/include/features.h
00c0d4
index ea7673ee115bcf0a..fe9fe16d034fad1b 100644
00c0d4
--- a/include/features.h
00c0d4
+++ b/include/features.h
00c0d4
@@ -381,6 +381,11 @@
00c0d4
 #  warning _FORTIFY_SOURCE requires compiling with optimization (-O)
00c0d4
 # elif !__GNUC_PREREQ (4, 1)
00c0d4
 #  warning _FORTIFY_SOURCE requires GCC 4.1 or later
00c0d4
+# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0)
00c0d4
+#  if _FORTIFY_SOURCE > 3
00c0d4
+#   warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform
00c0d4
+#  endif
00c0d4
+#  define __USE_FORTIFY_LEVEL 3
00c0d4
 # elif _FORTIFY_SOURCE > 1
00c0d4
 #  if _FORTIFY_SOURCE > 2
00c0d4
 #   warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform
00c0d4
diff --git a/manual/creature.texi b/manual/creature.texi
00c0d4
index 8876b2ab779c988f..64f361f27a7d6cdf 100644
00c0d4
--- a/manual/creature.texi
00c0d4
+++ b/manual/creature.texi
00c0d4
@@ -247,7 +247,8 @@ included.
00c0d4
 @standards{GNU, (none)}
00c0d4
 If this macro is defined to @math{1}, security hardening is added to
00c0d4
 various library functions.  If defined to @math{2}, even stricter
00c0d4
-checks are applied.
00c0d4
+checks are applied. If defined to @math{3}, @theglibc{} may also use
00c0d4
+checks that may have an additional performance overhead.
00c0d4
 @end defvr
00c0d4
 
00c0d4
 @defvr Macro _REENTRANT
00c0d4
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
00c0d4
index 3f6fe3cc8563b493..1e39307b0ebcf38f 100644
00c0d4
--- a/misc/sys/cdefs.h
00c0d4
+++ b/misc/sys/cdefs.h
00c0d4
@@ -123,6 +123,15 @@
00c0d4
 #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
00c0d4
 #define __bos0(ptr) __builtin_object_size (ptr, 0)
00c0d4
 
00c0d4
+/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available.  */
00c0d4
+#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
00c0d4
+# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
00c0d4
+# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
00c0d4
+#else
00c0d4
+# define __glibc_objsize0(__o) __bos0 (__o)
00c0d4
+# define __glibc_objsize(__o) __bos (__o)
00c0d4
+#endif
00c0d4
+
00c0d4
 #if __GNUC_PREREQ (4,3)
00c0d4
 # define __warndecl(name, msg) \
00c0d4
   extern void name (void) __attribute__((__warning__ (msg)))