1 /* 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* 29 * NOTICE: This file was modified by McAfee Research in 2004 to introduce 30 * support for mandatory and extensible security protections. This notice 31 * is included in support of clause 2.2 (b) of the Apple Public License, 32 * Version 2.0. 33 */ 34 /* 35 * HISTORY 36 * @OSF_COPYRIGHT@ 37 */ 38 39 #if (defined(__has_include) && __has_include(<__xnu_libcxx_sentinel.h>) && !defined(XNU_LIBCXX_SDKROOT)) 40 41 #if !__has_include_next(<string.h>) 42 #error Do not build with -nostdinc (use GCC_USE_STANDARD_INCLUDE_SEARCHING=NO) 43 #endif /* !__has_include_next(<string.h>) */ 44 45 #include_next <string.h> 46 47 #else /* (defined(__has_include) && __has_include(<__xnu_libcxx_sentinel.h>) && !defined(XNU_LIBCXX_SDKROOT)) */ 48 49 #ifndef _STRING_H_ 50 #define _STRING_H_ 1 51 52 #ifdef MACH_KERNEL_PRIVATE 53 #include <types.h> 54 #else 55 #include <sys/types.h> 56 #endif 57 #include <sys/cdefs.h> 58 59 __BEGIN_DECLS 60 61 #ifndef NULL 62 #if defined (__cplusplus) 63 #if __cplusplus >= 201103L 64 #define NULL nullptr 65 #else 66 #define NULL 0 67 #endif 68 #else 69 #define NULL ((void *)0) 70 #endif 71 #endif 72 73 /* 74 * Memory functions 75 * 76 * int bcmp(const void *s1, const void *s2, size_t n); 77 * int memcmp(const void *s1, const void *s2, size_t n); 78 * int timingsafe_bcmp(const void *b1, const void *b2, size_t n); 79 * 80 * void bzero(void *dst, size_t n); 81 * void *memset(void *s, int c, size_t n); 82 * int memset_s(void *s __sized_by(smax), size_t smax, int c, size_t n); 83 * 84 * void bcopy(const void *src, void *dst, size_t n); 85 * void *memcpy(void *dst, const void *src, size_t n); 86 * void *memove(void *dst, const void *src, size_t n); 87 * 88 * 89 * String functions 90 * 91 * size_t strlen(const char *s); 92 * size_t strnlen(const char *s, size_t n); 93 * 94 * int strcmp(const char *s1, const char *s2); 95 * int strncmp(const char *s1, const char *s2, size_t n); 96 * int strprefix(const char *s1, const char *s2) __stateful_pure; 97 * int strcasecmp(const char *s1, const char *s2); 98 * int strncasecmp(const char *s1, const char *s2, size_t n); 99 * 100 * char *strchr(const char *s, int c); 101 * char *strrchr(const char *s, int c); 102 * char *strnstr(const char *s, const char *find, size_t slen); 103 * 104 * size_t strlcpy(char *dst, const char *src, size_t n); 105 * size_t strlcat(char *dst, const char *src, size_t n); 106 */ 107 108 109 /* 110 * _FORTIFY_SOURCE > 0 will enable checked memory/string functions. 111 * 112 * _FORTIFY_SOURCE_STRICT will enable stricter checking (optional) 113 * for memcpy/memmove/bcopy and will check that copies do not go 114 * past the end of a struct member. 115 */ 116 #if KASAN 117 # define XNU_USE_CHK_BUILTIN(n) 0 118 # define XNU_USE_STRING_BUILTIN(n) 0 119 #elif defined (_FORTIFY_SOURCE) && _FORTIFY_SOURCE == 0 120 # define XNU_USE_CHK_BUILTIN(n) 0 121 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 122 #elif __has_ptrcheck 123 # define XNU_USE_CHK_BUILTIN(n) 0 124 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 125 #elif defined(__cplusplus) && __has_include(<__xnu_libcxx_sentinel.h>) 126 # define XNU_USE_CHK_BUILTIN(n) 0 127 # define XNU_USE_STRING_BUILTIN(n) 0 128 #elif XNU_KERNEL_PRIVATE || defined(_FORTIFY_SOURCE_STRICT) 129 # define XNU_USE_CHK_BUILTIN(n) __has_builtin(__builtin___##n##_chk) 130 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 131 # define __xnu_bos_default(ptr) __xnu_bos_strict(ptr) 132 #else 133 # define XNU_USE_CHK_BUILTIN(n) __has_builtin(__builtin___##n##_chk) 134 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 135 # define __xnu_bos_default(ptr) __xnu_bos_loose(ptr) 136 #endif 137 138 #if __has_builtin(__builtin_dynamic_object_size) 139 # define __xnu_bos_loose(ptr) __builtin_dynamic_object_size(ptr, 0) 140 # define __xnu_bos_strict(ptr) __builtin_dynamic_object_size(ptr, 1) 141 #else 142 # define __xnu_bos_loose(ptr) __builtin_object_size(ptr, 0) 143 # define __xnu_bos_strict(ptr) __builtin_object_size(ptr, 1) 144 #endif 145 146 147 #pragma mark memory functions 148 149 extern int bcmp(const void *s1 __sized_by(n), const void *s2 __sized_by(n), size_t n) __stateful_pure; 150 #if XNU_USE_STRING_BUILTIN(bcmp) 151 #define bcmp(s1, s2, n) __builtin_bcmp(s1, s2, n) 152 #endif 153 154 155 extern int memcmp(const void *s1 __sized_by(n), const void *s2 __sized_by(n), size_t n) __stateful_pure; 156 #if XNU_USE_STRING_BUILTIN(memcmp) 157 #define memcmp(s1, s2, n) __builtin_memcmp(s1, s2, n) 158 #endif 159 160 161 #ifdef XNU_KERNEL_PRIVATE 162 /* 163 * memcmp_zero_ptr_aligned() checks string s of n bytes contains all zeros. 164 * Address and size of the string s must be pointer-aligned. 165 * Return 0 if true, 1 otherwise. Also return 0 if n is 0. 166 */ 167 extern unsigned long memcmp_zero_ptr_aligned(const void *s __sized_by(n), size_t n) __stateful_pure; 168 #endif 169 170 171 extern int timingsafe_bcmp(const void *b1 __sized_by(n), const void *b2 __sized_by(n), size_t n); 172 173 174 extern void bzero(void *s __sized_by(n), size_t n); 175 #if XNU_USE_STRING_BUILTIN(bzero) 176 #define bzero(s, n) __builtin_bzero(s, n) 177 #endif 178 179 180 extern void *memset(void *s __sized_by(n), int c, size_t n); 181 #if XNU_USE_CHK_BUILTIN(memset) && XNU_KERNEL_PRIVATE /* rdar://103270898&103281379 */ 182 #define memset(s, c, n) __builtin___memset_chk(s, c, n, __xnu_bos_default(s)) 183 #elif XNU_USE_STRING_BUILTIN(memset) && XNU_KERNEL_PRIVATE 184 #define memset(s, c, n) __builtin_memset(s, c, n) 185 #endif 186 187 188 extern int memset_s(void *s __sized_by(smax), size_t smax, int c, size_t n); 189 190 191 extern void *memcpy(void *dst __sized_by(n), const void *src __sized_by(n), size_t n); 192 #if XNU_USE_CHK_BUILTIN(memcpy) 193 #define memcpy(dst, src, n) __builtin___memcpy_chk(dst, src, n, __xnu_bos_default(dst)) 194 #define __nochk_memcpy(dst, src, n) __builtin___memcpy_chk(dst, src, n, __xnu_bos_loose(dst)) 195 #elif XNU_USE_STRING_BUILTIN(memcpy) 196 #define memcpy(dst, src, n) __builtin_memcpy(dst, src, n) 197 #define __nochk_memcpy(dst, src, n) memcpy(dst, src, n) 198 #else 199 #define __nochk_memcpy(dst, src, n) memcpy(dst, src, n) 200 #endif 201 202 203 extern void *memmove(void *dst __sized_by(n), const void *src __sized_by(n), size_t n); 204 extern void bcopy(const void *src __sized_by(n), void *dst __sized_by(n), size_t n); 205 #if XNU_USE_CHK_BUILTIN(memmove) 206 #define memmove(dst, src, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_default(dst)) 207 #define bcopy(src, dst, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_default(dst)) 208 #define __nochk_memmove(dst, src, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_loose(dst)) 209 #define __nochk_bcopy(src, dst, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_loose(dst)) 210 #elif XNU_USE_STRING_BUILTIN(memmove) 211 #define memmove(dst, src, n) __builtin_memmove(dst, src, n) 212 #define bcopy(src, dst, n) __builtin_memmove(dst, src, n) 213 #define __nochk_memmove(dst, src, n) memmove(dst, src, n) 214 #define __nochk_bcopy(src, dst, n) bcopy(src, dst, n) 215 #else 216 #define __nochk_memmove(dst, src, n) memmove(dst, src, n) 217 #define __nochk_bcopy(src, dst, n) bcopy(src, dst, n) 218 #endif /* !XNU_USE_CHK_BUILTIN(memmove) */ 219 220 221 #pragma mark string functions 222 223 extern size_t strlen(const char *__null_terminated s) __stateful_pure; 224 #if XNU_USE_STRING_BUILTIN(strlen) 225 #define strlen(s) __builtin_strlen(s) 226 #endif 227 228 229 extern size_t strnlen(const char *__null_terminated s, size_t n) __stateful_pure; 230 #if XNU_USE_STRING_BUILTIN(strnlen) 231 #define strnlen(s, n) __builtin_strnlen(s, n) 232 #endif 233 234 235 extern int strcmp(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure; 236 #if XNU_USE_STRING_BUILTIN(strcmp) 237 #define strcmp(s1, s2) __builtin_strcmp(s1, s2) 238 #endif 239 240 241 extern int strncmp(const char *__null_terminated s1, const char *__null_terminated s2, size_t n) __stateful_pure; 242 #if XNU_USE_STRING_BUILTIN(strncmp) 243 #define strncmp(s1, s2, n) __builtin_strncmp(s1, s2, n) 244 #endif 245 246 247 extern int strprefix(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure; 248 249 250 extern int strcasecmp(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure; 251 #if XNU_USE_STRING_BUILTIN(strcasecmp) 252 #define strcasecmp(s1, s2) __builtin_strcasecmp(s1, s2) 253 #endif 254 255 256 extern int strncasecmp(const char *__null_terminated s1, const char *__null_terminated s2, size_t n) __stateful_pure; 257 #if XNU_USE_STRING_BUILTIN(strncasecmp) 258 #define strncasecmp(s1, s2, n) __builtin_strncasecmp(s1, s2, n) 259 #endif 260 261 262 extern char *__null_terminated strchr(const char *__null_terminated s, int c) __stateful_pure; 263 #if XNU_USE_STRING_BUILTIN(strchr) && !__has_ptrcheck /* rdar://103265304 */ 264 #define strchr(s, c) __builtin_strchr(s, c) 265 #endif 266 267 268 #if XNU_KERNEL_PRIVATE /* rdar://103276672 */ 269 extern char *__null_terminated strrchr(const char *__null_terminated s, int c) __stateful_pure; 270 #if XNU_USE_STRING_BUILTIN(strrchr) && !__has_ptrcheck /* rdar://103265304 */ 271 #define strrchr(s, c) __builtin_strrchr(s, c) 272 #endif 273 #endif 274 275 276 extern char *__null_terminated strnstr(const char *__null_terminated s, const char *__null_terminated find, size_t slen) __stateful_pure; 277 #if XNU_USE_STRING_BUILTIN(strnstr) && !__has_ptrcheck /* rdar://103265304 */ 278 #define strnstr(s, find, slen) __builtin_strnstr(s, find, slen) 279 #endif 280 281 282 extern size_t strlcpy(char *__sized_by(n) dst, const char *__null_terminated src, size_t n); 283 #if XNU_USE_CHK_BUILTIN(strlcpy) 284 #define strlcpy(dst, src, n) __builtin___strlcpy_chk(dst, src, n, __xnu_bos_strict(dst)) 285 #elif XNU_USE_STRING_BUILTIN(strlcpy) 286 #define strlcpy(dst, src, n) __builtin_strlcpy(dst, src, n) 287 #endif 288 289 290 extern size_t strlcat(char *__sized_by(n) dst, const char *__null_terminated src, size_t n); 291 #if XNU_USE_CHK_BUILTIN(strlcat) 292 #define strlcat(dst, src, n) __builtin___strlcat_chk(dst, src, n, __xnu_bos_strict(dst)) 293 #elif XNU_USE_STRING_BUILTIN(strlcat) 294 #define strlcat(dst, src, n) __builtin_strlcat(dst, src, n) 295 #endif 296 297 298 #pragma mark deprecated functions 299 #if !__has_ptrcheck 300 301 /* 302 * char *strncat(char *dst, const char *src, size_t n); 303 * char *strncpy(char *dst, const char *src, size_t n); 304 * 305 * char *strcat(char *dst, const char *src); 306 * char *strcpy(char *, const char *); 307 * 308 * char *STRDUP(const char *, int); 309 */ 310 311 __deprecated_msg("use strlcat") 312 __kpi_deprecated_arm64_macos_unavailable 313 extern char *strncat(char *dst, const char *src, size_t n); 314 #if XNU_USE_CHK_BUILTIN(strncat) 315 #define strncat(dst, src, n) __builtin___strncat_chk(dst, src, n, __xnu_bos_strict(dst)) 316 #endif 317 318 319 __deprecated_msg("use strlcpy") 320 __kpi_deprecated_arm64_macos_unavailable 321 extern char *strncpy(char *dst, const char *src, size_t n); 322 #if XNU_USE_CHK_BUILTIN(strncpy) 323 #define strncpy(dst, src, n) __builtin___strncpy_chk(dst, src, n, __xnu_bos_strict(dst)) 324 #endif 325 326 __deprecated_msg("use strlcpy") 327 __kpi_deprecated_arm64_macos_unavailable 328 extern char *strcpy(char *, const char *); 329 #if XNU_USE_CHK_BUILTIN(strcpy) 330 /* rdar://103287225 */ 331 #define strcpy(dst, src, len) __builtin___strcpy_chk(dst, src, __xnu_bos_strict(dst)) 332 #endif 333 334 __deprecated_msg("use strlcat") 335 __kpi_deprecated_arm64_macos_unavailable 336 extern char *strcat(char *dst, const char *src); 337 #if XNU_USE_CHK_BUILTIN(strcat) 338 #define strcat(dst, src) __builtin___strcat_chk(dst, src, __xnu_bos_strict(dst)) 339 #endif 340 341 #if XNU_PLATFORM_MacOSX 342 #ifndef KERNEL_PRIVATE 343 extern char *STRDUP(const char *, int); 344 #endif 345 #endif /* XNU_PLATFORM_MacOSX */ 346 347 #endif /* !__has_ptrcheck */ 348 349 #if __has_include(<san/memintrinsics.h>) 350 #include <san/memintrinsics.h> 351 #endif 352 353 __END_DECLS 354 355 #endif /* _STRING_H_ */ 356 357 #endif 358