aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/include/any-macos-any/secure
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2025-09-17 15:35:48 +0200
committerGitHub <noreply@github.com>2025-09-17 15:35:48 +0200
commitae00a2a84d34417c1fb6229db5919abcdced0ea0 (patch)
tree4ad139042d72adb805b81df3026ec561b3f943c0 /lib/libc/include/any-macos-any/secure
parent8e8a143d62b6176d94289a2a1e52295b46dfd319 (diff)
parent93218eacaada52eb028e5569b48b47ac38b1df70 (diff)
downloadzig-ae00a2a84d34417c1fb6229db5919abcdced0ea0.tar.gz
zig-ae00a2a84d34417c1fb6229db5919abcdced0ea0.zip
Merge pull request #25257 from linusg/bump-macos-headers
libc: Update macOS headers to SDK 26.0
Diffstat (limited to 'lib/libc/include/any-macos-any/secure')
-rw-r--r--lib/libc/include/any-macos-any/secure/_common.h2
-rw-r--r--lib/libc/include/any-macos-any/secure/_stdio.h103
-rw-r--r--lib/libc/include/any-macos-any/secure/_string.h295
-rw-r--r--lib/libc/include/any-macos-any/secure/_strings.h49
4 files changed, 337 insertions, 112 deletions
diff --git a/lib/libc/include/any-macos-any/secure/_common.h b/lib/libc/include/any-macos-any/secure/_common.h
index 03181dd30c..6a7a508b28 100644
--- a/lib/libc/include/any-macos-any/secure/_common.h
+++ b/lib/libc/include/any-macos-any/secure/_common.h
@@ -39,5 +39,7 @@
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)
+#define __darwin_pass_obsz0 __attribute__((__pass_object_size__(0)))
+#define __darwin_pass_obsz __attribute__((__pass_object_size__(_USE_FORTIFY_LEVEL > 1 ? 1 : 0)))
#endif
diff --git a/lib/libc/include/any-macos-any/secure/_stdio.h b/lib/libc/include/any-macos-any/secure/_stdio.h
index 9046dac920..cc678f318a 100644
--- a/lib/libc/include/any-macos-any/secure/_stdio.h
+++ b/lib/libc/include/any-macos-any/secure/_stdio.h
@@ -35,54 +35,95 @@ _LIBC_SINGLE_BY_DEFAULT()
#if _USE_FORTIFY_LEVEL > 0
-#ifndef __has_builtin
-#define _undef__has_builtin
-#define __has_builtin(x) 0
-#endif
+extern int __snprintf_chk (char * __restrict _LIBC_COUNT(__maxlen), size_t __maxlen, int, size_t,
+ const char * __restrict, ...);
+extern int __vsnprintf_chk (char * __restrict _LIBC_COUNT(__maxlen), size_t __maxlen, int, size_t,
+ const char * __restrict, va_list);
-/* sprintf, vsprintf, snprintf, vsnprintf */
-#if __has_builtin(__builtin___sprintf_chk) || defined(__GNUC__)
extern int __sprintf_chk (char * __restrict _LIBC_UNSAFE_INDEXABLE, int, size_t,
const char * __restrict, ...);
+extern int __vsprintf_chk (char * __restrict _LIBC_UNSAFE_INDEXABLE, int, size_t,
+ const char * __restrict, va_list);
-#undef sprintf
-#define sprintf(str, ...) \
- __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
+#ifdef __LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES
+
+/* verify that there are at least __n characters at __str */
+static inline char *_LIBC_COUNT(__n)
+__libc_ptrchk_strbuf_chk(char *_LIBC_COUNT(__n) __str, size_t __n) { return __str; }
+
+#undef __sprintf_chk_func /* sprintf is unavailable */
+#undef __vsprintf_chk_func /* vsprintf is unavailable */
+
+#define __vsnprintf_chk_func(str, len, flag, format, ap) ({ \
+ size_t __len = (len); \
+ __builtin___vsnprintf_chk (__libc_ptrchk_strbuf_chk(str, __len), __len, flag, __darwin_obsz(str), format, ap); \
+})
+
+#define __snprintf_chk_func(str, len, flag, ...) ({ \
+ size_t __len = (len); \
+ __builtin___snprintf_chk (__libc_ptrchk_strbuf_chk(str, __len), __len, flag, __darwin_obsz(str), __VA_ARGS__); \
+})
+
+#else
+
+#ifndef __has_builtin
+#define __undef__has_builtin
+#define __has_builtin(x) defined(__GNUC__)
#endif
-#if __DARWIN_C_LEVEL >= 200112L
-#if __has_builtin(__builtin___snprintf_chk) || defined(__GNUC__)
-extern int __snprintf_chk (char * __restrict _LIBC_COUNT(__maxlen), size_t __maxlen, int, size_t,
- const char * __restrict, ...);
+#if __has_builtin(__builtin___snprintf_chk)
+#define __snprintf_chk_func(str, len, flag, ...) \
+ __builtin___snprintf_chk (str, len, flag, __darwin_obsz(str), __VA_ARGS__)
+#endif
-#undef snprintf
-#define snprintf(str, len, ...) \
- __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
+#if __has_builtin(__builtin___vsnprintf_chk)
+#define __vsnprintf_chk_func(str, len, flag, format, ap) \
+ __builtin___vsnprintf_chk (str, len, flag, __darwin_obsz(str), format, ap)
#endif
-#if __has_builtin(__builtin___vsprintf_chk) || defined(__GNUC__)
-extern int __vsprintf_chk (char * __restrict _LIBC_UNSAFE_INDEXABLE, int, size_t,
- const char * __restrict, va_list);
+#if __has_builtin(__builtin___sprintf_chk)
+#define __sprintf_chk_func(str, flag, ...) \
+ __builtin___sprintf_chk (str, flag, __darwin_obsz(str), __VA_ARGS__)
+#endif
+
+#if __has_builtin(__builtin___vsprintf_chk)
+#define __vsprintf_chk_func(str, flag, format, ap) \
+ __builtin___vsprintf_chk (str, flag, __darwin_obsz(str), format, ap)
+#endif
+
+
+#ifdef __undef__has_builtin
+#undef __undef__has_builtin
+#undef __has_builtin
+#endif
+
+#endif
+
+/* sprintf, vsprintf, snprintf, vsnprintf */
+
+#ifdef __sprintf_chk_func
+#undef sprintf
+#define sprintf(str, ...) __sprintf_chk_func (str, 0, __VA_ARGS__)
+#endif
+
+#if __DARWIN_C_LEVEL >= 200112L
+
+#ifdef __vsprintf_chk_func
#undef vsprintf
-#define vsprintf(str, format, ap) \
- __builtin___vsprintf_chk (str, 0, __darwin_obsz(str), format, ap)
+#define vsprintf(str, ...) __vsprintf_chk_func (str, 0, __VA_ARGS__)
#endif
-#if __has_builtin(__builtin___vsnprintf_chk) || defined(__GNUC__)
-extern int __vsnprintf_chk (char * __restrict _LIBC_COUNT(__maxlen), size_t __maxlen, int, size_t,
- const char * __restrict, va_list);
+#ifdef __snprintf_chk_func
+#undef snprintf
+#define snprintf(str, len, ...) __snprintf_chk_func (str, len, 0, __VA_ARGS__)
+#endif
+#ifdef __vsnprintf_chk_func
#undef vsnprintf
-#define vsnprintf(str, len, format, ap) \
- __builtin___vsnprintf_chk (str, len, 0, __darwin_obsz(str), format, ap)
+#define vsnprintf(str, len, ...) __vsnprintf_chk_func (str, len, 0, __VA_ARGS__)
#endif
-#endif /* __DARWIN_C_LEVEL >= 200112L */
-
-#ifdef _undef__has_builtin
-#undef _undef__has_builtin
-#undef __has_builtin
#endif
#endif /* _USE_FORTIFY_LEVEL > 0 */
diff --git a/lib/libc/include/any-macos-any/secure/_string.h b/lib/libc/include/any-macos-any/secure/_string.h
index f023af32a1..d16ecd165c 100644
--- a/lib/libc/include/any-macos-any/secure/_string.h
+++ b/lib/libc/include/any-macos-any/secure/_string.h
@@ -34,117 +34,262 @@
#if _USE_FORTIFY_LEVEL > 0
-/* <rdar://problem/12622659> */
-#if defined(__clang__) && \
- ((defined(__apple_build_version__) && __apple_build_version__ >= 4260006) || \
- (!defined(__apple_build_version__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 3))))
-#define __HAS_FIXED_CHK_PROTOTYPES 1
-#else
-#define __HAS_FIXED_CHK_PROTOTYPES 0
+#ifdef __LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES
+
+#if __has_builtin(__builtin___memcpy_chk)
+static inline void *_LIBC_SIZE(__n)
+__memcpy_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, const void *_LIBC_SIZE(__n) __src, size_t __n) {
+ return _LIBC_FORGE_PTR(__builtin___memcpy_chk(__dst, __src, __n, __darwin_obsz0(__dst)), __n);
+}
+#define __memcpy_chk_func __memcpy_ptrchk
#endif
-/* memccpy, memcpy, mempcpy, memmove, memset, strcpy, strlcpy, stpcpy,
- strncpy, stpncpy, strcat, strlcat, and strncat */
+#if __has_builtin(__builtin___memmove_chk)
+static inline void *_LIBC_SIZE(__n)
+__memmove_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, const void *_LIBC_SIZE(__n) __src, size_t __n) {
+ return _LIBC_FORGE_PTR(__builtin___memmove_chk(__dst, __src, __n, __darwin_obsz0(__dst)), __n);
+}
+#define __memmove_chk_func __memmove_ptrchk
+#endif
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 || \
- defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
-#if __has_builtin(__builtin___memccpy_chk) && __HAS_FIXED_CHK_PROTOTYPES
-#undef memccpy
-/* void *memccpy(void *dst, const void *src, int c, size_t n) */
-#define memccpy(dest, ...) \
- __builtin___memccpy_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
+#if __has_builtin(__builtin___memset_chk)
+static inline void *_LIBC_SIZE(__n)
+__memset_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, int __c, size_t __n) {
+ return _LIBC_FORGE_PTR(__builtin___memset_chk(__dst, __c, __n, __darwin_obsz0(__dst)), __n);
+}
+#define __memset_chk_func __memset_ptrchk
#endif
+
+#undef __stpncpy_chk_func /* stpncpy unavailable */
+#undef __strncpy_chk_func /* strncpy unavailable */
+
+#if __has_builtin(__builtin___strlcpy_chk)
+static inline size_t
+__strlcpy_ptrchk(char *const _LIBC_SIZE(__n) __darwin_pass_obsz __dst, const char *__src, size_t __n) {
+ return __builtin___strlcpy_chk(__dst, __src, __n, __darwin_obsz(__dst));
+}
+#define __strlcpy_chk_func __strlcpy_ptrchk
#endif
-#if __has_builtin(__builtin___memcpy_chk) || defined(__GNUC__)
-#undef memcpy
-/* void *memcpy(void *dst, const void *src, size_t n) */
-#define memcpy(dest, ...) \
+#if __has_builtin(__builtin___strlcat_chk)
+static inline size_t
+__strlcat_ptrchk(char *const _LIBC_SIZE(__n) __darwin_pass_obsz __dst, const char *__src, size_t __n) {
+ return __builtin___strlcat_chk(__dst, __src, __n, __darwin_obsz(__dst));
+}
+#define __strlcat_chk_func __strlcat_ptrchk
+#endif
+
+#if __has_builtin(__builtin___memccpy_chk)
+static inline void *_LIBC_SIZE(__n)
+__memccpy_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, const void *_LIBC_SIZE(__n) __src, int __c, size_t __n) {
+ return _LIBC_FORGE_PTR(__builtin___memccpy_chk(__dst, __src, __c, __n, __darwin_obsz0(__dst)), __n);
+}
+#define __memccpy_chk_func __memccpy_ptrchk
+#endif
+
+#undef __strcpy_chk_func /* strcpy unavailable */
+#undef __stpcpy_chk_func /* stpcpy unavailable */
+#undef __strcat_chk_func /* strcat unavailable */
+#undef __strncat_chk_func /* strncat unavailable */
+
+#else /* __LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES */
+
+#define __is_modern_darwin(ios, macos) \
+ (__IPHONE_OS_VERSION_MIN_REQUIRED >= (ios) || \
+ __MAC_OS_X_VERSION_MIN_REQUIRED >= (macos) || \
+ defined(__DRIVERKIT_VERSION_MIN_REQUIRED))
+
+/* __is_gcc(gcc_major, gcc_minor)
+ * Special values:
+ * 10.0 means "test should always fail when __has_builtin isn't supported"
+ (because gcc got __has_builtin in version 10.0); this is used for builtins
+ that gcc did not support yet at the time __has_builtin was introduced, so
+ there is no point checking the compiler version.
+ * 0.0 means that we did not research when gcc started supporting this builtin,
+ but it's believed to have been the case at least since gcc 4.0, which came
+ out in 2005. (Hello from 2025! What year is it now? Can't believe we're still
+ using C!)
+ */
+#define __is_gcc(major, minor) \
+ (__GNUC__ > (gcc_major) || \
+ (__GNUC__ == (gcc_major) && __GNUC_MINOR__ >= (gcc_minor)))
+
+#ifdef __has_builtin
+#define __supports_builtin(builtin, gcc_major, gcc_minor) \
+ __has_builtin(builtin)
+#else
+#define __supports_builtin(builtin, gcc_major, gcc_minor) __is_gcc(gcc_major, gcc_minor)
+#endif
+
+
+#if __supports_builtin(__builtin___memcpy_chk, 0, 0)
+#define __memcpy_chk_func(dest, ...) \
__builtin___memcpy_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
#endif
-#if __has_builtin(__builtin___memmove_chk) || defined(__GNUC__)
-#undef memmove
-/* void *memmove(void *dst, const void *src, size_t len) */
-#define memmove(dest, ...) \
+#if __supports_builtin(__builtin___memmove_chk, 0, 0)
+#define __memmove_chk_func(dest, ...) \
__builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
#endif
-#if __has_builtin(__builtin___memset_chk) || defined(__GNUC__)
-#undef memset
-/* void *memset(void *b, int c, size_t len) */
-#define memset(dest, ...) \
+#if __supports_builtin(__builtin___memset_chk, 0, 0)
+#define __memset_chk_func(dest, ...) \
__builtin___memset_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
#endif
-#if __has_builtin(__builtin___strcpy_chk) || defined(__GNUC__)
-#undef strcpy
-/* char *strcpy(char *dst, const char *src) */
-#define strcpy(dest, ...) \
- __builtin___strcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
+#if __supports_builtin(__builtin___stpncpy_chk, 4, 7)
+#define __stpncpy_chk_func(dest, ...) \
+ __builtin___stpncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
-#if __DARWIN_C_LEVEL >= 200809L
-#if __has_builtin(__builtin___stpcpy_chk) || defined(__GNUC__)
-#undef stpcpy
-/* char *stpcpy(char *dst, const char *src) */
-#define stpcpy(dest, ...) \
- __builtin___stpcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
+#if __supports_builtin(__builtin___strncpy_chk, 0, 0)
+#define __strncpy_chk_func(dest, ...) \
+ __builtin___strncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
-#endif /* __DARWIN_C_LEVEL >= 200809L */
-#if __DARWIN_C_LEVEL >= 200809L
-#if __has_builtin(__builtin___stpncpy_chk) || __APPLE_CC__ >= 5666 || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
-#undef stpncpy
-/* char *stpncpy(char *dst, const char *src, size_t n) */
-#define stpncpy(dest, ...) \
- __builtin___stpncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
-#endif
-#endif /* _DARWIN_C_LEVEL >= 200809L */
+#if __is_modern_darwin(70000, 1090)
-#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 || \
- defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
-#if __has_builtin(__builtin___strlcpy_chk) && __HAS_FIXED_CHK_PROTOTYPES
-#undef strlcpy
-/* size_t strlcpy(char *dst, const char *source, size_t size) */
-#define strlcpy(dest, ...) \
+#if __supports_builtin(__builtin___strlcpy_chk, 0, 0)
+#define __strlcpy_chk_func(dest, ...) \
__builtin___strlcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
-#if __has_builtin(__builtin___strlcat_chk) && __HAS_FIXED_CHK_PROTOTYPES
-#undef strlcat
-/* size_t strlcat(char *dst, const char *source, size_t size) */
-#define strlcat(dest, ...) \
+#if __supports_builtin(__builtin___strlcat_chk, 0, 0)
+#define __strlcat_chk_func(dest, ...) \
__builtin___strlcat_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
-#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 */
-#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
-#if __has_builtin(__builtin___strncpy_chk) || defined(__GNUC__)
-#undef strncpy
-/* char *strncpy(char *dst, const char *src, size_t n) */
-#define strncpy(dest, ...) \
- __builtin___strncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
+#if __supports_builtin(__builtin___memccpy_chk, 10, 0)
+#define __memccpy_chk_func(dest, ...) \
+ __builtin___memccpy_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
#endif
-#if __has_builtin(__builtin___strcat_chk) || defined(__GNUC__)
-#undef strcat
-/* char *strcat(char *s1, const char *s2) */
-#define strcat(dest, ...) \
+#endif /* __is_modern_darwin(70000, 1090) */
+
+
+#if __supports_builtin(__builtin___strcpy_chk, 0, 0)
+#define __strcpy_chk_func(dest, ...) \
+ __builtin___strcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
+#endif
+
+#if __supports_builtin(__builtin___stpcpy_chk, 0, 0)
+#define __stpcpy_chk_func(dest, ...) \
+ __builtin___stpcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
+#endif
+
+#if __supports_builtin(__builtin___strcat_chk, 0, 0)
+#define __strcat_chk_func(dest, ...) \
__builtin___strcat_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000)
-#if __has_builtin(__builtin___strncat_chk) || defined(__GNUC__)
-#undef strncat
-/* char *strncat(char *s1, const char *s2, size_t n) */
-#define strncat(dest, ...) \
+#if __supports_builtin(__builtin___strncat_chk, 0, 0)
+#define __strncat_chk_func(dest, ...) \
__builtin___strncat_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
#endif
-#undef __HAS_FIXED_CHK_PROTOTYPES
+
+#undef __supports_builtin
+#undef __is_gcc
+
+#endif /* defined(__has_ptrcheck) && __has_ptrcheck */
+
+#undef __is_modern_darwin
+
+/* memccpy, memcpy, mempcpy, memmove, memset, strcpy, strlcpy, stpcpy,
+ strncpy, stpncpy, strcat, strlcat, and strncat */
+
+/* The use of .../__VA_ARGS__ is load-bearing. If the macros take fixed
+ * arguments, they are unable to themselves accept macros that expand to
+ * multiple arguments, like this:
+ * #define memcpy(a, b, c) ...
+ * #define FOO(data) get_bytes(data), get_length(data)
+ * memcpy(bar, FOO(d));
+ * This will fail because the preprocessor only sees two arguments on the first
+ * expansion of memcpy, when 3 are required.
+ * This is also required to support syntaxes that embed commas. The preprocessor
+ * recognizes parentheses for the isolation of arguments but not brackets. This
+ * expands to 3 arguments:
+ * strcpy(destination, [NSString stringWithFormat:@"%i", 4].UTF8String);
+ * ^ ^ ^
+ * |destination | |
+ * |[NSString stringWithFormat:@"%i" |
+ * |4].UTF8String
+ * This expands to 4 arguments:
+ * memcpy(destination, (uint8_t[]) { 1, 2 }, 2);
+ * ^ ^ ^ ^
+ * To work correctly under these hostile circumstances, chk_func macros
+ * need to expand to a bare identifier (like #define memcpy_chk_func __memcpy)
+ * or to a macro that also takes variadic arguments.
+ */
+
+#ifdef __memccpy_chk_func
+#undef memccpy
+#define memccpy(...) __memccpy_chk_func (__VA_ARGS__)
+#endif
+
+#ifdef __memcpy_chk_func
+#undef memcpy
+#define memcpy(...) __memcpy_chk_func (__VA_ARGS__)
+#endif
+
+#ifdef __memmove_chk_func
+#undef memmove
+#define memmove(...) __memmove_chk_func (__VA_ARGS__)
+#endif
+
+#ifdef __memset_chk_func
+#undef memset
+#define memset(...) __memset_chk_func (__VA_ARGS__)
+#endif
+
+#if defined(__strcpy_chk_func)
+#undef strcpy
+#define strcpy(...) __strcpy_chk_func (__VA_ARGS__)
+#endif
+
+#if defined(__strcat_chk_func)
+#undef strcat
+#define strcat(...) __strcat_chk_func (__VA_ARGS__)
+#endif
+
+#if defined(__strncpy_chk_func)
+#undef strncpy
+#define strncpy(...) __strncpy_chk_func (__VA_ARGS__)
+#endif
+
+#if defined(__strncat_chk_func)
+#undef strncat
+#define strncat(...) __strncat_chk_func (__VA_ARGS__)
+#endif
+
+#if __DARWIN_C_LEVEL >= 200809L
+
+#if defined(__stpcpy_chk_func)
+#undef stpcpy
+#define stpcpy(...) __stpcpy_chk_func (__VA_ARGS__)
+#endif
+
+#if defined(__stpncpy_chk_func)
+#undef stpncpy
+#define stpncpy(...) __stpncpy_chk_func (__VA_ARGS__)
+#endif
+
+#endif /* __DARWIN_C_LEVEL >= 200809L */
+
+#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
+#if defined(__strlcpy_chk_func)
+#undef strlcpy
+#define strlcpy(...) __strlcpy_chk_func (__VA_ARGS__)
+#endif
+
+#if defined(__strlcat_chk_func)
+#undef strlcat
+#define strlcat(...) __strlcat_chk_func (__VA_ARGS__)
+#endif
+#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
#endif /* _USE_FORTIFY_LEVEL > 0 */
+
#endif /* _SECURE__STRING_H_ */
diff --git a/lib/libc/include/any-macos-any/secure/_strings.h b/lib/libc/include/any-macos-any/secure/_strings.h
index 384c5068a6..a841395dda 100644
--- a/lib/libc/include/any-macos-any/secure/_strings.h
+++ b/lib/libc/include/any-macos-any/secure/_strings.h
@@ -39,18 +39,55 @@
/* Removed in Issue 7 */
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L
-#if __has_builtin(__builtin___memmove_chk) || defined(__GNUC__)
+#ifdef __LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES
+
+static inline void
+__bcopy_ptrcheck(const void *_LIBC_SIZE(__n) __src, void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, size_t __n) {
+ memmove(__dst, __src, __n);
+}
+
+static inline void
+__bzero_ptrcheck(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, size_t __n) {
+ memset(__dst, 0, __n);
+}
+
+#define __bcopy_chk_func __bcopy_ptrcheck
+#define __bzero_chk_func __bzero_ptrcheck
+
+#else
+
+#ifndef __has_builtin
+#define __undef__has_builtin
+#define __has_builtin(x) defined(__GNUC__)
+#endif
+
+#if __has_builtin(__builtin___memmove_chk)
+#define __bcopy_chk_func(src, dst, ...) \
+ __builtin___memmove_chk(dst, src, __VA_ARGS__, __darwin_obsz0 (dst))
+#endif
+
+#if __has_builtin(__builtin___memset_chk)
+#define __bzero_chk_func(dst, ...) \
+ __builtin___memset_chk(dst, 0, __VA_ARGS__, __darwin_obsz0 (dst))
+#endif
+
+#ifdef __undef__has_builtin
+#undef __undef__has_builtin
+#undef __has_builtin
+#endif
+
+#endif
+
+#ifdef __bcopy_chk_func
#undef bcopy
/* void bcopy(const void *src, void *dst, size_t len) */
-#define bcopy(src, dest, ...) \
- __builtin___memmove_chk (dest, src, __VA_ARGS__, __darwin_obsz0 (dest))
+#define bcopy(...) __bcopy_chk_func (__VA_ARGS__)
#endif
-#if __has_builtin(__builtin___memset_chk) || defined(__GNUC__)
+#ifdef __bzero_chk_func
#undef bzero
/* void bzero(void *s, size_t n) */
-#define bzero(dest, ...) \
- __builtin___memset_chk (dest, 0, __VA_ARGS__, __darwin_obsz0 (dest))
+#define bzero(...) __bzero_chk_func (__VA_ARGS__)
#endif
#endif