xref: /xnu-10002.1.13/osfmk/libsa/string.h (revision 1031c584a5e37aff177559b9f69dbd3c8c3fd30a)
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