diff options
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/memcpy_chk.c | 66 | ||||
-rw-r--r-- | sysdeps/generic/memmove_chk.c | 98 | ||||
-rw-r--r-- | sysdeps/generic/mempcpy_chk.c | 67 | ||||
-rw-r--r-- | sysdeps/generic/memset_chk.c | 92 | ||||
-rw-r--r-- | sysdeps/generic/readonly-area.c | 29 | ||||
-rw-r--r-- | sysdeps/generic/stpcpy_chk.c | 45 | ||||
-rw-r--r-- | sysdeps/generic/strcat_chk.c | 58 | ||||
-rw-r--r-- | sysdeps/generic/strcpy_chk.c | 46 | ||||
-rw-r--r-- | sysdeps/generic/strncat_chk.c | 100 | ||||
-rw-r--r-- | sysdeps/generic/strncpy_chk.c | 89 |
10 files changed, 690 insertions, 0 deletions
diff --git a/sysdeps/generic/memcpy_chk.c b/sysdeps/generic/memcpy_chk.c new file mode 100644 index 0000000000..638cd0e4fb --- /dev/null +++ b/sysdeps/generic/memcpy_chk.c @@ -0,0 +1,66 @@ +/* Copy memory to memory until the specified number of bytes + has been copied with error checking. Overlap is NOT handled correctly. + Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <memcopy.h> +#include <pagecopy.h> + +void * +__memcpy_chk (dstpp, srcpp, len, dstlen) + void *dstpp; + const void *srcpp; + size_t len; + size_t dstlen; +{ + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + unsigned long int dstp = (long int) dstpp; + unsigned long int srcp = (long int) srcpp; + + /* Copy from the beginning to the end. */ + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= (-dstp) % OPSIZ; + BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); + + /* Copy whole pages from SRCP to DSTP by virtual address manipulation, + as much as possible. */ + + PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); + + /* Copy from SRCP to DSTP taking advantage of the known alignment of + DSTP. Number of bytes remaining is put in the third argument, + i.e. in LEN. This number may vary from machine to machine. */ + + WORD_COPY_FWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_FWD (dstp, srcp, len); + + return dstpp; +} diff --git a/sysdeps/generic/memmove_chk.c b/sysdeps/generic/memmove_chk.c new file mode 100644 index 0000000000..f3b74d23d9 --- /dev/null +++ b/sysdeps/generic/memmove_chk.c @@ -0,0 +1,98 @@ +/* Copy memory to memory until the specified number of bytes + has been copied with error checking. Overlap is handled correctly. + Copyright (C) 1991,1995,1996,1997,2003,2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <memcopy.h> +#include <pagecopy.h> + +void * +__memmove_chk (dest, src, len, destlen) + void *dest; + const void *src; + size_t len; + size_t destlen; +{ + if (__builtin_expect (destlen < len, 0)) + __chk_fail (); + + unsigned long int dstp = (long int) dest; + unsigned long int srcp = (long int) src; + + /* This test makes the forward copying code be used whenever possible. + Reduces the working set. */ + if (dstp - srcp >= len) /* *Unsigned* compare! */ + { + /* Copy from the beginning to the end. */ + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= (-dstp) % OPSIZ; + BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); + + /* Copy whole pages from SRCP to DSTP by virtual address + manipulation, as much as possible. */ + + PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); + + /* Copy from SRCP to DSTP taking advantage of the known + alignment of DSTP. Number of bytes remaining is put + in the third argument, i.e. in LEN. This number may + vary from machine to machine. */ + + WORD_COPY_FWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_FWD (dstp, srcp, len); + } + else + { + /* Copy from the end to the beginning. */ + srcp += len; + dstp += len; + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= dstp % OPSIZ; + BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ); + + /* Copy from SRCP to DSTP taking advantage of the known + alignment of DSTP. Number of bytes remaining is put + in the third argument, i.e. in LEN. This number may + vary from machine to machine. */ + + WORD_COPY_BWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_BWD (dstp, srcp, len); + } + + return dest; +} diff --git a/sysdeps/generic/mempcpy_chk.c b/sysdeps/generic/mempcpy_chk.c new file mode 100644 index 0000000000..5297bbab92 --- /dev/null +++ b/sysdeps/generic/mempcpy_chk.c @@ -0,0 +1,67 @@ +/* Copy memory to memory until the specified number of bytes + has been copied, return pointer to following byte, with error checking. + Overlap is NOT handled correctly. + Copyright (C) 1991, 1997, 1998, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <memcopy.h> +#include <pagecopy.h> + +void * +__mempcpy_chk (dstpp, srcpp, len, dstlen) + void *dstpp; + const void *srcpp; + size_t len; + size_t dstlen; +{ + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + unsigned long int dstp = (long int) dstpp; + unsigned long int srcp = (long int) srcpp; + + /* Copy from the beginning to the end. */ + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= (-dstp) % OPSIZ; + BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); + + /* Copy whole pages from SRCP to DSTP by virtual address manipulation, + as much as possible. */ + + PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); + + /* Copy from SRCP to DSTP taking advantage of the known alignment of + DSTP. Number of bytes remaining is put in the third argument, + i.e. in LEN. This number may vary from machine to machine. */ + + WORD_COPY_FWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_FWD (dstp, srcp, len); + + return (void *) dstp; +} diff --git a/sysdeps/generic/memset_chk.c b/sysdeps/generic/memset_chk.c new file mode 100644 index 0000000000..c311914395 --- /dev/null +++ b/sysdeps/generic/memset_chk.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <memcopy.h> + +void * +__memset_chk (dstpp, c, len, dstlen) + void *dstpp; + int c; + size_t len; + size_t dstlen; +{ + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + long int dstp = (long int) dstpp; + + if (len >= 8) + { + size_t xlen; + op_t cccc; + + cccc = (unsigned char) c; + cccc |= cccc << 8; + cccc |= cccc << 16; + if (OPSIZ > 4) + /* Do the shift in two steps to avoid warning if long has 32 bits. */ + cccc |= (cccc << 16) << 16; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((byte *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ + xlen = len / (OPSIZ * 8); + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + ((op_t *) dstp)[1] = cccc; + ((op_t *) dstp)[2] = cccc; + ((op_t *) dstp)[3] = cccc; + ((op_t *) dstp)[4] = cccc; + ((op_t *) dstp)[5] = cccc; + ((op_t *) dstp)[6] = cccc; + ((op_t *) dstp)[7] = cccc; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ + xlen = len / OPSIZ; + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len > 0) + { + ((byte *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + return dstpp; +} diff --git a/sysdeps/generic/readonly-area.c b/sysdeps/generic/readonly-area.c new file mode 100644 index 0000000000..df5b96015c --- /dev/null +++ b/sysdeps/generic/readonly-area.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Return 1 if the whole area PTR .. PTR+SIZE is not writable. + Return -1 if it is writable. */ + +#include <stdlib.h> + +int +__readonly_str (const void *ptr, size_t size) +{ + /* The conservative answer is that all strings are writable. */ + return -1; +} diff --git a/sysdeps/generic/stpcpy_chk.c b/sysdeps/generic/stpcpy_chk.c new file mode 100644 index 0000000000..dacda0115a --- /dev/null +++ b/sysdeps/generic/stpcpy_chk.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1992, 1995, 1997, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> + + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +char * +__stpcpy_chk (dest, src, destlen) + char *dest; + const char *src; + size_t destlen; +{ + register char *d = dest; + register const char *s = src; + + do + { + if (__builtin_expect (destlen-- == 0, 0)) + __chk_fail (); + *d++ = *s; + } + while (*s++ != '\0'); + + return d - 1; +} diff --git a/sysdeps/generic/strcat_chk.c b/sysdeps/generic/strcat_chk.c new file mode 100644 index 0000000000..b3fb3470b7 --- /dev/null +++ b/sysdeps/generic/strcat_chk.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <memcopy.h> + + +/* Append SRC on the end of DEST. */ +char * +__strcat_chk (dest, src, destlen) + char *dest; + const char *src; + size_t destlen; +{ + char *s1 = dest; + const char *s2 = src; + reg_char c; + + /* Find the end of the string. */ + do + { + if (__builtin_expect (destlen-- == 0, 0)) + __chk_fail (); + c = *s1++; + } + while (c != '\0'); + + /* Make S1 point before the next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + ++destlen; + s1 -= 2; + + do + { + if (__builtin_expect (destlen-- == 0, 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + } + while (c != '\0'); + + return dest; +} diff --git a/sysdeps/generic/strcpy_chk.c b/sysdeps/generic/strcpy_chk.c new file mode 100644 index 0000000000..5c1ae44cd0 --- /dev/null +++ b/sysdeps/generic/strcpy_chk.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1997, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <string.h> +#include <memcopy.h> + +#undef strcpy + +/* Copy SRC to DEST with checking of destination buffer overflow. */ +char * +__strcpy_chk (dest, src, destlen) + char *dest; + const char *src; + size_t destlen; +{ + reg_char c; + char *s = (char *) src; + const ptrdiff_t off = dest - s - 1; + + do + { + if (__builtin_expect (destlen-- == 0, 0)) + __chk_fail (); + c = *s++; + s[off] = c; + } + while (c != '\0'); + + return dest; +} diff --git a/sysdeps/generic/strncat_chk.c b/sysdeps/generic/strncat_chk.c new file mode 100644 index 0000000000..953b435a4b --- /dev/null +++ b/sysdeps/generic/strncat_chk.c @@ -0,0 +1,100 @@ +/* Copyright (C) 1991, 1997, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> + +#include <memcopy.h> + + +char * +__strncat_chk (s1, s2, n, s1len) + char *s1; + const char *s2; + size_t n; + size_t s1len; +{ + reg_char c; + char *s = s1; + + /* Find the end of S1. */ + do + { + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + c = *s1++; + } + while (c != '\0'); + + /* Make S1 point before next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + ++s1len; + s1 -= 2; + + if (n >= 4) + { + size_t n4 = n >> 2; + do + { + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + } while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + n--; + } + + if (c != '\0') + { + if (__builtin_expect (s1len-- == 0, 0)) + __chk_fail (); + *++s1 = '\0'; + } + + return s; +} diff --git a/sysdeps/generic/strncpy_chk.c b/sysdeps/generic/strncpy_chk.c new file mode 100644 index 0000000000..bdede7738b --- /dev/null +++ b/sysdeps/generic/strncpy_chk.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <memcopy.h> + + +char * +__strncpy_chk (s1, s2, n, s1len) + char *s1; + const char *s2; + size_t n; + size_t s1len; +{ + reg_char c; + char *s = s1; + + if (__builtin_expect (s1len < n, 0)) + __chk_fail (); + + --s1; + + if (n >= 4) + { + size_t n4 = n >> 2; + + for (;;) + { + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + if (--n4 == 0) + goto last_chars; + } + n = n - (s1 - s) - 1; + if (n == 0) + return s; + goto zero_fill; + } + + last_chars: + n &= 3; + if (n == 0) + return s; + + do + { + c = *s2++; + *++s1 = c; + if (--n == 0) + return s; + } + while (c != '\0'); + + zero_fill: + do + *++s1 = '\0'; + while (--n > 0); + + return s; +} |