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 #ifndef _STRING_H_ 39 #define _STRING_H_ 1 40 41 #ifdef MACH_KERNEL_PRIVATE 42 #include <types.h> 43 #else 44 #include <sys/types.h> 45 #endif 46 #include <sys/cdefs.h> 47 48 __BEGIN_DECLS 49 50 #ifndef NULL 51 #if defined (__cplusplus) 52 #if __cplusplus >= 201103L 53 #define NULL nullptr 54 #else 55 #define NULL 0 56 #endif 57 #else 58 #define NULL ((void *)0) 59 #endif 60 #endif 61 62 /* 63 * Memory functions 64 * 65 * int bcmp(const void *s1, const void *s2, size_t n); 66 * int memcmp(const void *s1, const void *s2, size_t n); 67 * int timingsafe_bcmp(const void *b1, const void *b2, size_t n); 68 * 69 * void bzero(void *dst, size_t n); 70 * void *memset(void *s, int c, size_t n); 71 * int memset_s(void *s __sized_by(smax), size_t smax, int c, size_t n); 72 * 73 * void bcopy(const void *src, void *dst, size_t n); 74 * void *memcpy(void *dst, const void *src, size_t n); 75 * void *memove(void *dst, const void *src, size_t n); 76 * 77 * 78 * String functions 79 * 80 * size_t strlen(const char *s); 81 * size_t strnlen(const char *s, size_t n); 82 * 83 * int strcmp(const char *s1, const char *s2); 84 * int strncmp(const char *s1, const char *s2, size_t n); 85 * int strprefix(const char *s1, const char *s2) __stateful_pure; 86 * int strcasecmp(const char *s1, const char *s2); 87 * int strncasecmp(const char *s1, const char *s2, size_t n); 88 * 89 * char *strchr(const char *s, int c); 90 * char *strrchr(const char *s, int c); 91 * char *strnstr(const char *s, const char *find, size_t slen); 92 * 93 * size_t strlcpy(char *dst, const char *src, size_t n); 94 * size_t strlcat(char *dst, const char *src, size_t n); 95 */ 96 97 98 /* 99 * _FORTIFY_SOURCE > 0 will enable checked memory/string functions. 100 * 101 * _FORTIFY_SOURCE_STRICT will enable stricter checking (optional) 102 * for memcpy/memmove/bcopy and will check that copies do not go 103 * past the end of a struct member. 104 */ 105 #if KASAN 106 # define XNU_USE_CHK_BUILTIN(n) 0 107 # define XNU_USE_STRING_BUILTIN(n) 0 108 #elif defined (_FORTIFY_SOURCE) && _FORTIFY_SOURCE == 0 109 # define XNU_USE_CHK_BUILTIN(n) 0 110 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 111 #elif __has_ptrcheck 112 # define XNU_USE_CHK_BUILTIN(n) 0 113 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 114 #elif defined(__cplusplus) && __has_include(<__xnu_libcxx_sentinel.h>) 115 # define XNU_USE_CHK_BUILTIN(n) 0 116 # define XNU_USE_STRING_BUILTIN(n) 0 117 #elif XNU_KERNEL_PRIVATE || defined(_FORTIFY_SOURCE_STRICT) 118 # define XNU_USE_CHK_BUILTIN(n) __has_builtin(__builtin___##n##_chk) 119 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 120 # define __xnu_bos_default(ptr) __xnu_bos_strict(ptr) 121 #else 122 # define XNU_USE_CHK_BUILTIN(n) __has_builtin(__builtin___##n##_chk) 123 # define XNU_USE_STRING_BUILTIN(n) __has_builtin(__builtin_##n) 124 # define __xnu_bos_default(ptr) __xnu_bos_loose(ptr) 125 #endif 126 127 #if __has_builtin(__builtin_dynamic_object_size) 128 # define __xnu_bos_loose(ptr) __builtin_dynamic_object_size(ptr, 0) 129 # define __xnu_bos_strict(ptr) __builtin_dynamic_object_size(ptr, 1) 130 #else 131 # define __xnu_bos_loose(ptr) __builtin_object_size(ptr, 0) 132 # define __xnu_bos_strict(ptr) __builtin_object_size(ptr, 1) 133 #endif 134 135 136 #pragma mark memory functions 137 138 extern int bcmp(const void *s1 __sized_by(n), const void *s2 __sized_by(n), size_t n) __stateful_pure; 139 #if XNU_USE_STRING_BUILTIN(bcmp) 140 #define bcmp(s1, s2, n) __builtin_bcmp(s1, s2, n) 141 #endif 142 143 144 extern int memcmp(const void *s1 __sized_by(n), const void *s2 __sized_by(n), size_t n) __stateful_pure; 145 #if XNU_USE_STRING_BUILTIN(memcmp) 146 #define memcmp(s1, s2, n) __builtin_memcmp(s1, s2, n) 147 #endif 148 149 150 #ifdef XNU_KERNEL_PRIVATE 151 /* 152 * memcmp_zero_ptr_aligned() checks string s of n bytes contains all zeros. 153 * Address and size of the string s must be pointer-aligned. 154 * Return 0 if true, 1 otherwise. Also return 0 if n is 0. 155 */ 156 extern unsigned long memcmp_zero_ptr_aligned(const void *s __sized_by(n), size_t n) __stateful_pure; 157 #endif 158 159 160 extern int timingsafe_bcmp(const void *b1 __sized_by(n), const void *b2 __sized_by(n), size_t n); 161 162 163 extern void bzero(void *s __sized_by(n), size_t n); 164 #if XNU_USE_STRING_BUILTIN(bzero) 165 #define bzero(s, n) __builtin_bzero(s, n) 166 #endif 167 168 169 extern void *memset(void *s __sized_by(n), int c, size_t n); 170 #if XNU_USE_CHK_BUILTIN(memset) && XNU_KERNEL_PRIVATE /* rdar://103270898&103281379 */ 171 #define memset(s, c, n) __builtin___memset_chk(s, c, n, __xnu_bos_default(s)) 172 #elif XNU_USE_STRING_BUILTIN(memset) && XNU_KERNEL_PRIVATE 173 #define memset(s, c, n) __builtin_memset(s, c, n) 174 #endif 175 176 177 extern int memset_s(void *s __sized_by(smax), size_t smax, int c, size_t n); 178 179 180 extern void *memcpy(void *dst __sized_by(n), const void *src __sized_by(n), size_t n); 181 #if XNU_USE_CHK_BUILTIN(memcpy) 182 #define memcpy(dst, src, n) __builtin___memcpy_chk(dst, src, n, __xnu_bos_default(dst)) 183 #define __nochk_memcpy(dst, src, n) __builtin___memcpy_chk(dst, src, n, __xnu_bos_loose(dst)) 184 #elif XNU_USE_STRING_BUILTIN(memcpy) 185 #define memcpy(dst, src, n) __builtin_memcpy(dst, src, n) 186 #define __nochk_memcpy(dst, src, n) memcpy(dst, src, n) 187 #else 188 #define __nochk_memcpy(dst, src, n) memcpy(dst, src, n) 189 #endif 190 191 192 extern void *memmove(void *dst __sized_by(n), const void *src __sized_by(n), size_t n); 193 extern void bcopy(const void *src __sized_by(n), void *dst __sized_by(n), size_t n); 194 #if XNU_USE_CHK_BUILTIN(memmove) 195 #define memmove(dst, src, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_default(dst)) 196 #define bcopy(src, dst, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_default(dst)) 197 #define __nochk_memmove(dst, src, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_loose(dst)) 198 #define __nochk_bcopy(src, dst, n) __builtin___memmove_chk(dst, src, n, __xnu_bos_loose(dst)) 199 #elif XNU_USE_STRING_BUILTIN(memmove) 200 #define memmove(dst, src, n) __builtin_memmove(dst, src, n) 201 #define bcopy(src, dst, n) __builtin_memmove(dst, src, n) 202 #define __nochk_memmove(dst, src, n) memmove(dst, src, n) 203 #define __nochk_bcopy(src, dst, n) bcopy(src, dst, n) 204 #else 205 #define __nochk_memmove(dst, src, n) memmove(dst, src, n) 206 #define __nochk_bcopy(src, dst, n) bcopy(src, dst, n) 207 #endif /* !XNU_USE_CHK_BUILTIN(memmove) */ 208 209 210 #pragma mark string functions 211 212 extern size_t strlen(const char *__null_terminated s) __stateful_pure; 213 #if XNU_USE_STRING_BUILTIN(strlen) 214 #define strlen(s) __builtin_strlen(s) 215 #endif 216 217 218 extern size_t strnlen(const char *__null_terminated s, size_t n) __stateful_pure; 219 #if XNU_USE_STRING_BUILTIN(strnlen) 220 #define strnlen(s, n) __builtin_strnlen(s, n) 221 #endif 222 223 224 extern int strcmp(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure; 225 #if XNU_USE_STRING_BUILTIN(strcmp) 226 #define strcmp(s1, s2) __builtin_strcmp(s1, s2) 227 #endif 228 229 230 extern int strncmp(const char *__null_terminated s1, const char *__null_terminated s2, size_t n) __stateful_pure; 231 #if XNU_USE_STRING_BUILTIN(strncmp) 232 #define strncmp(s1, s2, n) __builtin_strncmp(s1, s2, n) 233 #endif 234 235 236 extern int strprefix(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure; 237 238 239 extern int strcasecmp(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure; 240 #if XNU_USE_STRING_BUILTIN(strcasecmp) 241 #define strcasecmp(s1, s2) __builtin_strcasecmp(s1, s2) 242 #endif 243 244 245 extern int strncasecmp(const char *__null_terminated s1, const char *__null_terminated s2, size_t n) __stateful_pure; 246 #if XNU_USE_STRING_BUILTIN(strncasecmp) 247 #define strncasecmp(s1, s2, n) __builtin_strncasecmp(s1, s2, n) 248 #endif 249 250 251 extern char *__null_terminated strchr(const char *__null_terminated s, int c) __stateful_pure; 252 #if XNU_USE_STRING_BUILTIN(strchr) && !__has_ptrcheck /* rdar://103265304 */ 253 #define strchr(s, c) __builtin_strchr(s, c) 254 #endif 255 256 257 #if XNU_KERNEL_PRIVATE /* rdar://103276672 */ 258 extern char *__null_terminated strrchr(const char *__null_terminated s, int c) __stateful_pure; 259 #if XNU_USE_STRING_BUILTIN(strrchr) && !__has_ptrcheck /* rdar://103265304 */ 260 #define strrchr(s, c) __builtin_strrchr(s, c) 261 #endif 262 #endif 263 264 265 extern char *__null_terminated strnstr(const char *__null_terminated s, const char *__null_terminated find, size_t slen) __stateful_pure; 266 #if XNU_USE_STRING_BUILTIN(strnstr) && !__has_ptrcheck /* rdar://103265304 */ 267 #define strnstr(s, find, slen) __builtin_strnstr(s, find, slen) 268 #endif 269 270 271 extern size_t strlcpy(char *__sized_by(n) dst, const char *__null_terminated src, size_t n); 272 #if XNU_USE_CHK_BUILTIN(strlcpy) 273 #define strlcpy(dst, src, n) __builtin___strlcpy_chk(dst, src, n, __xnu_bos_strict(dst)) 274 #elif XNU_USE_STRING_BUILTIN(strlcpy) 275 #define strlcpy(dst, src, n) __builtin_strlcpy(dst, src, n) 276 #endif 277 278 279 extern size_t strlcat(char *__sized_by(n) dst, const char *__null_terminated src, size_t n); 280 #if XNU_USE_CHK_BUILTIN(strlcat) 281 #define strlcat(dst, src, n) __builtin___strlcat_chk(dst, src, n, __xnu_bos_strict(dst)) 282 #elif XNU_USE_STRING_BUILTIN(strlcat) 283 #define strlcat(dst, src, n) __builtin_strlcat(dst, src, n) 284 #endif 285 286 287 #pragma mark deprecated functions 288 #if !__has_ptrcheck 289 290 /* 291 * char *strncat(char *dst, const char *src, size_t n); 292 * char *strncpy(char *dst, const char *src, size_t n); 293 * 294 * char *strcat(char *dst, const char *src); 295 * char *strcpy(char *, const char *); 296 * 297 * char *STRDUP(const char *, int); 298 */ 299 300 __deprecated_msg("use strlcat") 301 __kpi_deprecated_arm64_macos_unavailable 302 extern char *strncat(char *dst, const char *src, size_t n); 303 #if XNU_USE_CHK_BUILTIN(strncat) 304 #define strncat(dst, src, n) __builtin___strncat_chk(dst, src, n, __xnu_bos_strict(dst)) 305 #endif 306 307 308 __deprecated_msg("use strlcpy") 309 __kpi_deprecated_arm64_macos_unavailable 310 extern char *strncpy(char *dst, const char *src, size_t n); 311 #if XNU_USE_CHK_BUILTIN(strncpy) 312 #define strncpy(dst, src, n) __builtin___strncpy_chk(dst, src, n, __xnu_bos_strict(dst)) 313 #endif 314 315 __deprecated_msg("use strlcpy") 316 __kpi_deprecated_arm64_macos_unavailable 317 extern char *strcpy(char *, const char *); 318 #if XNU_USE_CHK_BUILTIN(strcpy) 319 /* rdar://103287225 */ 320 #define strcpy(dst, src, len) __builtin___strcpy_chk(dst, src, __xnu_bos_strict(dst)) 321 #endif 322 323 __deprecated_msg("use strlcat") 324 __kpi_deprecated_arm64_macos_unavailable 325 extern char *strcat(char *dst, const char *src); 326 #if XNU_USE_CHK_BUILTIN(strcat) 327 #define strcat(dst, src) __builtin___strcat_chk(dst, src, __xnu_bos_strict(dst)) 328 #endif 329 330 #if XNU_PLATFORM_MacOSX 331 #ifndef KERNEL_PRIVATE 332 extern char *STRDUP(const char *, int); 333 #endif 334 #endif /* XNU_PLATFORM_MacOSX */ 335 336 #endif /* !__has_ptrcheck */ 337 338 #if __has_include(<san/memintrinsics.h>) 339 #include <san/memintrinsics.h> 340 #endif 341 342 __END_DECLS 343 344 #endif /* _STRING_H_ */ 345