1 /*
2 * Copyright (c) 2000-2020 Apple 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 * @OSF_COPYRIGHT@
30 */
31 /*
32 *(C)UNIX System Laboratories, Inc. all or some portions of this file are
33 * derived from material licensed to the University of California by
34 * American Telephone and Telegraph Co. or UNIX System Laboratories,
35 * Inc. and are reproduced herein with the permission of UNIX System
36 * Laboratories, Inc.
37 */
38
39 /*
40 * Mach Operating System
41 * Copyright (c) 1993,1991,1990,1989,1988 Carnegie Mellon University
42 * All Rights Reserved.
43 *
44 * Permission to use, copy, modify and distribute this software and its
45 * documentation is hereby granted, provided that both the copyright
46 * notice and this permission notice appear in all copies of the
47 * software, derivative works or modified versions, and any portions
48 * thereof, and that both notices appear in supporting documentation.
49 *
50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
52 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53 *
54 * Carnegie Mellon requests users of this software to return to
55 *
56 * Software Distribution Coordinator or [email protected]
57 * School of Computer Science
58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie Mellon
62 * the rights to redistribute these changes.
63 */
64 /*
65 */
66 /*
67 * Copyright (c) 1988 Regents of the University of California.
68 * All rights reserved.
69 *
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
72 * are met:
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. All advertising materials mentioning features or use of this software
79 * must display the following acknowledgement:
80 * This product includes software developed by the University of
81 * California, Berkeley and its contributors.
82 * 4. Neither the name of the University nor the names of its contributors
83 * may be used to endorse or promote products derived from this software
84 * without specific prior written permission.
85 *
86 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
87 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
88 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
89 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
90 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
91 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
92 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
93 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
94 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
95 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
96 * SUCH DAMAGE.
97 */
98
99 /*
100 * Copyright (c) 1998 Todd C. Miller <[email protected]>
101 * All rights reserved.
102 *
103 * Redistribution and use in source and binary forms, with or without
104 * modification, are permitted provided that the following conditions
105 * are met:
106 * 1. Redistributions of source code must retain the above copyright
107 * notice, this list of conditions and the following disclaimer.
108 * 2. Redistributions in binary form must reproduce the above copyright
109 * notice, this list of conditions and the following disclaimer in the
110 * documentation and/or other materials provided with the distribution.
111 * 3. The name of the author may not be used to endorse or promote products
112 * derived from this software without specific prior written permission.
113 *
114 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
115 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
116 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
117 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
118 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
119 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
120 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
121 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
122 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
123 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124 */
125
126 /*
127 * NOTICE: This file was modified by McAfee Research in 2004 to introduce
128 * support for mandatory and extensible security protections. This notice
129 * is included in support of clause 2.2 (b) of the Apple Public License,
130 * Version 2.0.
131 */
132 /*
133 * Random device subroutines and stubs.
134 */
135
136 #include <vm/vm_kern.h>
137 #include <kern/misc_protos.h>
138 #include <libsa/stdlib.h>
139 #include <sys/malloc.h>
140 #include <libkern/section_keywords.h>
141 #include <machine/string.h> /* __arch_* defines */
142
143 /*
144 * Note to implementers, when adding new string/memory functions
145 *
146 * - add a prototype/wrapper to osfmk/libsa/string.h,
147 * and an impl prototype to osfmk/machine/string.h.
148 *
149 * - if the function has a "chk" variant, add support to osfmk/libsa/string.h
150 * and the implementation for the checked variant at the end of this file.
151 *
152 * - define the function with the "impl" name and wrap it inside
153 * an #ifndef __arch_${function} block to allow each architecture
154 * to provide an optimized version if they so desire.
155 */
156
157 static_assert(__arch_bcopy, "architecture must provide bcopy");
158 static_assert(__arch_bzero, "architecture must provide bzero");
159 static_assert(__arch_memcpy, "architecture must provide memcpy");
160 static_assert(__arch_memset, "architecture must provide memset");
161
162 #ifndef __arch_bcmp
163 int
bcmp_impl(const void * pa,const void * pb,size_t len)164 bcmp_impl(const void *pa, const void *pb, size_t len)
165 {
166 const char *a = (const char *)pa;
167 const char *b = (const char *)pb;
168
169 if (len == 0) {
170 return 0;
171 }
172
173 do{
174 if (*a++ != *b++) {
175 break;
176 }
177 } while (--len);
178
179 /*
180 * Check for the overflow case but continue to handle the non-overflow
181 * case the same way just in case someone is using the return value
182 * as more than zero/non-zero
183 */
184 if ((len & 0xFFFFFFFF00000000ULL) && !(len & 0x00000000FFFFFFFFULL)) {
185 return 0xFFFFFFFFL;
186 } else {
187 return (int)len;
188 }
189 }
190 #endif /* __arch_bcmp */
191
192 #ifndef __arch_memcmp
193 MARK_AS_HIBERNATE_TEXT
194 int
memcmp_impl(const void * s1,const void * s2,size_t n)195 memcmp_impl(const void *s1, const void *s2, size_t n)
196 {
197 if (n != 0) {
198 const unsigned char *p1 = s1, *p2 = s2;
199
200 do {
201 if (*p1++ != *p2++) {
202 return *--p1 - *--p2;
203 }
204 } while (--n != 0);
205 }
206 return 0;
207 }
208 #endif /* __arch_memcmp */
209
210 #ifndef __arch_memcmp_zero_ptr_aligned
211 unsigned long
memcmp_zero_ptr_aligned(const void * addr,size_t size)212 memcmp_zero_ptr_aligned(const void *addr, size_t size)
213 {
214 const uint64_t *p = (const uint64_t *)addr;
215 uint64_t a = p[0];
216
217 static_assert(sizeof(unsigned long) == sizeof(uint64_t));
218
219 if (size < 4 * sizeof(uint64_t)) {
220 if (size > 1 * sizeof(uint64_t)) {
221 a |= p[1];
222 if (size > 2 * sizeof(uint64_t)) {
223 a |= p[2];
224 }
225 }
226 } else {
227 size_t count = size / sizeof(uint64_t);
228 uint64_t b = p[1];
229 uint64_t c = p[2];
230 uint64_t d = p[3];
231
232 /*
233 * note: for sizes not a multiple of 32 bytes, this will load
234 * the bytes [size % 32 .. 32) twice which is ok
235 */
236 while (count > 4) {
237 count -= 4;
238 a |= p[count + 0];
239 b |= p[count + 1];
240 c |= p[count + 2];
241 d |= p[count + 3];
242 }
243
244 a |= b | c | d;
245 }
246
247 return a;
248 }
249 #endif /* __arch_memcmp_zero_ptr_aligned */
250
251 #ifndef __arch_memmove
252 /* memcpy is provided as a linker alias */
253 void *
memmove_impl(void * dst,const void * src,size_t ulen)254 memmove_impl(void *dst, const void *src, size_t ulen)
255 {
256 bcopy_impl(src, dst, ulen);
257 return dst;
258 }
259 #endif /* __arch_memmove */
260
261 /*
262 * Abstract:
263 * strlen returns the number of characters in "string" preceeding
264 * the terminating null character.
265 */
266 #ifndef __arch_strlen
267 size_t
strlen_impl(const char * string)268 strlen_impl(const char *string)
269 {
270 const char *ret = string;
271
272 while (*string++ != '\0') {
273 continue;
274 }
275 return string - 1 - ret;
276 }
277 #endif /* __arch_strlen */
278
279 /*
280 * Does the same thing as strlen, except only looks up
281 * to max chars inside the buffer.
282 * Taken from archive/kern-stuff/sbf_machine.c in
283 * seatbelt.
284 * inputs:
285 * s string whose length is to be measured
286 * max maximum length of string to search for null
287 * outputs:
288 * length of s or max; whichever is smaller
289 */
290 #ifndef __arch_strnlen
291 size_t
strnlen_impl(const char * s,size_t max)292 strnlen_impl(const char *s, size_t max)
293 {
294 const char *es = s + max, *p = s;
295 while (p != es && *p) {
296 p++;
297 }
298
299 return p - s;
300 }
301 #endif /* __arch_strlen */
302
303 /*
304 * Abstract:
305 * strcmp (s1, s2) compares the strings "s1" and "s2".
306 * It returns 0 if the strings are identical. It returns
307 * > 0 if the first character that differs in the two strings
308 * is larger in s1 than in s2 or if s1 is longer than s2 and
309 * the contents are identical up to the length of s2.
310 * It returns < 0 if the first differing character is smaller
311 * in s1 than in s2 or if s1 is shorter than s2 and the
312 * contents are identical upto the length of s1.
313 * Deprecation Warning:
314 * strcmp() is being deprecated. Please use strncmp() instead.
315 */
316 #ifndef __arch_strcmp
317 int
strcmp_impl(const char * s1,const char * s2)318 strcmp_impl(const char *s1, const char *s2)
319 {
320 unsigned int a, b;
321
322 do {
323 a = *s1++;
324 b = *s2++;
325 if (a != b) {
326 return a - b; /* includes case when
327 * 'a' is zero and 'b' is not zero
328 * or vice versa */
329 }
330 } while (a != '\0');
331
332 return 0; /* both are zero */
333 }
334 #endif /* __arch_strcmp */
335
336 /*
337 * Abstract:
338 * strncmp (s1, s2, n) compares the strings "s1" and "s2"
339 * in exactly the same way as strcmp does. Except the
340 * comparison runs for at most "n" characters.
341 */
342
343 #ifndef __arch_strncmp
344 int
strncmp_impl(const char * s1,const char * s2,size_t n)345 strncmp_impl(const char *s1, const char *s2, size_t n)
346 {
347 unsigned int a, b;
348
349 while (n != 0) {
350 a = *s1++;
351 b = *s2++;
352 if (a != b) {
353 return a - b; /* includes case when
354 * 'a' is zero and 'b' is not zero
355 * or vice versa */
356 }
357 if (a == '\0') {
358 return 0; /* both are zero */
359 }
360 n--;
361 }
362
363 return 0;
364 }
365 #endif /* __arch_strncmp */
366
367 /*
368 * Return TRUE(1) if string 2 is a prefix of string 1.
369 */
370 int
strprefix(const char * s1,const char * s2)371 strprefix(const char *s1, const char *s2)
372 {
373 int c;
374
375 while ((c = *s2++) != '\0') {
376 if (c != *s1++) {
377 return 0;
378 }
379 }
380 return 1;
381 }
382
383
384 //
385 // Lame implementation just for use by strcasecmp/strncasecmp
386 //
387 __header_always_inline int
tolower(unsigned char ch)388 tolower(unsigned char ch)
389 {
390 if (ch >= 'A' && ch <= 'Z') {
391 ch = 'a' + (ch - 'A');
392 }
393
394 return ch;
395 }
396
397 #ifndef __arch_strcasecmp
398 int
strcasecmp_impl(const char * s1,const char * s2)399 strcasecmp_impl(const char *s1, const char *s2)
400 {
401 const unsigned char *us1 = (const u_char *)s1,
402 *us2 = (const u_char *)s2;
403
404 while (tolower(*us1) == tolower(*us2++)) {
405 if (*us1++ == '\0') {
406 return 0;
407 }
408 }
409 return tolower(*us1) - tolower(*--us2);
410 }
411 #endif /* __arch_strcasecmp */
412
413 #ifndef __arch_strncasecmp
414 int
strncasecmp_impl(const char * s1,const char * s2,size_t n)415 strncasecmp_impl(const char *s1, const char *s2, size_t n)
416 {
417 if (n != 0) {
418 const unsigned char *us1 = (const u_char *)s1,
419 *us2 = (const u_char *)s2;
420
421 do {
422 if (tolower(*us1) != tolower(*us2++)) {
423 return tolower(*us1) - tolower(*--us2);
424 }
425 if (*us1++ == '\0') {
426 break;
427 }
428 } while (--n != 0);
429 }
430 return 0;
431 }
432 #endif /* __arch_strncasecmp */
433
434 #ifndef __arch_strchr
435 char *
strchr_impl(const char * s,int c)436 strchr_impl(const char *s, int c)
437 {
438 if (!s) {
439 return NULL;
440 }
441
442 do {
443 if (*s == c) {
444 return __CAST_AWAY_QUALIFIER(s, const, char *);
445 }
446 } while (*s++);
447
448 return NULL;
449 }
450 #endif /* __arch_strchr */
451
452 #ifndef __arch_strrchr
453 char *
strrchr_impl(const char * s,int c)454 strrchr_impl(const char *s, int c)
455 {
456 const char *found = NULL;
457
458 if (!s) {
459 return NULL;
460 }
461
462 do {
463 if (*s == c) {
464 found = s;
465 }
466 } while (*s++);
467
468 return __CAST_AWAY_QUALIFIER(found, const, char *);
469 }
470 #endif /* __arch_strchr */
471
472 #if CONFIG_VSPRINTF
473 /*
474 * Abstract:
475 * strcpy copies the contents of the string "from" including
476 * the null terminator to the string "to". A pointer to "to"
477 * is returned.
478 * Deprecation Warning:
479 * strcpy() is being deprecated. Please use strlcpy() instead.
480 */
481 char *
strcpy_impl(char * to,const char * from)482 strcpy_impl(char *to, const char *from)
483 {
484 char *ret = to;
485
486 while ((*to++ = *from++) != '\0') {
487 continue;
488 }
489
490 return ret;
491 }
492 #endif
493
494 /*
495 * Abstract:
496 * strncpy copies "count" characters from the "from" string to
497 * the "to" string. If "from" contains less than "count" characters
498 * "to" will be padded with null characters until exactly "count"
499 * characters have been written. The return value is a pointer
500 * to the "to" string.
501 */
502 #ifndef __arch_strncpy
503 char *
strncpy_impl(char * dst,const char * src,size_t maxlen)504 strncpy_impl(char * dst, const char * src, size_t maxlen)
505 {
506 const size_t srclen = strnlen_impl(src, maxlen);
507 if (srclen < maxlen) {
508 memcpy_impl(dst, src, srclen);
509 memset_impl(dst + srclen, 0, maxlen - srclen);
510 } else {
511 memcpy_impl(dst, src, maxlen);
512 }
513 return dst;
514 }
515 #endif /* __arch_strncpy */
516
517 /*
518 * atoi:
519 *
520 * This function converts an ascii string into an integer.
521 *
522 * input : string
523 * output : a number
524 */
525
526 int
atoi(const char * cp)527 atoi(const char *cp)
528 {
529 int number;
530
531 for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++) {
532 number = (number * 10) + (*cp - '0');
533 }
534
535 return number;
536 }
537
538 /*
539 * convert an integer to an ASCII string.
540 * inputs:
541 * num integer to be converted
542 * str string pointer.
543 *
544 * outputs:
545 * pointer to string start.
546 */
547
548 char *
itoa(int num,char * str)549 itoa(int num, char *str)
550 {
551 char digits[11];
552 char *dp;
553 char *cp = str;
554
555 if (num == 0) {
556 *cp++ = '0';
557 } else {
558 dp = digits;
559 while (num) {
560 *dp++ = '0' + num % 10;
561 num /= 10;
562 }
563 while (dp != digits) {
564 *cp++ = *--dp;
565 }
566 }
567 *cp++ = '\0';
568
569 return str;
570 }
571
572 #if CONFIG_VSPRINTF
573 /*
574 * Deprecation Warning:
575 * strcat() is being deprecated. Please use strlcat() instead.
576 */
577 char *
strcat_impl(char * dest,const char * src)578 strcat_impl(char *dest, const char *src)
579 {
580 char *old = dest;
581
582 while (*dest) {
583 ++dest;
584 }
585 while ((*dest++ = *src++)) {
586 ;
587 }
588 return old;
589 }
590 #endif
591
592 /*
593 * Appends src to string dst of size siz (unlike strncat, siz is the
594 * full size of dst, not space left). At most siz-1 characters
595 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
596 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
597 * If retval >= siz, truncation occurred.
598 */
599 #ifndef __arch_strlcat
600 size_t
strlcat_impl(char * dst,const char * src,size_t siz)601 strlcat_impl(char *dst, const char *src, size_t siz)
602 {
603 char *d = dst;
604 const char *s = src;
605 size_t n = siz;
606 size_t dlen = strlen_impl(dst);
607
608 /* Find the end of dst and adjust bytes left but don't go past end */
609 while (n-- != 0 && *d != '\0') {
610 d++;
611 }
612 dlen = d - dst;
613 n = siz - dlen;
614
615 if (n == 0) {
616 return dlen + strlen_impl(s);
617 }
618 while (*s != '\0') {
619 if (n != 1) {
620 *d++ = *s;
621 n--;
622 }
623 s++;
624 }
625 *d = '\0';
626
627 return dlen + (s - src); /* count does not include NUL */
628 }
629 #endif /* __arch_strlcat */
630
631 /*
632 * Copy src to string dst of size siz. At most siz-1 characters
633 * will be copied. Always NUL terminates (unless siz == 0).
634 * Returns strlen(src); if retval >= siz, truncation occurred.
635 */
636 #ifndef __arch_strlcpy
637 size_t
strlcpy_impl(char * dst,const char * src,size_t maxlen)638 strlcpy_impl(char * dst, const char * src, size_t maxlen)
639 {
640 const size_t srclen = strlen_impl(src);
641 if (srclen + 1 < maxlen) {
642 memcpy_impl(dst, src, srclen + 1);
643 } else if (maxlen != 0) {
644 memcpy_impl(dst, src, maxlen - 1);
645 dst[maxlen - 1] = '\0';
646 }
647 return srclen;
648 }
649 #endif /* __arch_strlcpy */
650
651 #ifndef __arch_strncat
652 char *
strncat_impl(char * s1,const char * s2,size_t n)653 strncat_impl(char *s1, const char *s2, size_t n)
654 {
655 if (n != 0) {
656 char *d = s1;
657 const char *s = s2;
658
659 while (*d != 0) {
660 d++;
661 }
662 do {
663 if ((*d = *s++) == '\0') {
664 break;
665 }
666 d++;
667 } while (--n != 0);
668 *d = '\0';
669 }
670
671 return __CAST_AWAY_QUALIFIER(s1, const, char *);
672 }
673 #endif /* __arch_strncat */
674
675 #ifndef __arch_strnstr
676 char *
strnstr_impl(const char * s,const char * find,size_t slen)677 strnstr_impl(const char *s, const char *find, size_t slen)
678 {
679 char c, sc;
680 size_t len;
681
682 if ((c = *find++) != '\0') {
683 len = strlen_impl(find);
684 do {
685 do {
686 if ((sc = *s++) == '\0' || slen-- < 1) {
687 return NULL;
688 }
689 } while (sc != c);
690 if (len > slen) {
691 return NULL;
692 }
693 } while (strncmp_impl(s, find, len) != 0);
694 s--;
695 }
696
697 return __CAST_AWAY_QUALIFIER(s, const, char *);
698 }
699 #endif /* __arch_strnstr */
700
701 void * __memcpy_chk(void *dst, void const *src, size_t s, size_t chk_size);
702 void * __memmove_chk(void *dst, void const *src, size_t s, size_t chk_size);
703 void * __memset_chk(void *dst, int c, size_t s, size_t chk_size);
704 size_t __strlcpy_chk(char *dst, char const *src, size_t s, size_t chk_size);
705 size_t __strlcat_chk(char *dst, char const *src, size_t s, size_t chk_size);
706 char * __strncpy_chk(char *restrict dst, char *restrict src, size_t len, size_t chk_size);
707 char * __strncat_chk(char *restrict dst, const char *restrict src, size_t len, size_t chk_size);
708 char * __strcpy_chk(char *restrict dst, const char *restrict src, size_t chk_size);
709 char * __strcat_chk(char *restrict dst, const char *restrict src, size_t chk_size);
710
711 MARK_AS_HIBERNATE_TEXT
712 void *
__memcpy_chk(void * dst,void const * src,size_t s,size_t chk_size)713 __memcpy_chk(void *dst, void const *src, size_t s, size_t chk_size)
714 {
715 if (__improbable(chk_size < s)) {
716 panic("__memcpy_chk object size check failed: dst %p, src %p, (%zu < %zu)", dst, src, chk_size, s);
717 }
718 return memcpy_impl(dst, src, s);
719 }
720
721 void *
__memmove_chk(void * dst,void const * src,size_t s,size_t chk_size)722 __memmove_chk(void *dst, void const *src, size_t s, size_t chk_size)
723 {
724 if (__improbable(chk_size < s)) {
725 panic("__memmove_chk object size check failed: dst %p, src %p, (%zu < %zu)", dst, src, chk_size, s);
726 }
727 return memmove_impl(dst, src, s);
728 }
729
730 MARK_AS_HIBERNATE_TEXT
731 void *
__memset_chk(void * dst,int c,size_t s,size_t chk_size)732 __memset_chk(void *dst, int c, size_t s, size_t chk_size)
733 {
734 if (__improbable(chk_size < s)) {
735 panic("__memset_chk object size check failed: dst %p, c %c, (%zu < %zu)", dst, c, chk_size, s);
736 }
737 return memset_impl(dst, c, s);
738 }
739
740 size_t
__strlcat_chk(char * dst,char const * src,size_t s,size_t chk_size)741 __strlcat_chk(char *dst, char const *src, size_t s, size_t chk_size)
742 {
743 if (__improbable(chk_size < s)) {
744 panic("__strlcat_chk object size check failed: dst %p, src %p, (%zu < %zu)", dst, src, chk_size, s);
745 }
746 return strlcat_impl(dst, src, s);
747 }
748
749 size_t
__strlcpy_chk(char * dst,char const * src,size_t s,size_t chk_size)750 __strlcpy_chk(char *dst, char const *src, size_t s, size_t chk_size)
751 {
752 if (__improbable(chk_size < s)) {
753 panic("__strlcpy_chk object size check failed: dst %p, src %p, (%zu < %zu)", dst, src, chk_size, s);
754 }
755 return strlcpy_impl(dst, src, s);
756 }
757
758 char *
__strncpy_chk(char * restrict dst,char * restrict src,size_t len,size_t chk_size)759 __strncpy_chk(char *restrict dst, char *restrict src,
760 size_t len, size_t chk_size)
761 {
762 if (__improbable(chk_size < len)) {
763 panic("__strncpy_chk object size check failed: dst %p, src %p, (%zu < %zu)", dst, src, chk_size, len);
764 }
765 return strncpy_impl(dst, src, len);
766 }
767
768 char *
__strncat_chk(char * restrict dst,const char * restrict src,size_t len,size_t chk_size)769 __strncat_chk(char *restrict dst, const char *restrict src,
770 size_t len, size_t chk_size)
771 {
772 size_t len1 = strlen_impl(dst);
773 size_t len2 = strnlen_impl(src, len);
774 if (__improbable(chk_size < len1 + len2 + 1)) {
775 panic("__strncat_chk object size check failed: dst %p, src %p, (%zu < %zu + %zu + 1)", dst, src, chk_size, len1, len2);
776 }
777 return strncat_impl(dst, src, len);
778 }
779
780 char *
__strcpy_chk(char * restrict dst,const char * restrict src,size_t chk_size)781 __strcpy_chk(char *restrict dst, const char *restrict src, size_t chk_size)
782 {
783 size_t len = strlen_impl(src);
784 if (__improbable(chk_size < len + 1)) {
785 panic("__strcpy_chk object size check failed: dst %p, src %p, (%zu < %zu + 1)", dst, src, chk_size, len);
786 }
787 memcpy_impl(dst, src, len + 1);
788 return dst;
789 }
790
791 char *
__strcat_chk(char * restrict dst,const char * restrict src,size_t chk_size)792 __strcat_chk(char *restrict dst, const char *restrict src, size_t chk_size)
793 {
794 size_t len1 = strlen_impl(dst);
795 size_t len2 = strlen_impl(src);
796 size_t required_len = len1 + len2 + 1;
797 if (__improbable(chk_size < required_len)) {
798 panic("__strcat_chk object size check failed: dst %p, src %p, (%zu < %zu + %zu + 1)", dst, src, chk_size, len1, len2);
799 }
800 memcpy_impl(dst + len1, src, len2 + 1);
801 return dst;
802 }
803