aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/include/any-macos-any/secure/_string.h
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/_string.h
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/_string.h')
-rw-r--r--lib/libc/include/any-macos-any/secure/_string.h295
1 files changed, 220 insertions, 75 deletions
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_ */