[PATCH] ssp: add support for _FORTIFY_SOURCE=3

Christian Franke <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
_FORTIFY_SOURCE=3 is already supported by glibc and MinGW-w64 headers.

Tested on Cygwin with current gcc 13.2.1 test release.

-- 
Regards,
Christian
0001-ssp-add-support-for-_FORTIFY_SOURCE-3.patch (text/plain, 4.6 KB)
From 95bd8aadf02ee95bbc9a05f37e88c78430027733 Mon Sep 17 00:00:00 2001
From: Christian Franke <[email protected]>
Date: Fri, 26 Jan 2024 17:20:37 +0100
Subject: [PATCH] ssp: add support for _FORTIFY_SOURCE=3

If specified, use __builtin_dynamic_object_size() instead of
__builtin_object_size() if supported (GCC 12.0 or later).
This enables buffer overflow checks if the buffer size is non-const
but known during runtime.
Use new macro __ssp_bos_known() instead of the (bos(p) != (size_t)-1)
checks.  The latter is no longer a compile time constant in all cases.
This avoids the generation of unused code.

Signed-off-by: Christian Franke <[email protected]>
---
 newlib/libc/include/ssp/ssp.h      | 11 ++++++++++-
 newlib/libc/include/ssp/string.h   |  4 ++--
 newlib/libc/include/ssp/strings.h  |  4 ++--
 newlib/libc/include/sys/features.h | 12 +++++++++---
 4 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/newlib/libc/include/ssp/ssp.h b/newlib/libc/include/ssp/ssp.h
index 922908659..49ea5f2dd 100644
--- a/newlib/libc/include/ssp/ssp.h
+++ b/newlib/libc/include/ssp/ssp.h
@@ -43,11 +43,20 @@
 
 #define __ssp_inline extern __inline__ __attribute__((__always_inline__, __gnu_inline__))
 
+#if __SSP_FORTIFY_LEVEL > 2
+#define __ssp_bos(ptr) __builtin_dynamic_object_size(ptr, 1)
+#define __ssp_bos0(ptr) __builtin_dynamic_object_size(ptr, 0)
+#define __ssp_bos_known(ptr) \
+       (__builtin_object_size(ptr, 0) != (size_t)-1 \
+       || !__builtin_constant_p(__ssp_bos(ptr)))
+#else
 #define __ssp_bos(ptr) __builtin_object_size(ptr, __SSP_FORTIFY_LEVEL > 1)
 #define __ssp_bos0(ptr) __builtin_object_size(ptr, 0)
+#define __ssp_bos_known(ptr) (__ssp_bos0(ptr) != (size_t)-1)
+#endif
 
 #define __ssp_check(buf, len, bos) \
-	if (bos(buf) != (size_t)-1 && len > bos(buf)) \
+	if (__ssp_bos_known(buf) && len > bos(buf)) \
 		__chk_fail()
 #define __ssp_decl(rtype, fun, args) \
 rtype __ssp_real_(fun) args __asm__(__ASMNAME(#fun)); \
diff --git a/newlib/libc/include/ssp/string.h b/newlib/libc/include/ssp/string.h
index 85c4512ac..22b52097c 100644
--- a/newlib/libc/include/ssp/string.h
+++ b/newlib/libc/include/ssp/string.h
@@ -49,12 +49,12 @@ __END_DECLS
 #if __SSP_FORTIFY_LEVEL > 0
 
 #define __ssp_bos_check3(fun, dst, src, len) \
-    ((__ssp_bos0(dst) != (size_t)-1) ? \
+    (__ssp_bos_known(dst) ? \
     __builtin___ ## fun ## _chk(dst, src, len, __ssp_bos0(dst)) : \
     __ ## fun ## _ichk(dst, src, len))
 
 #define __ssp_bos_check2(fun, dst, src) \
-    ((__ssp_bos0(dst) != (size_t)-1) ? \
+    (__ssp_bos_known(dst) ? \
     __builtin___ ## fun ## _chk(dst, src, __ssp_bos0(dst)) : \
     __ ## fun ## _ichk(dst, src))
 
diff --git a/newlib/libc/include/ssp/strings.h b/newlib/libc/include/ssp/strings.h
index 13adba175..be59882eb 100644
--- a/newlib/libc/include/ssp/strings.h
+++ b/newlib/libc/include/ssp/strings.h
@@ -37,11 +37,11 @@
 
 #if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
 #define bcopy(src, dst, len) \
-    ((__ssp_bos0(dst) != (size_t)-1) ? \
+    (__ssp_bos_known(dst) ? \
     __builtin___memmove_chk(dst, src, len, __ssp_bos0(dst)) : \
     __memmove_ichk(dst, src, len))
 #define bzero(dst, len) \
-    ((__ssp_bos0(dst) != (size_t)-1) ? \
+    (__ssp_bos_known(dst) ? \
     __builtin___memset_chk(dst, 0, len, __ssp_bos0(dst)) : \
     __memset_ichk(dst, 0, len))
 #endif
diff --git a/newlib/libc/include/sys/features.h b/newlib/libc/include/sys/features.h
index a7d4bc52d..6a925c87e 100644
--- a/newlib/libc/include/sys/features.h
+++ b/newlib/libc/include/sys/features.h
@@ -104,7 +104,7 @@ extern "C" {
  * _DEFAULT_SOURCE (or none of the above)
  * 	POSIX-1.2008 with BSD and SVr4 extensions
  *
- * _FORTIFY_SOURCE = 1 or 2
+ * _FORTIFY_SOURCE = 1, 2 or 3
  * 	Object Size Checking function wrappers
  */
 
@@ -247,7 +247,7 @@ extern "C" {
  * 	GNU extensions; enabled with _GNU_SOURCE.
  *
  * __SSP_FORTIFY_LEVEL
- * 	Object Size Checking; defined to 0 (off), 1, or 2.
+ * 	Object Size Checking; defined to 0 (off), 1, 2 or 3.
  *
  * In all cases above, "enabled by default" means either by defining
  * _DEFAULT_SOURCE, or by not defining any of the public feature test macros.
@@ -335,7 +335,13 @@ extern "C" {
 #if _FORTIFY_SOURCE > 0 && !defined(__cplusplus) && !defined(__lint__) && \
    (__OPTIMIZE__ > 0 || defined(__clang__)) && __GNUC_PREREQ__(4, 1) && \
    !defined(_LIBC)
-#  if _FORTIFY_SOURCE > 1
+#  if _FORTIFY_SOURCE > 2 && defined(__has_builtin)
+#    if __has_builtin(__builtin_dynamic_object_size)
+#      define __SSP_FORTIFY_LEVEL 3
+#    else
+#      define __SSP_FORTIFY_LEVEL 2
+#    endif
+#  elif _FORTIFY_SOURCE > 1
 #    define __SSP_FORTIFY_LEVEL 2
 #  else
 #    define __SSP_FORTIFY_LEVEL 1
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.