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