| 1 | /* |
| 2 | * Copyright (c) 2007,2017,2023 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * @APPLE_LICENSE_HEADER_START@ |
| 5 | * |
| 6 | * This file contains Original Code and/or Modifications of Original Code |
| 7 | * as defined in and that are subject to the Apple Public Source License |
| 8 | * Version 2.0 (the 'License'). You may not use this file except in |
| 9 | * compliance with the License. Please obtain a copy of the License at |
| 10 | * http://www.opensource.apple.com/apsl/ and read it before using this |
| 11 | * file. |
| 12 | * |
| 13 | * The Original Code and all software distributed under the License are |
| 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
| 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
| 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
| 18 | * Please see the License for the specific language governing rights and |
| 19 | * limitations under the License. |
| 20 | * |
| 21 | * @APPLE_LICENSE_HEADER_END@ |
| 22 | */ |
| 23 | |
| 24 | #ifndef _STRING_H_ |
| 25 | # error "Never use <secure/_string.h> directly; include <string.h> instead." |
| 26 | #endif |
| 27 | |
| 28 | #ifndef _SECURE__STRING_H_ |
| 29 | #define _SECURE__STRING_H_ |
| 30 | |
| 31 | #include <sys/cdefs.h> |
| 32 | #include <Availability.h> |
| 33 | #include <secure/_common.h> |
| 34 | |
| 35 | #if _USE_FORTIFY_LEVEL > 0 |
| 36 | |
| 37 | #ifdef __LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES |
| 38 | |
| 39 | #if __has_builtin(__builtin___memcpy_chk) |
| 40 | static inline void *_LIBC_SIZE(__n) |
| 41 | __memcpy_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, const void *_LIBC_SIZE(__n) __src, size_t __n) { |
| 42 | 	return _LIBC_FORGE_PTR(__builtin___memcpy_chk(__dst, __src, __n, __darwin_obsz0(__dst)), __n); |
| 43 | } |
| 44 | #define __memcpy_chk_func __memcpy_ptrchk |
| 45 | #endif |
| 46 | |
| 47 | #if __has_builtin(__builtin___memmove_chk) |
| 48 | static inline void *_LIBC_SIZE(__n) |
| 49 | __memmove_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, const void *_LIBC_SIZE(__n) __src, size_t __n) { |
| 50 | 	return _LIBC_FORGE_PTR(__builtin___memmove_chk(__dst, __src, __n, __darwin_obsz0(__dst)), __n); |
| 51 | } |
| 52 | #define __memmove_chk_func __memmove_ptrchk |
| 53 | #endif |
| 54 | |
| 55 | #if __has_builtin(__builtin___memset_chk) |
| 56 | static inline void *_LIBC_SIZE(__n) |
| 57 | __memset_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, int __c, size_t __n) { |
| 58 | 	return _LIBC_FORGE_PTR(__builtin___memset_chk(__dst, __c, __n, __darwin_obsz0(__dst)), __n); |
| 59 | } |
| 60 | #define __memset_chk_func __memset_ptrchk |
| 61 | #endif |
| 62 | |
| 63 | #undef __stpncpy_chk_func /* stpncpy unavailable */ |
| 64 | #undef __strncpy_chk_func /* strncpy unavailable */ |
| 65 | |
| 66 | #if __has_builtin(__builtin___strlcpy_chk) |
| 67 | static inline size_t |
| 68 | __strlcpy_ptrchk(char *const _LIBC_SIZE(__n) __darwin_pass_obsz __dst, const char *__src, size_t __n) { |
| 69 | 	return __builtin___strlcpy_chk(__dst, __src, __n, __darwin_obsz(__dst)); |
| 70 | } |
| 71 | #define __strlcpy_chk_func __strlcpy_ptrchk |
| 72 | #endif |
| 73 | |
| 74 | #if __has_builtin(__builtin___strlcat_chk) |
| 75 | static inline size_t |
| 76 | __strlcat_ptrchk(char *const _LIBC_SIZE(__n) __darwin_pass_obsz __dst, const char *__src, size_t __n) { |
| 77 | 	return __builtin___strlcat_chk(__dst, __src, __n, __darwin_obsz(__dst)); |
| 78 | } |
| 79 | #define __strlcat_chk_func __strlcat_ptrchk |
| 80 | #endif |
| 81 | |
| 82 | #if __has_builtin(__builtin___memccpy_chk) |
| 83 | static inline void *_LIBC_SIZE(__n) |
| 84 | __memccpy_ptrchk(void *const _LIBC_SIZE(__n) __darwin_pass_obsz0 __dst, const void *_LIBC_SIZE(__n) __src, int __c, size_t __n) { |
| 85 | 	return _LIBC_FORGE_PTR(__builtin___memccpy_chk(__dst, __src, __c, __n, __darwin_obsz0(__dst)), __n); |
| 86 | } |
| 87 | #define __memccpy_chk_func __memccpy_ptrchk |
| 88 | #endif |
| 89 | |
| 90 | #undef __strcpy_chk_func /* strcpy unavailable */ |
| 91 | #undef __stpcpy_chk_func /* stpcpy unavailable */ |
| 92 | #undef __strcat_chk_func /* strcat unavailable */ |
| 93 | #undef __strncat_chk_func /* strncat unavailable */ |
| 94 | |
| 95 | #else /* __LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES */ |
| 96 | |
| 97 | #define __is_modern_darwin(ios, macos) \ |
| 98 | 	(__IPHONE_OS_VERSION_MIN_REQUIRED >= (ios) || \ |
| 99 | 	 __MAC_OS_X_VERSION_MIN_REQUIRED >= (macos) || \ |
| 100 | 	 defined(__DRIVERKIT_VERSION_MIN_REQUIRED)) |
| 101 | |
| 102 | /* __is_gcc(gcc_major, gcc_minor) |
| 103 | * Special values: |
| 104 | * 10.0 means "test should always fail when __has_builtin isn't supported" |
| 105 | (because gcc got __has_builtin in version 10.0); this is used for builtins |
| 106 | that gcc did not support yet at the time __has_builtin was introduced, so |
| 107 | there is no point checking the compiler version. |
| 108 | * 0.0 means that we did not research when gcc started supporting this builtin, |
| 109 | but it's believed to have been the case at least since gcc 4.0, which came |
| 110 | out in 2005. (Hello from 2025! What year is it now? Can't believe we're still |
| 111 | using C!) |
| 112 | */ |
| 113 | #define __is_gcc(major, minor) \ |
| 114 | 	(__GNUC__ > (gcc_major) || \ |
| 115 | 	(__GNUC__ == (gcc_major) && __GNUC_MINOR__ >= (gcc_minor))) |
| 116 | |
| 117 | #ifdef __has_builtin |
| 118 | #define __supports_builtin(builtin, gcc_major, gcc_minor) \ |
| 119 | 	__has_builtin(builtin) |
| 120 | #else |
| 121 | #define __supports_builtin(builtin, gcc_major, gcc_minor) __is_gcc(gcc_major, gcc_minor) |
| 122 | #endif |
| 123 | |
| 124 | |
| 125 | #if __supports_builtin(__builtin___memcpy_chk, 0, 0) |
| 126 | #define __memcpy_chk_func(dest, ...) \ |
| 127 | 		__builtin___memcpy_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest)) |
| 128 | #endif |
| 129 | |
| 130 | #if __supports_builtin(__builtin___memmove_chk, 0, 0) |
| 131 | #define __memmove_chk_func(dest, ...) \ |
| 132 | 		__builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest)) |
| 133 | #endif |
| 134 | |
| 135 | #if __supports_builtin(__builtin___memset_chk, 0, 0) |
| 136 | #define __memset_chk_func(dest, ...) \ |
| 137 | 		__builtin___memset_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest)) |
| 138 | #endif |
| 139 | |
| 140 | #if __supports_builtin(__builtin___stpncpy_chk, 4, 7) |
| 141 | #define __stpncpy_chk_func(dest, ...) \ |
| 142 | 		__builtin___stpncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 143 | #endif |
| 144 | |
| 145 | #if __supports_builtin(__builtin___strncpy_chk, 0, 0) |
| 146 | #define __strncpy_chk_func(dest, ...) \ |
| 147 | 		__builtin___strncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 148 | #endif |
| 149 | |
| 150 | #if __is_modern_darwin(70000, 1090) |
| 151 | |
| 152 | #if __supports_builtin(__builtin___strlcpy_chk, 0, 0) |
| 153 | #define __strlcpy_chk_func(dest, ...) \ |
| 154 | 		__builtin___strlcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 155 | #endif |
| 156 | |
| 157 | #if __supports_builtin(__builtin___strlcat_chk, 0, 0) |
| 158 | #define __strlcat_chk_func(dest, ...) \ |
| 159 | 		__builtin___strlcat_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 160 | #endif |
| 161 | |
| 162 | #if __supports_builtin(__builtin___memccpy_chk, 10, 0) |
| 163 | #define __memccpy_chk_func(dest, ...) \ |
| 164 | 	__builtin___memccpy_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest)) |
| 165 | #endif |
| 166 | |
| 167 | #endif /* __is_modern_darwin(70000, 1090) */ |
| 168 | |
| 169 | |
| 170 | #if __supports_builtin(__builtin___strcpy_chk, 0, 0) |
| 171 | #define __strcpy_chk_func(dest, ...) \ |
| 172 | 		__builtin___strcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 173 | #endif |
| 174 | |
| 175 | #if __supports_builtin(__builtin___stpcpy_chk, 0, 0) |
| 176 | #define __stpcpy_chk_func(dest, ...) \ |
| 177 | 		__builtin___stpcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 178 | #endif |
| 179 | |
| 180 | #if __supports_builtin(__builtin___strcat_chk, 0, 0) |
| 181 | #define __strcat_chk_func(dest, ...) \ |
| 182 | 		__builtin___strcat_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 183 | #endif |
| 184 | |
| 185 | #if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000) |
| 186 | #if __supports_builtin(__builtin___strncat_chk, 0, 0) |
| 187 | #define __strncat_chk_func(dest, ...) \ |
| 188 | 		__builtin___strncat_chk (dest, __VA_ARGS__, __darwin_obsz (dest)) |
| 189 | #endif |
| 190 | #endif |
| 191 | |
| 192 | |
| 193 | #undef __supports_builtin |
| 194 | #undef __is_gcc |
| 195 | |
| 196 | #endif /* defined(__has_ptrcheck) && __has_ptrcheck */ |
| 197 | |
| 198 | #undef __is_modern_darwin |
| 199 | |
| 200 | /* memccpy, memcpy, mempcpy, memmove, memset, strcpy, strlcpy, stpcpy, |
| 201 | strncpy, stpncpy, strcat, strlcat, and strncat */ |
| 202 | |
| 203 | /* The use of .../__VA_ARGS__ is load-bearing. If the macros take fixed |
| 204 | * arguments, they are unable to themselves accept macros that expand to |
| 205 | * multiple arguments, like this: |
| 206 | * #define memcpy(a, b, c) ... |
| 207 | * #define FOO(data) get_bytes(data), get_length(data) |
| 208 | * memcpy(bar, FOO(d)); |
| 209 | * This will fail because the preprocessor only sees two arguments on the first |
| 210 | * expansion of memcpy, when 3 are required. |
| 211 | * This is also required to support syntaxes that embed commas. The preprocessor |
| 212 | * recognizes parentheses for the isolation of arguments but not brackets. This |
| 213 | * expands to 3 arguments: |
| 214 | * strcpy(destination, [NSString stringWithFormat:@"%i", 4].UTF8String); |
| 215 | * ^ ^ ^ |
| 216 | * |destination | | |
| 217 | * |[NSString stringWithFormat:@"%i" | |
| 218 | *							 |4].UTF8String |
| 219 | * This expands to 4 arguments: |
| 220 | * memcpy(destination, (uint8_t[]) { 1, 2 }, 2); |
| 221 | * ^ ^ ^ ^ |
| 222 | * To work correctly under these hostile circumstances, chk_func macros |
| 223 | * need to expand to a bare identifier (like #define memcpy_chk_func __memcpy) |
| 224 | * or to a macro that also takes variadic arguments. |
| 225 | */ |
| 226 | |
| 227 | #ifdef __memccpy_chk_func |
| 228 | #undef memccpy |
| 229 | #define memccpy(...) __memccpy_chk_func (__VA_ARGS__) |
| 230 | #endif |
| 231 | |
| 232 | #ifdef __memcpy_chk_func |
| 233 | #undef memcpy |
| 234 | #define memcpy(...) __memcpy_chk_func (__VA_ARGS__) |
| 235 | #endif |
| 236 | |
| 237 | #ifdef __memmove_chk_func |
| 238 | #undef memmove |
| 239 | #define memmove(...) __memmove_chk_func (__VA_ARGS__) |
| 240 | #endif |
| 241 | |
| 242 | #ifdef __memset_chk_func |
| 243 | #undef memset |
| 244 | #define memset(...) __memset_chk_func (__VA_ARGS__) |
| 245 | #endif |
| 246 | |
| 247 | #if defined(__strcpy_chk_func) |
| 248 | #undef strcpy |
| 249 | #define strcpy(...) __strcpy_chk_func (__VA_ARGS__) |
| 250 | #endif |
| 251 | |
| 252 | #if defined(__strcat_chk_func) |
| 253 | #undef strcat |
| 254 | #define strcat(...) __strcat_chk_func (__VA_ARGS__) |
| 255 | #endif |
| 256 | |
| 257 | #if defined(__strncpy_chk_func) |
| 258 | #undef strncpy |
| 259 | #define strncpy(...) __strncpy_chk_func (__VA_ARGS__) |
| 260 | #endif |
| 261 | |
| 262 | #if defined(__strncat_chk_func) |
| 263 | #undef strncat |
| 264 | #define strncat(...) __strncat_chk_func (__VA_ARGS__) |
| 265 | #endif |
| 266 | |
| 267 | #if __DARWIN_C_LEVEL >= 200809L |
| 268 | |
| 269 | #if defined(__stpcpy_chk_func) |
| 270 | #undef stpcpy |
| 271 | #define stpcpy(...) __stpcpy_chk_func (__VA_ARGS__) |
| 272 | #endif |
| 273 | |
| 274 | #if defined(__stpncpy_chk_func) |
| 275 | #undef stpncpy |
| 276 | #define stpncpy(...) __stpncpy_chk_func (__VA_ARGS__) |
| 277 | #endif |
| 278 | |
| 279 | #endif /* __DARWIN_C_LEVEL >= 200809L */ |
| 280 | |
| 281 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL |
| 282 | #if defined(__strlcpy_chk_func) |
| 283 | #undef strlcpy |
| 284 | #define strlcpy(...) __strlcpy_chk_func (__VA_ARGS__) |
| 285 | #endif |
| 286 | |
| 287 | #if defined(__strlcat_chk_func) |
| 288 | #undef strlcat |
| 289 | #define strlcat(...) __strlcat_chk_func (__VA_ARGS__) |
| 290 | #endif |
| 291 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ |
| 292 | |
| 293 | #endif /* _USE_FORTIFY_LEVEL > 0 */ |
| 294 | |
| 295 | #endif /* _SECURE__STRING_H_ */ |