mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 02:40:08 +00:00
2004-10-15 Jakub Jelinek <jakub@redhat.com>
* elf/dl-minimal.c (__chk_fail): New. Add rtld_hidden_def. * sysdeps/unix/sysv/linux/readonly-area.c: New file. * sysdeps/i386/i686/memmove.S (__memmove_chk): Add checking routine. * sysdeps/i386/i686/memcpy.S (__memcpy_chk): Likewise. * sysdeps/i386/i686/mempcpy.S (__mempcpy_chk): Likewise. * sysdeps/i386/i686/memset.S (__memset_chk): Likewise. * sysdeps/i386/i686/memmove-chk.S: New file. * sysdeps/i386/i686/memcpy-chk.S: Likewise. * sysdeps/i386/i686/mempcpy-chk.S: Likewise. * sysdeps/i386/i686/memset-chk.S: Likewise. * sysdeps/generic/strcat-chk.c (__strcat_chk): Don't __chk_fail if exactly fitting into buffer. * sysdeps/generic/strncat-chk.c (__strncat_chk): Likewise. * sysdeps/generic/readonly-area.c: New file. * sysdeps/generic/strncpy-chk.c (__strncpy_chk): Only test destlen once. * sysdeps/x86_64/memset.S (__memset_chk): Add checking routine. * sysdeps/x86_64/memcpy.S (__memcpy_chk): Likewise. * sysdeps/x86_64/mempcpy.S (__memcpy_chk): Define to __mempcpy_chk. * sysdeps/x86_64/memcpy-chk.S: New file. * sysdeps/x86_64/mempcpy-chk.S: Likewise. * sysdeps/x86_64/memset-chk.S: Likewise. * sysdeps/x86_64/strcpy-chk.S: Likewise. * sysdeps/x86_64/stpcpy-chk.S: Likewise. * argp/argp-xinl.c (__OPTIMIZE__): Define to 1 instead of nothing. * argp/argp-fs-xinl.c (__OPTIMIZE__): Likewise. * debug/tst-chk1.c: New test. * debug/tst-chk2.c: Likewise. * debug/tst-chk3.c: Likewise. * debug/test-strcpy_chk.c: Likewise. * debug/test-stpcpy_chk.c: Likewise. * debug/vsprintf_chk.c (__vsprintf_chk): If flags > 0, request _IO_FLAGS2_CHECK_PERCENT_N. Add libc_hidden_def. * debug/Makefile (routines): Add printf_chk, fprintf_chk, vprintf_chk, vfprintf_chk, gets_chk and readonly-area. (CFLAGS-*_chk.c): Set. (tests): Add tst-chk1, tst-chk2, tst-chk3, test-strcpy_chk and test-stpcpy_chk. * debug/vprintf_chk.c: New file. * debug/printf_chk.c: Likewise. * debug/vfprintf_chk.c: Likewise. * debug/fprintf_chk.c: Likewise. * debug/gets_chk.c: Likewise. * debug/chk_fail.c (__chk_fail): Add libc_hidden_def. * debug/snprintf_chk.c (__snprintf_chk): Fix order of arguments passed to __vsnprintf_chk. * debug/Versions (libc): Export __printf_chk, __fprintf_chk, __vprintf_chk, __vfprintf_chk and __gets_chk @GLIBC_2.3.4. * debug/vsnprintf_chk.c (__vsnprintf_chk): Don't call __vsnprintf, instead create a temporary file with _IO_strn_jumps jumptable. If flags > 0, request _IO_FLAGS2_CHECK_PERCENT_N. Add libc_hidden_def. * libio/Makefile (headers): Add bits/stdio2.h. * libio/stdio.h: Include <bits/stdio2.h> if __USE_FORTIFY_LEVEL. (sprintf, snprintf, vsprintf, vsnprintf): Remove defines. * libio/strfile.h (_IO_strnfile): New type. (_IO_strn_jumps): New extern. * libio/vsnprintf.c (_IO_strnfile): Remove. (_IO_strn_jumps): Remove static. * libio/bits/stdio2.h: New file. * libio/vswprintf.c (_IO_strnfile): Rename type to... (_IO_wstrnfile): ...this. Adjust all uses. * libio/libio.h (_IO_FLAGS2_CHECK_PERCENT_N): Define. * stdio-common/vfprintf.c (STR_LEN): Define. (vfprintf): Add readonly_format variable. Handle _IO_FLAGS2_CHECK_PERCENT_N. (buffered_vfprintf): Copy _flags2. * include/stdio.h (__sprintf_chk, __snprintf_chk, __vsprintf_chk, __vsnprintf_chk, __printf_chk, __fprintf_chk, __vprintf_chk, __vfprintf_chk): New prototypes. (__vsprintf_chk, __vsnprintf_chk): Add libc_hidden_proto. * include/string.h (__memcpy_chk, __memmove_chk, __mempcpy_chk, __memset_chk, __strcpy_chk, __stpcpy_chk, __strncpy_chk, __strcat_chk, __strncat_chk): New prototypes. * include/bits/string3.h: New file. * include/sys/cdefs.h (__chk_fail): Add libc_hidden_proto and rtld_hidden_proto. * string/Makefile (headers): Add bits/string3.h. * string/bits/string3.h (bcopy, bzero): New defines. (memset, memcpy, memmove, strcpy, strncpy, strcat, strncat): Change macros so that inlines are used only if unknown destination size or side-effects in destination argument. (mempcpy, stpcpy): Likewise. Protect with #ifdef __USE_GNU. 2004-09-16 Ulrich Drepper <drepper@redhat.com> * debug/Makefile (routines): Add *_chk. * debug/Versions (libc): Export __chk_fail, __memcpy_chk, __memmove_chk, __mempcpy_chk, __memset_chk, __stpcpy_chk, __strcat_chk, __strcpy_chk, __strncat_chk, __strncpy_chk, __sprintf_chk, __vsprintf_chk, __snprintf_chk, __vsnprintf_chk @GLIBC_2.3.4. * debug/chk_fail.c: New file. * debug/snprintf_chk.c: Likewise. * debug/sprintf_chk.c: Likewise. * debug/vsnprintf_chk.c: Likewise. * debug/vsprintf_chk.c: Likewise. * include/features.h (_FORTIFY_SOURCE): Document, handle. (__USE_FORTIFY_LEVEL): Define. (__GNUC_PREREQ): Move to earlier location. * include/sys/cdefs.h (__chk_fail): New prototype. * libio/bits/stdio.h (sprintf, vsprintf, snprintf, vsnprintf): Define if __USE_FORTIFY_LEVEL. * misc/sys/cdefs.h (__bos, __bos0): Define. * string/string.h: Include <bits/string3.h> if __USE_FORTIFY_LEVEL. * bits/string/string3.h: New header. * sysdeps/generic/memcpy_chk.c: New file. * sysdeps/generic/memmove_chk.c: Likewise. * sysdeps/generic/mempcpy_chk.c: Likewise. * sysdeps/generic/memset_chk.c: Likewise. * sysdeps/generic/stpcpy_chk.c: Likewise. * sysdeps/generic/strcat_chk.c: Likewise. * sysdeps/generic/strcpy_chk.c: Likewise. * sysdeps/generic/strncat_chk.c: Likewise. * sysdeps/generic/strncpy_chk.c: Likewise. 2004-10-15 Jakub Jelinek <jakub@redhat.com> * elf/dl-minimal.c (__chk_fail): New. Add rtld_hidden_def. * sysdeps/unix/sysv/linux/readonly-area.c: New file. * sysdeps/i386/i686/memmove.S (__memmove_chk): Add checking routine. * sysdeps/i386/i686/memcpy.S (__memcpy_chk): Likewise. * sysdeps/i386/i686/mempcpy.S (__mempcpy_chk): Likewise. * sysdeps/i386/i686/memset.S (__memset_chk): Likewise. * sysdeps/i386/i686/memmove-chk.S: New file. * sysdeps/i386/i686/memcpy-chk.S: Likewise. * sysdeps/i386/i686/mempcpy-chk.S: Likewise. * sysdeps/i386/i686/memset-chk.S: Likewise. * sysdeps/generic/strcat-chk.c (__strcat_chk): Don't __chk_fail if exactly fitting into buffer. * sysdeps/generic/strncat-chk.c (__strncat_chk): Likewise. * sysdeps/generic/readonly-area.c: New file. * sysdeps/generic/strncpy-chk.c (__strncpy_chk): Only test destlen once. * sysdeps/x86_64/memset.S (__memset_chk): Add checking routine. * sysdeps/x86_64/memcpy.S (__memcpy_chk): Likewise. * sysdeps/x86_64/mempcpy.S (__memcpy_chk): Define to __mempcpy_chk. * sysdeps/x86_64/memcpy-chk.S: New file. * sysdeps/x86_64/mempcpy-chk.S: Likewise. * sysdeps/x86_64/memset-chk.S: Likewise. * sysdeps/x86_64/strcpy-chk.S: Likewise. * sysdeps/x86_64/stpcpy-chk.S: Likewise. * argp/argp-xinl.c (__OPTIMIZE__): Define to 1 instead of nothing. * argp/argp-fs-xinl.c (__OPTIMIZE__): Likewise. * debug/tst-chk1.c: New test. * debug/tst-chk2.c: Likewise. * debug/tst-chk3.c: Likewise. * debug/test-strcpy_chk.c: Likewise. * debug/test-stpcpy_chk.c: Likewise. * debug/vsprintf_chk.c (__vsprintf_chk): If flags > 0, request _IO_FLAGS2_CHECK_PERCENT_N. Add libc_hidden_def. * debug/Makefile (routines): Add printf_chk, fprintf_chk, vprintf_chk, vfprintf_chk, gets_chk and readonly-area. (CFLAGS-*_chk.c): Set. (tests): Add tst-chk1, tst-chk2, tst-chk3, test-strcpy_chk and test-stpcpy_chk. * debug/vprintf_chk.c: New file. * debug/printf_chk.c: Likewise. * debug/vfprintf_chk.c: Likewise. * debug/fprintf_chk.c: Likewise. * debug/gets_chk.c: Likewise. * debug/chk_fail.c (__chk_fail): Add libc_hidden_def. * debug/snprintf_chk.c (__snprintf_chk): Fix order of arguments passed to __vsnprintf_chk. * debug/Versions (libc): Export __printf_chk, __fprintf_chk, __vprintf_chk, __vfprintf_chk and __gets_chk @GLIBC_2.3.4. * debug/vsnprintf_chk.c (__vsnprintf_chk): Don't call __vsnprintf, instead create a temporary file with _IO_strn_jumps jumptable. If flags > 0, request _IO_FLAGS2_CHECK_PERCENT_N. Add libc_hidden_def. * libio/Makefile (headers): Add bits/stdio2.h. * libio/stdio.h: Include <bits/stdio2.h> if __USE_FORTIFY_LEVEL. (sprintf, snprintf, vsprintf, vsnprintf): Remove defines. * libio/strfile.h (_IO_strnfile): New type. (_IO_strn_jumps): New extern. * libio/vsnprintf.c (_IO_strnfile): Remove. (_IO_strn_jumps): Remove static. * libio/bits/stdio2.h: New file. * libio/vswprintf.c (_IO_strnfile): Rename type to... (_IO_wstrnfile): ...this. Adjust all uses. * libio/libio.h (_IO_FLAGS2_CHECK_PERCENT_N): Define. * stdio-common/vfprintf.c (STR_LEN): Define. (vfprintf): Add readonly_format variable. Handle _IO_FLAGS2_CHECK_PERCENT_N. (buffered_vfprintf): Copy _flags2. * include/stdio.h (__sprintf_chk, __snprintf_chk, __vsprintf_chk, __vsnprintf_chk, __printf_chk, __fprintf_chk, __vprintf_chk, __vfprintf_chk): New prototypes. (__vsprintf_chk, __vsnprintf_chk): Add libc_hidden_proto. * include/string.h (__memcpy_chk, __memmove_chk, __mempcpy_chk, __memset_chk, __strcpy_chk, __stpcpy_chk, __strncpy_chk, __strcat_chk, __strncat_chk): New prototypes. * include/bits/string3.h: New file. * include/sys/cdefs.h (__chk_fail): Add libc_hidden_proto and rtld_hidden_proto. * string/Makefile (headers): Add bits/string3.h. * string/bits/string3.h (bcopy, bzero): New defines. (memset, memcpy, memmove, strcpy, strncpy, strcat, strncat): Change macros so that inlines are used only if unknown destination size or side-effects in destination argument. (mempcpy, stpcpy): Likewise. Protect with #ifdef __USE_GNU. 2004-09-16 Ulrich Drepper <drepper@redhat.com> * debug/Makefile (routines): Add *_chk. * debug/Versions (libc): Export __chk_fail, __memcpy_chk, __memmove_chk, __mempcpy_chk, __memset_chk, __stpcpy_chk, __strcat_chk, __strcpy_chk, __strncat_chk, __strncpy_chk, __sprintf_chk, __vsprintf_chk, __snprintf_chk, __vsnprintf_chk @GLIBC_2.3.4. * debug/chk_fail.c: New file. * debug/snprintf_chk.c: Likewise. * debug/sprintf_chk.c: Likewise. * debug/vsnprintf_chk.c: Likewise. * debug/vsprintf_chk.c: Likewise. * include/features.h (_FORTIFY_SOURCE): Document, handle. (__USE_FORTIFY_LEVEL): Define. (__GNUC_PREREQ): Move to earlier location. * include/sys/cdefs.h (__chk_fail): New prototype. * libio/bits/stdio.h (sprintf, vsprintf, snprintf, vsnprintf): Define if __USE_FORTIFY_LEVEL. * misc/sys/cdefs.h (__bos, __bos0): Define. * string/string.h: Include <bits/string3.h> if __USE_FORTIFY_LEVEL. * bits/string/string3.h: New header. * sysdeps/generic/memcpy_chk.c: New file. * sysdeps/generic/memmove_chk.c: Likewise. * sysdeps/generic/mempcpy_chk.c: Likewise. * sysdeps/generic/memset_chk.c: Likewise. * sysdeps/generic/stpcpy_chk.c: Likewise. * sysdeps/generic/strcat_chk.c: Likewise. * sysdeps/generic/strcpy_chk.c: Likewise. * sysdeps/generic/strncat_chk.c: Likewise. * sysdeps/generic/strncpy_chk.c: Likewise.
This commit is contained in:
parent
10e0498e2d
commit
b5cc329c4f
119
ChangeLog
119
ChangeLog
@ -1,3 +1,122 @@
|
||||
2004-10-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/dl-minimal.c (__chk_fail): New. Add rtld_hidden_def.
|
||||
* sysdeps/unix/sysv/linux/readonly-area.c: New file.
|
||||
* sysdeps/i386/i686/memmove.S (__memmove_chk): Add checking
|
||||
routine.
|
||||
* sysdeps/i386/i686/memcpy.S (__memcpy_chk): Likewise.
|
||||
* sysdeps/i386/i686/mempcpy.S (__mempcpy_chk): Likewise.
|
||||
* sysdeps/i386/i686/memset.S (__memset_chk): Likewise.
|
||||
* sysdeps/i386/i686/memmove-chk.S: New file.
|
||||
* sysdeps/i386/i686/memcpy-chk.S: Likewise.
|
||||
* sysdeps/i386/i686/mempcpy-chk.S: Likewise.
|
||||
* sysdeps/i386/i686/memset-chk.S: Likewise.
|
||||
* sysdeps/generic/strcat-chk.c (__strcat_chk): Don't __chk_fail
|
||||
if exactly fitting into buffer.
|
||||
* sysdeps/generic/strncat-chk.c (__strncat_chk): Likewise.
|
||||
* sysdeps/generic/readonly-area.c: New file.
|
||||
* sysdeps/generic/strncpy-chk.c (__strncpy_chk): Only test
|
||||
destlen once.
|
||||
* sysdeps/x86_64/memset.S (__memset_chk): Add checking routine.
|
||||
* sysdeps/x86_64/memcpy.S (__memcpy_chk): Likewise.
|
||||
* sysdeps/x86_64/mempcpy.S (__memcpy_chk): Define to __mempcpy_chk.
|
||||
* sysdeps/x86_64/memcpy-chk.S: New file.
|
||||
* sysdeps/x86_64/mempcpy-chk.S: Likewise.
|
||||
* sysdeps/x86_64/memset-chk.S: Likewise.
|
||||
* sysdeps/x86_64/strcpy-chk.S: Likewise.
|
||||
* sysdeps/x86_64/stpcpy-chk.S: Likewise.
|
||||
* argp/argp-xinl.c (__OPTIMIZE__): Define to 1 instead of nothing.
|
||||
* argp/argp-fs-xinl.c (__OPTIMIZE__): Likewise.
|
||||
* debug/tst-chk1.c: New test.
|
||||
* debug/tst-chk2.c: Likewise.
|
||||
* debug/tst-chk3.c: Likewise.
|
||||
* debug/test-strcpy_chk.c: Likewise.
|
||||
* debug/test-stpcpy_chk.c: Likewise.
|
||||
* debug/vsprintf_chk.c (__vsprintf_chk): If flags > 0, request
|
||||
_IO_FLAGS2_CHECK_PERCENT_N. Add libc_hidden_def.
|
||||
* debug/Makefile (routines): Add printf_chk, fprintf_chk, vprintf_chk,
|
||||
vfprintf_chk, gets_chk and readonly-area.
|
||||
(CFLAGS-*_chk.c): Set.
|
||||
(tests): Add tst-chk1, tst-chk2, tst-chk3, test-strcpy_chk and
|
||||
test-stpcpy_chk.
|
||||
* debug/vprintf_chk.c: New file.
|
||||
* debug/printf_chk.c: Likewise.
|
||||
* debug/vfprintf_chk.c: Likewise.
|
||||
* debug/fprintf_chk.c: Likewise.
|
||||
* debug/gets_chk.c: Likewise.
|
||||
* debug/chk_fail.c (__chk_fail): Add libc_hidden_def.
|
||||
* debug/snprintf_chk.c (__snprintf_chk): Fix order of arguments
|
||||
passed to __vsnprintf_chk.
|
||||
* debug/Versions (libc): Export __printf_chk, __fprintf_chk,
|
||||
__vprintf_chk, __vfprintf_chk and __gets_chk @GLIBC_2.3.4.
|
||||
* debug/vsnprintf_chk.c (__vsnprintf_chk): Don't call
|
||||
__vsnprintf, instead create a temporary file with
|
||||
_IO_strn_jumps jumptable. If flags > 0, request
|
||||
_IO_FLAGS2_CHECK_PERCENT_N. Add libc_hidden_def.
|
||||
* libio/Makefile (headers): Add bits/stdio2.h.
|
||||
* libio/stdio.h: Include <bits/stdio2.h> if __USE_FORTIFY_LEVEL.
|
||||
(sprintf, snprintf, vsprintf, vsnprintf): Remove defines.
|
||||
* libio/strfile.h (_IO_strnfile): New type.
|
||||
(_IO_strn_jumps): New extern.
|
||||
* libio/vsnprintf.c (_IO_strnfile): Remove.
|
||||
(_IO_strn_jumps): Remove static.
|
||||
* libio/bits/stdio2.h: New file.
|
||||
* libio/vswprintf.c (_IO_strnfile): Rename type to...
|
||||
(_IO_wstrnfile): ...this. Adjust all uses.
|
||||
* libio/libio.h (_IO_FLAGS2_CHECK_PERCENT_N): Define.
|
||||
* stdio-common/vfprintf.c (STR_LEN): Define.
|
||||
(vfprintf): Add readonly_format variable.
|
||||
Handle _IO_FLAGS2_CHECK_PERCENT_N.
|
||||
(buffered_vfprintf): Copy _flags2.
|
||||
* include/stdio.h (__sprintf_chk, __snprintf_chk, __vsprintf_chk,
|
||||
__vsnprintf_chk, __printf_chk, __fprintf_chk, __vprintf_chk,
|
||||
__vfprintf_chk): New prototypes.
|
||||
(__vsprintf_chk, __vsnprintf_chk): Add libc_hidden_proto.
|
||||
* include/string.h (__memcpy_chk, __memmove_chk, __mempcpy_chk,
|
||||
__memset_chk, __strcpy_chk, __stpcpy_chk, __strncpy_chk, __strcat_chk,
|
||||
__strncat_chk): New prototypes.
|
||||
* include/bits/string3.h: New file.
|
||||
* include/sys/cdefs.h (__chk_fail): Add libc_hidden_proto
|
||||
and rtld_hidden_proto.
|
||||
* string/Makefile (headers): Add bits/string3.h.
|
||||
* string/bits/string3.h (bcopy, bzero): New defines.
|
||||
(memset, memcpy, memmove, strcpy, strncpy, strcat, strncat): Change
|
||||
macros so that inlines are used only if unknown destination size
|
||||
or side-effects in destination argument.
|
||||
(mempcpy, stpcpy): Likewise. Protect with #ifdef __USE_GNU.
|
||||
|
||||
2004-09-16 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* debug/Makefile (routines): Add *_chk.
|
||||
* debug/Versions (libc): Export __chk_fail, __memcpy_chk,
|
||||
__memmove_chk, __mempcpy_chk, __memset_chk, __stpcpy_chk,
|
||||
__strcat_chk, __strcpy_chk, __strncat_chk, __strncpy_chk,
|
||||
__sprintf_chk, __vsprintf_chk, __snprintf_chk, __vsnprintf_chk
|
||||
@GLIBC_2.3.4.
|
||||
* debug/chk_fail.c: New file.
|
||||
* debug/snprintf_chk.c: Likewise.
|
||||
* debug/sprintf_chk.c: Likewise.
|
||||
* debug/vsnprintf_chk.c: Likewise.
|
||||
* debug/vsprintf_chk.c: Likewise.
|
||||
* include/features.h (_FORTIFY_SOURCE): Document, handle.
|
||||
(__USE_FORTIFY_LEVEL): Define.
|
||||
(__GNUC_PREREQ): Move to earlier location.
|
||||
* include/sys/cdefs.h (__chk_fail): New prototype.
|
||||
* libio/bits/stdio.h (sprintf, vsprintf, snprintf, vsnprintf):
|
||||
Define if __USE_FORTIFY_LEVEL.
|
||||
* misc/sys/cdefs.h (__bos, __bos0): Define.
|
||||
* string/string.h: Include <bits/string3.h> if __USE_FORTIFY_LEVEL.
|
||||
* bits/string/string3.h: New header.
|
||||
* sysdeps/generic/memcpy_chk.c: New file.
|
||||
* sysdeps/generic/memmove_chk.c: Likewise.
|
||||
* sysdeps/generic/mempcpy_chk.c: Likewise.
|
||||
* sysdeps/generic/memset_chk.c: Likewise.
|
||||
* sysdeps/generic/stpcpy_chk.c: Likewise.
|
||||
* sysdeps/generic/strcat_chk.c: Likewise.
|
||||
* sysdeps/generic/strcpy_chk.c: Likewise.
|
||||
* sysdeps/generic/strncat_chk.c: Likewise.
|
||||
* sysdeps/generic/strncpy_chk.c: Likewise.
|
||||
|
||||
2004-10-17 Roland McGrath <roland@frob.com>
|
||||
|
||||
* manual/memory.texi (Page Lock Functions): Typo fix.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Real definitions for extern inline functions in argp-fmtstream.h
|
||||
Copyright (C) 1997, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
#define ARGP_FS_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__
|
||||
#define __OPTIMIZE__ 1
|
||||
#include "argp-fmtstream.h"
|
||||
|
||||
#if 0
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Real definitions for extern inline functions in argp.h
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#endif
|
||||
#define ARGP_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__
|
||||
#define __OPTIMIZE__ 1
|
||||
#include "argp.h"
|
||||
|
||||
/* Add weak aliases. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1998, 1999, 2000, 2001, 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
|
||||
@ -24,11 +24,26 @@ subdir := debug
|
||||
headers := execinfo.h
|
||||
distribute = sigcontextinfo.h register-dump.h frame.h
|
||||
|
||||
routines := backtrace backtracesyms backtracesymsfd noophooks
|
||||
routines := backtrace backtracesyms backtracesymsfd noophooks \
|
||||
memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
|
||||
strcat_chk strcpy_chk strncat_chk strncpy_chk \
|
||||
sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
|
||||
printf_chk fprintf_chk vprintf_chk vfprintf_chk \
|
||||
gets_chk chk_fail readonly-area
|
||||
|
||||
CFLAGS-backtrace.c = -fno-omit-frame-pointer
|
||||
CFLAGS-sprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-snprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-vsprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-vsnprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-printf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-fprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-vprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
|
||||
tests = backtrace-tst
|
||||
tests = backtrace-tst tst-chk1 tst-chk2 tst-chk3 \
|
||||
test-strcpy_chk test-stpcpy_chk
|
||||
|
||||
extra-libs = libSegFault libpcprofile
|
||||
extra-libs-others = $(extra-libs)
|
||||
|
@ -10,4 +10,12 @@ libc {
|
||||
# These are to support some gcc features.
|
||||
__cyg_profile_func_enter; __cyg_profile_func_exit;
|
||||
}
|
||||
GLIBC_2.3.4 {
|
||||
__chk_fail;
|
||||
__memcpy_chk; __memmove_chk; __mempcpy_chk; __memset_chk; __stpcpy_chk;
|
||||
__strcat_chk; __strcpy_chk; __strncat_chk; __strncpy_chk;
|
||||
__sprintf_chk; __vsprintf_chk; __snprintf_chk; __vsnprintf_chk;
|
||||
__printf_chk; __fprintf_chk; __vprintf_chk; __vfprintf_chk;
|
||||
__gets_chk;
|
||||
}
|
||||
}
|
||||
|
38
debug/chk_fail.c
Normal file
38
debug/chk_fail.c
Normal file
@ -0,0 +1,38 @@
|
||||
/* 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. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <abort-instr.h>
|
||||
|
||||
|
||||
void
|
||||
__attribute__ ((noreturn))
|
||||
__chk_fail (void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
/* This will leave a nice backtrace. */
|
||||
abort ();
|
||||
#ifdef ABORT_INSTRUCTION
|
||||
ABORT_INSTRUCTION;
|
||||
#endif
|
||||
_exit (127);
|
||||
}
|
||||
}
|
||||
libc_hidden_def (__chk_fail)
|
45
debug/fprintf_chk.c
Normal file
45
debug/fprintf_chk.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
|
||||
/* Write formatted output to FP from the format string FORMAT. */
|
||||
int
|
||||
__fprintf_chk (FILE *fp, int flag, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int done;
|
||||
|
||||
_IO_acquire_lock (fp);
|
||||
if (flag > 0)
|
||||
fp->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
|
||||
|
||||
va_start (ap, format);
|
||||
done = vfprintf (fp, format, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (flag > 0)
|
||||
fp->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
|
||||
_IO_release_lock (fp);
|
||||
|
||||
return done;
|
||||
}
|
77
debug/gets_chk.c
Normal file
77
debug/gets_chk.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* Copyright (C) 1993, 1996, 1997, 1998, 2002, 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.
|
||||
|
||||
As a special exception, if you link the code in this file with
|
||||
files compiled with a GNU compiler to produce an executable,
|
||||
that does not cause the resulting executable to be covered by
|
||||
the GNU Lesser General Public License. This exception does not
|
||||
however invalidate any other reasons why the executable file
|
||||
might be covered by the GNU Lesser General Public License.
|
||||
This exception applies to code released by its copyright holders
|
||||
in files containing the exception. */
|
||||
|
||||
#include "../libio/libioP.h"
|
||||
#include <limits.h>
|
||||
|
||||
char *
|
||||
__gets_chk (char *buf, size_t size)
|
||||
{
|
||||
_IO_size_t count;
|
||||
int ch;
|
||||
char *retval;
|
||||
|
||||
if (size == 0)
|
||||
__chk_fail ();
|
||||
|
||||
_IO_acquire_lock (_IO_stdin);
|
||||
ch = _IO_getc_unlocked (_IO_stdin);
|
||||
if (ch == EOF)
|
||||
{
|
||||
retval = NULL;
|
||||
goto unlock_return;
|
||||
}
|
||||
if (ch == '\n')
|
||||
count = 0;
|
||||
else
|
||||
{
|
||||
/* This is very tricky since a file descriptor may be in the
|
||||
non-blocking mode. The error flag doesn't mean much in this
|
||||
case. We return an error only when there is a new error. */
|
||||
int old_error = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN;
|
||||
_IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN;
|
||||
buf[0] = (char) ch;
|
||||
count = INTUSE(_IO_getline) (_IO_stdin, buf + 1, size - 1, '\n', 0) + 1;
|
||||
if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN)
|
||||
{
|
||||
retval = NULL;
|
||||
goto unlock_return;
|
||||
}
|
||||
else
|
||||
_IO_stdin->_IO_file_flags |= old_error;
|
||||
}
|
||||
if (count >= size)
|
||||
__chk_fail ();
|
||||
buf[count] = 0;
|
||||
retval = buf;
|
||||
unlock_return:
|
||||
_IO_release_lock (_IO_stdin);
|
||||
return retval;
|
||||
}
|
||||
|
||||
link_warning (__gets_chk, "the `gets' function is dangerous and should not be used.")
|
45
debug/printf_chk.c
Normal file
45
debug/printf_chk.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
|
||||
/* Write formatted output to stdout from the format string FORMAT. */
|
||||
int
|
||||
__printf_chk (int flag, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int done;
|
||||
|
||||
_IO_acquire_lock (stdout);
|
||||
if (flag > 0)
|
||||
stdout->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
|
||||
|
||||
va_start (ap, format);
|
||||
done = vfprintf (stdout, format, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (flag > 0)
|
||||
stdout->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
|
||||
_IO_release_lock (stdout);
|
||||
|
||||
return done;
|
||||
}
|
38
debug/snprintf_chk.c
Normal file
38
debug/snprintf_chk.c
Normal file
@ -0,0 +1,38 @@
|
||||
/* Copyright (C) 1991, 1995, 1997, 1998, 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Write formatted output into S, according to the format
|
||||
string FORMAT, writing no more than MAXLEN characters. */
|
||||
/* VARARGS5 */
|
||||
int
|
||||
__snprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int done;
|
||||
|
||||
va_start (arg, format);
|
||||
done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg);
|
||||
va_end (arg);
|
||||
|
||||
return done;
|
||||
}
|
35
debug/sprintf_chk.c
Normal file
35
debug/sprintf_chk.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 1991,1995,1997,1998,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. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Write formatted output into S, according to the format string FORMAT. */
|
||||
/* VARARGS4 */
|
||||
int
|
||||
__sprintf_chk (char *s, int flags, size_t slen, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int done;
|
||||
|
||||
va_start (arg, format);
|
||||
done = __vsprintf_chk (s, flags, slen, format, arg);
|
||||
va_end (arg);
|
||||
|
||||
return done;
|
||||
}
|
46
debug/test-stpcpy_chk.c
Normal file
46
debug/test-stpcpy_chk.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Test and measure stpcpy checking functions.
|
||||
Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
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. */
|
||||
|
||||
#define STRCPY_RESULT(dst, len) ((dst) + (len))
|
||||
#define TEST_MAIN
|
||||
#include "../string/test-string.h"
|
||||
|
||||
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||
char *simple_stpcpy_chk (char *, const char *, size_t);
|
||||
extern char *normal_stpcpy (char *, const char *, size_t)
|
||||
__asm ("stpcpy");
|
||||
extern char *__stpcpy_chk (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_stpcpy_chk, 0)
|
||||
IMPL (normal_stpcpy, 1)
|
||||
IMPL (__stpcpy_chk, 2)
|
||||
|
||||
char *
|
||||
simple_stpcpy_chk (char *dst, const char *src, size_t len)
|
||||
{
|
||||
if (! len)
|
||||
__chk_fail ();
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
if (--len == 0)
|
||||
__chk_fail ();
|
||||
return dst - 1;
|
||||
}
|
||||
|
||||
#include "test-strcpy_chk.c"
|
370
debug/test-strcpy_chk.c
Normal file
370
debug/test-strcpy_chk.c
Normal file
@ -0,0 +1,370 @@
|
||||
/* Test and measure __strcpy_chk functions.
|
||||
Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef STRCPY_RESULT
|
||||
# define STRCPY_RESULT(dst, len) dst
|
||||
# define TEST_MAIN
|
||||
# include "../string/test-string.h"
|
||||
|
||||
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||
char *simple_strcpy_chk (char *, const char *, size_t);
|
||||
extern char *normal_strcpy (char *, const char *, size_t)
|
||||
__asm ("strcpy");
|
||||
extern char *__strcpy_chk (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_strcpy_chk, 0)
|
||||
IMPL (normal_strcpy, 1)
|
||||
IMPL (__strcpy_chk, 2)
|
||||
|
||||
char *
|
||||
simple_strcpy_chk (char *dst, const char *src, size_t len)
|
||||
{
|
||||
char *ret = dst;
|
||||
if (! len)
|
||||
__chk_fail ();
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
if (--len == 0)
|
||||
__chk_fail ();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
volatile int chk_fail_ok;
|
||||
jmp_buf chk_fail_buf;
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
if (chk_fail_ok)
|
||||
{
|
||||
chk_fail_ok = 0;
|
||||
longjmp (chk_fail_buf, 1);
|
||||
}
|
||||
else
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
size_t len, size_t dlen)
|
||||
{
|
||||
char *res;
|
||||
if (dlen <= len)
|
||||
{
|
||||
if (impl->test == 1)
|
||||
return;
|
||||
|
||||
chk_fail_ok = 1;
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
error (0, 0, "Function %s (%zd; %zd) did not __chk_fail",
|
||||
impl->name, len, dlen);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
|
||||
if (res != STRCPY_RESULT (dst, len))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, STRCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (dst, src) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));;
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, dlen);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL && dlen > len)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len, dlen);
|
||||
|
||||
if (HP_TIMING_AVAIL && dlen > len)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
do_random_tests (void)
|
||||
{
|
||||
size_t i, j, n, align1, align2, len, dlen;
|
||||
unsigned char *p1 = buf1 + page_size - 512;
|
||||
unsigned char *p2 = buf2 + page_size - 512;
|
||||
unsigned char *res;
|
||||
|
||||
for (n = 0; n < ITERATIONS; n++)
|
||||
{
|
||||
align1 = random () & 31;
|
||||
if (random () & 1)
|
||||
align2 = random () & 31;
|
||||
else
|
||||
align2 = align1 + (random () & 24);
|
||||
len = random () & 511;
|
||||
j = align1;
|
||||
if (align2 > j)
|
||||
j = align2;
|
||||
if (len + j >= 511)
|
||||
len = 510 - j - (random () & 7);
|
||||
j = len + align1 + 64;
|
||||
if (j > 512)
|
||||
j = 512;
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (i == len + align1)
|
||||
p1[i] = 0;
|
||||
else
|
||||
{
|
||||
p1[i] = random () & 255;
|
||||
if (i >= align1 && i < len + align1 && !p1[i])
|
||||
p1[i] = (random () & 127) + 3;
|
||||
}
|
||||
}
|
||||
|
||||
switch (random () & 7)
|
||||
{
|
||||
case 0:
|
||||
dlen = len - (random () & 31);
|
||||
if (dlen > len)
|
||||
dlen = len;
|
||||
break;
|
||||
case 1:
|
||||
dlen = (size_t) -1;
|
||||
break;
|
||||
case 2:
|
||||
dlen = len + 1 + (random () & 65535);
|
||||
break;
|
||||
case 3:
|
||||
dlen = len + 1 + (random () & 255);
|
||||
break;
|
||||
case 4:
|
||||
dlen = len + 1 + (random () & 31);
|
||||
break;
|
||||
case 5:
|
||||
dlen = len + 1 + (random () & 7);
|
||||
break;
|
||||
case 6:
|
||||
dlen = len + 1 + (random () & 3);
|
||||
break;
|
||||
default:
|
||||
dlen = len + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
if (dlen <= len)
|
||||
{
|
||||
if (impl->test != 1)
|
||||
{
|
||||
chk_fail_ok = 1;
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, p2 + align2, p1 + align1, dlen);
|
||||
error (0, 0, "Iteration %zd - did not __chk_fail", n);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
memset (p2 - 64, '\1', 512 + 64);
|
||||
res = CALL (impl, p2 + align2, p1 + align1, dlen);
|
||||
if (res != STRCPY_RESULT (p2 + align2, len))
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
|
||||
n, impl->name, align1, align2, len, res,
|
||||
STRCPY_RESULT (p2 + align2, len));
|
||||
ret = 1;
|
||||
}
|
||||
for (j = 0; j < align2 + 64; ++j)
|
||||
{
|
||||
if (p2[j - 64] != '\1')
|
||||
{
|
||||
error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j = align2 + len + 1; j < 512; ++j)
|
||||
{
|
||||
if (p2[j] != '\1')
|
||||
{
|
||||
error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memcmp (p1 + align1, p2 + align2, len + 1))
|
||||
{
|
||||
error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i + 1, 127);
|
||||
do_test (0, 0, i, i + 1, 255);
|
||||
do_test (0, i, i, i + 1, 127);
|
||||
do_test (i, 0, i, i + 1, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) + 1, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + 1, 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + 1, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + 1, 255);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i + 256, 127);
|
||||
do_test (0, 0, i, i + 256, 255);
|
||||
do_test (0, i, i, i + 256, 127);
|
||||
do_test (i, 0, i, i + 256, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) + 256, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + 256, 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + 256, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + 256, 255);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i, 127);
|
||||
do_test (0, 0, i, i + 2, 255);
|
||||
do_test (0, i, i, i + 3, 127);
|
||||
do_test (i, 0, i, i + 4, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) - 15, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + i, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + i + 2, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + i + 3, 255);
|
||||
}
|
||||
|
||||
do_random_tests ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
466
debug/tst-chk1.c
Normal file
466
debug/tst-chk1.c
Normal file
@ -0,0 +1,466 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
|
||||
|
||||
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 <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char *temp_filename;
|
||||
static void do_prepare (void);
|
||||
static int do_test (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static void
|
||||
do_prepare (void)
|
||||
{
|
||||
int temp_fd = create_temp_file ("tst-chk1.", &temp_filename);
|
||||
if (temp_fd == -1)
|
||||
{
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
|
||||
if (write (temp_fd, strs, strlen (strs)) != strlen (strs))
|
||||
{
|
||||
puts ("could not write test strings into file");
|
||||
unlink (temp_filename);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
volatile int chk_fail_ok;
|
||||
jmp_buf chk_fail_buf;
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
if (chk_fail_ok)
|
||||
{
|
||||
chk_fail_ok = 0;
|
||||
longjmp (chk_fail_buf, 1);
|
||||
}
|
||||
else
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
char buf[10];
|
||||
volatile size_t l0;
|
||||
volatile char *p;
|
||||
const char *str1 = "JIHGFEDCBA";
|
||||
const char *str2 = "F";
|
||||
const char *str3 = "%s%n%s%n";
|
||||
const char *str4 = "Hello, ";
|
||||
const char *str5 = "World!\n";
|
||||
char buf2[10] = "%s";
|
||||
int num1 = 67;
|
||||
int num2 = 987654;
|
||||
|
||||
#define FAIL() \
|
||||
do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
|
||||
#define CHK_FAIL_START \
|
||||
chk_fail_ok = 1; \
|
||||
if (! setjmp (chk_fail_buf)) \
|
||||
{
|
||||
#define CHK_FAIL_END \
|
||||
chk_fail_ok = 0; \
|
||||
FAIL (); \
|
||||
ret = 1; \
|
||||
}
|
||||
#if __USE_FORTIFY_LEVEL >= 2
|
||||
#define CHK_FAIL2_START CHK_FAIL_START
|
||||
#define CHK_FAIL2_END CHK_FAIL_END
|
||||
#else
|
||||
#define CHK_FAIL2_START
|
||||
#define CHK_FAIL2_END
|
||||
#endif
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
struct A { char buf1[9]; char buf2[1]; } a;
|
||||
|
||||
printf ("Test checking routines at fortify level %d\n",
|
||||
#ifdef __USE_FORTIFY_LEVEL
|
||||
(int) __USE_FORTIFY_LEVEL
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
|
||||
/* These ops can be done without runtime checking of object size. */
|
||||
memcpy (buf, "abcdefghij", 10);
|
||||
memmove (buf + 1, buf, 9);
|
||||
if (memcmp (buf, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
memset (buf + 8, 'j', 2);
|
||||
if (memcmp (buf, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf + 4, "EDCBA");
|
||||
if (memcmp (buf, "aabcEDCBA", 10))
|
||||
FAIL ();
|
||||
|
||||
if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
|
||||
FAIL ();
|
||||
|
||||
strncpy (buf + 6, "X", 4);
|
||||
if (memcmp (buf, "aabcEDX\0\0", 10))
|
||||
FAIL ();
|
||||
|
||||
if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10))
|
||||
FAIL ();
|
||||
|
||||
if (snprintf (buf + 7, 3, "%s", "987654") != 6
|
||||
|| memcmp (buf, "aabcEDX98", 10))
|
||||
FAIL ();
|
||||
|
||||
/* These ops need runtime checking, but shouldn't __chk_fail. */
|
||||
memcpy (buf, "abcdefghij", l0 + 10);
|
||||
memmove (buf + 1, buf, l0 + 9);
|
||||
if (memcmp (buf, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
memset (buf + 8, 'j', l0 + 2);
|
||||
if (memcmp (buf, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf + 4, str1 + 5);
|
||||
if (memcmp (buf, "aabcEDCBA", 10))
|
||||
FAIL ();
|
||||
|
||||
if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
|
||||
FAIL ();
|
||||
|
||||
strncpy (buf + 6, "X", l0 + 4);
|
||||
if (memcmp (buf, "aabcEDX\0\0", 10))
|
||||
FAIL ();
|
||||
|
||||
if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEDX67", 10))
|
||||
FAIL ();
|
||||
|
||||
if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10))
|
||||
FAIL ();
|
||||
|
||||
buf[l0 + 8] = '\0';
|
||||
strcat (buf, "A");
|
||||
if (memcmp (buf, "aabcEDX9A", 10))
|
||||
FAIL ();
|
||||
|
||||
buf[l0 + 7] = '\0';
|
||||
strncat (buf, "ZYXWV", l0 + 2);
|
||||
if (memcmp (buf, "aabcEDXZY", 10))
|
||||
FAIL ();
|
||||
|
||||
memcpy (a.buf1, "abcdefghij", l0 + 10);
|
||||
memmove (a.buf1 + 1, a.buf1, l0 + 9);
|
||||
if (memcmp (a.buf1, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
|
||||
|| memcmp (a.buf1, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
memset (a.buf1 + 8, 'j', l0 + 2);
|
||||
if (memcmp (a.buf1, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL < 2
|
||||
/* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
|
||||
and sufficient GCC support, as the string operations overflow
|
||||
from a.buf1 into a.buf2. */
|
||||
strcpy (a.buf1 + 4, str1 + 5);
|
||||
if (memcmp (a.buf1, "aabcEDCBA", 10))
|
||||
FAIL ();
|
||||
|
||||
if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10))
|
||||
FAIL ();
|
||||
|
||||
strncpy (a.buf1 + 6, "X", l0 + 4);
|
||||
if (memcmp (a.buf1, "aabcEDX\0\0", 10))
|
||||
FAIL ();
|
||||
|
||||
if (sprintf (a.buf1 + 7, "%d", num1) != 2 || memcmp (a.buf1, "aabcEDX67", 10))
|
||||
FAIL ();
|
||||
|
||||
if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
|
||||
|| memcmp (a.buf1, "aabcEDX98", 10))
|
||||
FAIL ();
|
||||
|
||||
a.buf1[l0 + 8] = '\0';
|
||||
strcat (a.buf1, "A");
|
||||
if (memcmp (a.buf1, "aabcEDX9A", 10))
|
||||
FAIL ();
|
||||
|
||||
a.buf1[l0 + 7] = '\0';
|
||||
strncat (a.buf1, "ZYXWV", l0 + 2);
|
||||
if (memcmp (a.buf1, "aabcEDXZY", 10))
|
||||
FAIL ();
|
||||
|
||||
#endif
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
/* Now check if all buffer overflows are caught at runtime. */
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (buf + 1, "abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (buf + 2, buf + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = mempcpy (buf + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (buf + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strcpy (buf + 5, str1 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = stpcpy (buf + 9, str2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (buf + 7, "X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
sprintf (buf + 8, "%d", num1);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (buf + 8, l0 + 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (buf, str1 + 2, l0 + 9);
|
||||
CHK_FAIL_START
|
||||
strcat (buf, "AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (buf, str1 + 3, l0 + 8);
|
||||
CHK_FAIL_START
|
||||
strncat (buf, "ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (a.buf1 + 1, "abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = mempcpy (a.buf1 + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (a.buf1 + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 2
|
||||
# define O 0
|
||||
#else
|
||||
# define O 1
|
||||
#endif
|
||||
|
||||
CHK_FAIL_START
|
||||
strcpy (a.buf1 + (O + 4), str1 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = stpcpy (a.buf1 + (O + 8), str2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (a.buf1 + (O + 6), "X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
sprintf (a.buf1 + (O + 7), "%d", num1);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
|
||||
CHK_FAIL_START
|
||||
strcat (a.buf1, "AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O);
|
||||
CHK_FAIL_START
|
||||
strncat (a.buf1, "ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
/* Now checks for %n protection. */
|
||||
|
||||
/* Constant literals passed directly are always ok
|
||||
(even with warnings about possible bugs from GCC). */
|
||||
int n1, n2;
|
||||
if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2
|
||||
|| n1 != 1 || n2 != 2)
|
||||
FAIL ();
|
||||
|
||||
/* In this case the format string is not known at compile time,
|
||||
but resides in read-only memory, so is ok. */
|
||||
if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2
|
||||
|| n1 != 1 || n2 != 2)
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
|
||||
CHK_FAIL2_START
|
||||
if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
CHK_FAIL2_START
|
||||
if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
/* But if there is no %n, even writable format string
|
||||
should work. */
|
||||
buf2[6] = '\0';
|
||||
if (sprintf (buf, buf2 + 4, str2) != 1)
|
||||
FAIL ();
|
||||
|
||||
/* Constant literals passed directly are always ok
|
||||
(even with warnings about possible bugs from GCC). */
|
||||
if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
/* In this case the format string is not known at compile time,
|
||||
but resides in read-only memory, so is ok. */
|
||||
if (printf (str3, str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
|
||||
CHK_FAIL2_START
|
||||
if (printf (buf2, str4, &n1, str5, &n1) != 14)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
/* But if there is no %n, even writable format string
|
||||
should work. */
|
||||
buf2[6] = '\0';
|
||||
if (printf (buf2 + 4, str5) != 7)
|
||||
FAIL ();
|
||||
|
||||
FILE *fp = stdout;
|
||||
|
||||
/* Constant literals passed directly are always ok
|
||||
(even with warnings about possible bugs from GCC). */
|
||||
if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
/* In this case the format string is not known at compile time,
|
||||
but resides in read-only memory, so is ok. */
|
||||
if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
|
||||
CHK_FAIL2_START
|
||||
if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
/* But if there is no %n, even writable format string
|
||||
should work. */
|
||||
buf2[6] = '\0';
|
||||
if (fprintf (fp, buf2 + 4, str5) != 7)
|
||||
FAIL ();
|
||||
|
||||
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||
{
|
||||
puts ("could not open temporary file");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
|
||||
FAIL ();
|
||||
if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
if (gets (buf) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||
{
|
||||
puts ("could not open temporary file");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (fseek (stdin, 9 + 10 + 11, SEEK_SET))
|
||||
{
|
||||
puts ("could not seek in test file");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
if (gets (buf) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
2
debug/tst-chk2.c
Normal file
2
debug/tst-chk2.c
Normal file
@ -0,0 +1,2 @@
|
||||
#define _FORTIFY_SOURCE 1
|
||||
#include "tst-chk1.c"
|
2
debug/tst-chk3.c
Normal file
2
debug/tst-chk3.c
Normal file
@ -0,0 +1,2 @@
|
||||
#define _FORTIFY_SOURCE 2
|
||||
#include "tst-chk1.c"
|
42
debug/vfprintf_chk.c
Normal file
42
debug/vfprintf_chk.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
|
||||
/* Write formatted output to FP from the format string FORMAT. */
|
||||
int
|
||||
__vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap)
|
||||
{
|
||||
int done;
|
||||
|
||||
_IO_acquire_lock (fp);
|
||||
if (flag > 0)
|
||||
fp->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
|
||||
|
||||
done = vfprintf (fp, format, ap);
|
||||
|
||||
if (flag > 0)
|
||||
fp->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
|
||||
_IO_release_lock (fp);
|
||||
|
||||
return done;
|
||||
}
|
42
debug/vprintf_chk.c
Normal file
42
debug/vprintf_chk.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
|
||||
/* Write formatted output to stdout from the format string FORMAT. */
|
||||
int
|
||||
__vprintf_chk (int flag, const char *format, va_list ap)
|
||||
{
|
||||
int done;
|
||||
|
||||
_IO_acquire_lock (stdout);
|
||||
if (flag > 0)
|
||||
stdout->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
|
||||
|
||||
done = vfprintf (stdout, format, ap);
|
||||
|
||||
if (flag > 0)
|
||||
stdout->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
|
||||
_IO_release_lock (stdout);
|
||||
|
||||
return done;
|
||||
}
|
70
debug/vsnprintf_chk.c
Normal file
70
debug/vsnprintf_chk.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 1991, 1995, 1997, 1998, 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
#include "../libio/strfile.h"
|
||||
|
||||
extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
|
||||
|
||||
/* Write formatted output into S, according to the format
|
||||
string FORMAT, writing no more than MAXLEN characters. */
|
||||
/* VARARGS5 */
|
||||
int
|
||||
__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
|
||||
const char *format, va_list args)
|
||||
{
|
||||
/* XXX Maybe for less strict version do not fail immediately.
|
||||
Though, maxlen is supposed to be the size of buffer pointed
|
||||
to by s, so a conforming program can't pass such maxlen
|
||||
to *snprintf. */
|
||||
if (__builtin_expect (slen < maxlen, 0))
|
||||
__chk_fail ();
|
||||
|
||||
_IO_strnfile sf;
|
||||
int ret;
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
sf.f._sbf._f._lock = NULL;
|
||||
#endif
|
||||
|
||||
/* We need to handle the special case where MAXLEN is 0. Use the
|
||||
overflow buffer right from the start. */
|
||||
if (maxlen == 0)
|
||||
{
|
||||
s = sf.overflow_buf;
|
||||
maxlen = sizeof (sf.overflow_buf);
|
||||
}
|
||||
|
||||
_IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
|
||||
_IO_JUMPS ((struct _IO_FILE_plus *) &sf.f._sbf) = &_IO_strn_jumps;
|
||||
s[0] = '\0';
|
||||
|
||||
/* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
|
||||
can only come from read-only format strings. */
|
||||
if (flags > 0)
|
||||
sf.f._sbf._f._flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
|
||||
|
||||
_IO_str_init_static_internal (&sf.f, s, maxlen - 1, s);
|
||||
ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf.f._sbf, format, args);
|
||||
|
||||
if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
|
||||
*sf.f._sbf._f._IO_write_ptr = '\0';
|
||||
return ret;
|
||||
}
|
||||
libc_hidden_def (__vsnprintf_chk)
|
91
debug/vsprintf_chk.c
Normal file
91
debug/vsprintf_chk.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* Copyright (C) 1994, 1997, 1999-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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
#include "../libio/strfile.h"
|
||||
|
||||
|
||||
static int _IO_str_chk_overflow (_IO_FILE *fp, int c) __THROW;
|
||||
|
||||
static int
|
||||
_IO_str_chk_overflow (fp, c)
|
||||
_IO_FILE *fp;
|
||||
int c;
|
||||
{
|
||||
/* When we come to here this means the user supplied buffer is
|
||||
filled. */
|
||||
__chk_fail ();
|
||||
}
|
||||
|
||||
|
||||
static const struct _IO_jump_t _IO_str_chk_jumps =
|
||||
{
|
||||
JUMP_INIT_DUMMY,
|
||||
JUMP_INIT(finish, _IO_str_finish),
|
||||
JUMP_INIT(overflow, _IO_str_chk_overflow),
|
||||
JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
|
||||
JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
|
||||
JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
|
||||
JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
|
||||
JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
|
||||
JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
|
||||
JUMP_INIT(seekpos, _IO_default_seekpos),
|
||||
JUMP_INIT(setbuf, _IO_default_setbuf),
|
||||
JUMP_INIT(sync, _IO_default_sync),
|
||||
JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
|
||||
JUMP_INIT(read, _IO_default_read),
|
||||
JUMP_INIT(write, _IO_default_write),
|
||||
JUMP_INIT(seek, _IO_default_seek),
|
||||
JUMP_INIT(close, _IO_default_close),
|
||||
JUMP_INIT(stat, _IO_default_stat),
|
||||
JUMP_INIT(showmanyc, _IO_default_showmanyc),
|
||||
JUMP_INIT(imbue, _IO_default_imbue)
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
__vsprintf_chk (char *s, int flags, size_t slen, const char *format,
|
||||
va_list args)
|
||||
{
|
||||
_IO_strfile f;
|
||||
int ret;
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
f._sbf._f._lock = NULL;
|
||||
#endif
|
||||
|
||||
if (slen == 0)
|
||||
__chk_fail ();
|
||||
|
||||
_IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
|
||||
_IO_JUMPS ((struct _IO_FILE_plus *) &f._sbf) = &_IO_str_chk_jumps;
|
||||
s[0] = '\0';
|
||||
_IO_str_init_static_internal (&f, s, slen - 1, s);
|
||||
|
||||
/* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
|
||||
can only come from read-only format strings. */
|
||||
if (flags > 0)
|
||||
f._sbf._f._flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
|
||||
|
||||
ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &f._sbf, format, args);
|
||||
|
||||
*f._sbf._f._IO_write_ptr = '\0';
|
||||
return ret;
|
||||
}
|
||||
libc_hidden_def (__vsprintf_chk)
|
@ -354,6 +354,13 @@ __strsep (char **stringp, const char *delim)
|
||||
weak_alias (__strsep, strsep)
|
||||
strong_alias (__strsep, __strsep_g)
|
||||
|
||||
void
|
||||
__attribute__ ((noreturn))
|
||||
__chk_fail (void)
|
||||
{
|
||||
_exit (127);
|
||||
}
|
||||
rtld_hidden_def (__chk_fail)
|
||||
|
||||
/* The '_itoa_lower_digits' variable in libc.so is able to handle bases
|
||||
up to 36. We don't need this here. */
|
||||
|
1
include/bits/string3.h
Normal file
1
include/bits/string3.h
Normal file
@ -0,0 +1 @@
|
||||
#include <string/bits/string3.h>
|
@ -41,6 +41,8 @@
|
||||
_GNU_SOURCE All of the above, plus GNU extensions.
|
||||
_REENTRANT Select additionally reentrant object.
|
||||
_THREAD_SAFE Same as _REENTRANT, often used by other systems.
|
||||
_FORTIFY_SOURCE If set to numeric value > 0 additional security
|
||||
measures are defined, according to level.
|
||||
|
||||
The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__.
|
||||
If none of these are defined, the default is to have _SVID_SOURCE,
|
||||
@ -69,6 +71,7 @@
|
||||
__USE_MISC Define things common to BSD and System V Unix.
|
||||
__USE_GNU Define GNU extensions.
|
||||
__USE_REENTRANT Define reentrant/thread-safe *_r functions.
|
||||
__USE_FORTIFY_LEVEL Additional security measures used, according to level.
|
||||
__FAVOR_BSD Favor 4.3BSD things in cases of conflict.
|
||||
|
||||
The macros `__GNU_LIBRARY__', `__GLIBC__', and `__GLIBC_MINOR__' are
|
||||
@ -101,6 +104,7 @@
|
||||
#undef __USE_MISC
|
||||
#undef __USE_GNU
|
||||
#undef __USE_REENTRANT
|
||||
#undef __USE_FORTIFY_LEVEL
|
||||
#undef __FAVOR_BSD
|
||||
#undef __KERNEL_STRICT_NAMES
|
||||
|
||||
@ -113,6 +117,20 @@
|
||||
/* Always use ISO C things. */
|
||||
#define __USE_ANSI 1
|
||||
|
||||
/* Convenience macros to test the versions of glibc and gcc.
|
||||
Use them like this:
|
||||
#if __GNUC_PREREQ (2,8)
|
||||
... code requiring gcc 2.8 or later ...
|
||||
#endif
|
||||
Note - they won't work for gcc1 or glibc1, since the _MINOR macros
|
||||
were not defined then. */
|
||||
#if defined __GNUC__ && defined __GNUC_MINOR__
|
||||
# define __GNUC_PREREQ(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#else
|
||||
# define __GNUC_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
|
||||
/* If _BSD_SOURCE was defined by the user, favor BSD over POSIX. */
|
||||
#if defined _BSD_SOURCE && \
|
||||
@ -244,6 +262,14 @@
|
||||
# define __USE_REENTRANT 1
|
||||
#endif
|
||||
|
||||
#if _FORTIFY_SOURCE > 0 && __GNUC_PREREQ (4, 1) && __OPTIMIZE__ > 0
|
||||
# if _FORTIFY_SOURCE == 1
|
||||
# define __USE_FORTIFY_LEVEL 1
|
||||
# elif _FORTIFY_SOURCE > 1
|
||||
# define __USE_FORTIFY_LEVEL 2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We do support the IEC 559 math functionality, real and complex. */
|
||||
#define __STDC_IEC_559__ 1
|
||||
#define __STDC_IEC_559_COMPLEX__ 1
|
||||
@ -265,20 +291,6 @@
|
||||
#define __GLIBC__ 2
|
||||
#define __GLIBC_MINOR__ 3
|
||||
|
||||
/* Convenience macros to test the versions of glibc and gcc.
|
||||
Use them like this:
|
||||
#if __GNUC_PREREQ (2,8)
|
||||
... code requiring gcc 2.8 or later ...
|
||||
#endif
|
||||
Note - they won't work for gcc1 or glibc1, since the _MINOR macros
|
||||
were not defined then. */
|
||||
#if defined __GNUC__ && defined __GNUC_MINOR__
|
||||
# define __GNUC_PREREQ(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#else
|
||||
# define __GNUC_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#define __GLIBC_PREREQ(maj, min) \
|
||||
((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
|
||||
|
||||
|
@ -27,6 +27,18 @@ extern int __vsscanf (__const char *__restrict __s,
|
||||
_G_va_list __arg)
|
||||
__attribute__ ((__format__ (__scanf__, 2, 0)));
|
||||
|
||||
extern int __sprintf_chk (char *, int, size_t, const char *, ...) __THROW;
|
||||
extern int __snprintf_chk (char *, size_t, int, size_t, const char *, ...)
|
||||
__THROW;
|
||||
extern int __vsprintf_chk (char *, int, size_t, const char *,
|
||||
_G_va_list) __THROW;
|
||||
extern int __vsnprintf_chk (char *, size_t, int, size_t, const char *,
|
||||
_G_va_list) __THROW;
|
||||
extern int __printf_chk (int, const char *, ...);
|
||||
extern int __fprintf_chk (FILE *, int, const char *, ...);
|
||||
extern int __vprintf_chk (int, const char *, _G_va_list);
|
||||
extern int __vfprintf_chk (FILE *, int, const char *, _G_va_list);
|
||||
|
||||
/* Prototypes for compatibility functions. */
|
||||
extern FILE *__new_tmpfile (void);
|
||||
extern FILE *__old_tmpfile (void);
|
||||
@ -109,6 +121,8 @@ libc_hidden_proto (fgets_unlocked)
|
||||
libc_hidden_proto (fputs_unlocked)
|
||||
libc_hidden_proto (open_memstream)
|
||||
libc_hidden_proto (__libc_fatal)
|
||||
libc_hidden_proto (__vsprintf_chk)
|
||||
libc_hidden_proto (__vsnprintf_chk)
|
||||
|
||||
# if !defined NOT_IN_libc && defined SHARED && defined DO_VERSIONING \
|
||||
&& defined HAVE_VISIBILITY_ATTRIBUTE && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE\
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
extern void *__memccpy (void *__dest, __const void *__src,
|
||||
int __c, size_t __n);
|
||||
int __c, size_t __n);
|
||||
|
||||
extern size_t __strnlen (__const char *__string, size_t __maxlen)
|
||||
__attribute_pure__;
|
||||
@ -114,4 +114,30 @@ libc_hidden_builtin_proto (ffs)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
extern void *__memcpy_chk (void *__restrict __dest,
|
||||
const void *__restrict __src, size_t __len,
|
||||
size_t __destlen) __THROW;
|
||||
extern void *__memmove_chk (void *__dest, const void *__src, size_t __len,
|
||||
size_t __destlen) __THROW;
|
||||
extern void *__mempcpy_chk (void *__restrict __dest,
|
||||
const void *__restrict __src, size_t __len,
|
||||
size_t __destlen) __THROW;
|
||||
extern void *__memset_chk (void *__dest, int __ch, size_t __len,
|
||||
size_t __destlen) __THROW;
|
||||
extern char *__strcpy_chk (char *__restrict __dest,
|
||||
const char *__restrict __src,
|
||||
size_t __destlen) __THROW;
|
||||
extern char *__stpcpy_chk (char *__restrict __dest,
|
||||
const char *__restrict __src,
|
||||
size_t __destlen) __THROW;
|
||||
extern char *__strncpy_chk (char *__restrict __dest,
|
||||
const char *__restrict __src,
|
||||
size_t __len, size_t __destlen) __THROW;
|
||||
extern char *__strcat_chk (char *__restrict __dest,
|
||||
const char *__restrict __src,
|
||||
size_t __destlen) __THROW;
|
||||
extern char *__strncat_chk (char *__restrict __dest,
|
||||
const char *__restrict __src,
|
||||
size_t __len, size_t __destlen) __THROW;
|
||||
|
||||
#endif
|
||||
|
@ -1 +1,9 @@
|
||||
#ifndef _SYS_CDEFS_H
|
||||
|
||||
#include <misc/sys/cdefs.h>
|
||||
|
||||
extern void __chk_fail (void) __attribute__ ((__noreturn__));
|
||||
libc_hidden_proto (__chk_fail)
|
||||
rtld_hidden_proto (__chk_fail)
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1995-2002, 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
|
||||
@ -22,7 +22,7 @@
|
||||
subdir := libio
|
||||
|
||||
headers := stdio.h libio.h _G_config.h bits/stdio.h bits/stdio-lock.h \
|
||||
bits/sys_errlist.h
|
||||
bits/sys_errlist.h bits/stdio2.h
|
||||
|
||||
routines := \
|
||||
filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \
|
||||
|
78
libio/bits/stdio2.h
Normal file
78
libio/bits/stdio2.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* Checking macros for stdio functions.
|
||||
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. */
|
||||
|
||||
#ifndef _STDIO_H
|
||||
# error "Never include <bits/stdio2.h> directly; use <stdio.h> instead."
|
||||
#endif
|
||||
|
||||
extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
|
||||
__const char *__restrict __format, ...) __THROW;
|
||||
extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
|
||||
__const char *__restrict __format,
|
||||
_G_va_list __ap) __THROW;
|
||||
|
||||
#define sprintf(str, ...) \
|
||||
__builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \
|
||||
__VA_ARGS__)
|
||||
#define vsprintf(str, fmt, ap) \
|
||||
__builtin___vsprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), fmt, ap)
|
||||
|
||||
#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
|
||||
|
||||
extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
|
||||
size_t __slen, __const char *__restrict __format,
|
||||
...) __THROW;
|
||||
extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
|
||||
size_t __slen, __const char *__restrict __format,
|
||||
_G_va_list __ap) __THROW;
|
||||
|
||||
# define snprintf(str, len, ...) \
|
||||
__builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
|
||||
__VA_ARGS__)
|
||||
# define vsnprintf(str, len, fmt, ap) \
|
||||
__builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
|
||||
fmt, ap)
|
||||
|
||||
#endif
|
||||
|
||||
#if __USE_FORTIFY_LEVEL > 1
|
||||
|
||||
extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
|
||||
__const char *__restrict __format, ...);
|
||||
extern int __printf_chk (int __flag, __const char *__restrict __format, ...);
|
||||
extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
|
||||
__const char *__restrict __format, _G_va_list __ap);
|
||||
extern int __vprintf_chk (int __flag, __const char *__restrict __format,
|
||||
_G_va_list __ap);
|
||||
|
||||
# define printf(...) \
|
||||
__printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
|
||||
# define fprintf(stream, ...) \
|
||||
__fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
|
||||
# define vprintf(format, ap) \
|
||||
__vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
|
||||
# define vfprintf(stream, format, ap) \
|
||||
__vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
|
||||
|
||||
#endif
|
||||
|
||||
extern char *__gets_chk (char *__str, size_t);
|
||||
#define gets(__str) \
|
||||
((__bos (__str) == (size_t) -1) \
|
||||
? (gets) (__str) : __gets_chk (__str, __bos (__str)))
|
@ -139,6 +139,9 @@
|
||||
|
||||
#define _IO_FLAGS2_MMAP 1
|
||||
#define _IO_FLAGS2_NOTCANCEL 2
|
||||
#ifdef _LIBC
|
||||
# define _IO_FLAGS2_CHECK_PERCENT_N 4
|
||||
#endif
|
||||
|
||||
/* These are "formatting flags" matching the iostream fmtflags enum values. */
|
||||
#define _IO_SKIPWS 01
|
||||
|
@ -827,6 +827,9 @@ extern void funlockfile (FILE *__stream) __THROW;
|
||||
#ifdef __USE_EXTERN_INLINES
|
||||
# include <bits/stdio.h>
|
||||
#endif
|
||||
#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
|
||||
# include <bits/stdio2.h>
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
@ -63,3 +63,13 @@ typedef struct _IO_strfile_
|
||||
/* frozen: set when the program has requested that the array object not
|
||||
be altered, reallocated, or freed. */
|
||||
#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_IO_strfile f;
|
||||
/* This is used for the characters which do not fit in the buffer
|
||||
provided by the user. */
|
||||
char overflow_buf[64];
|
||||
} _IO_strnfile;
|
||||
|
||||
extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
|
||||
|
@ -28,16 +28,6 @@
|
||||
#include "libioP.h"
|
||||
#include "strfile.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_IO_strfile f;
|
||||
/* This is used for the characters which do not fit in the buffer
|
||||
provided by the user. */
|
||||
char overflow_buf[64];
|
||||
} _IO_strnfile;
|
||||
|
||||
|
||||
static int _IO_strn_overflow (_IO_FILE *fp, int c) __THROW;
|
||||
|
||||
static int
|
||||
@ -77,7 +67,7 @@ _IO_strn_overflow (fp, c)
|
||||
}
|
||||
|
||||
|
||||
static const struct _IO_jump_t _IO_strn_jumps =
|
||||
const struct _IO_jump_t _IO_strn_jumps attribute_hidden =
|
||||
{
|
||||
JUMP_INIT_DUMMY,
|
||||
JUMP_INIT(finish, _IO_str_finish),
|
||||
|
@ -35,7 +35,7 @@ typedef struct
|
||||
/* This is used for the characters which do not fit in the buffer
|
||||
provided by the user. */
|
||||
wchar_t overflow_buf[64];
|
||||
} _IO_strnfile;
|
||||
} _IO_wstrnfile;
|
||||
|
||||
|
||||
static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW;
|
||||
@ -49,8 +49,8 @@ _IO_wstrn_overflow (fp, c)
|
||||
filled. But since we must return the number of characters which
|
||||
would have been written in total we must provide a buffer for
|
||||
further use. We can do this by writing on and on in the overflow
|
||||
buffer in the _IO_strnfile structure. */
|
||||
_IO_strnfile *snf = (_IO_strnfile *) fp;
|
||||
buffer in the _IO_wstrnfile structure. */
|
||||
_IO_wstrnfile *snf = (_IO_wstrnfile *) fp;
|
||||
|
||||
if (fp->_wide_data->_IO_buf_base != snf->overflow_buf)
|
||||
{
|
||||
@ -107,7 +107,7 @@ _IO_vswprintf (string, maxlen, format, args)
|
||||
const wchar_t *format;
|
||||
_IO_va_list args;
|
||||
{
|
||||
_IO_strnfile sf;
|
||||
_IO_wstrnfile sf;
|
||||
int ret;
|
||||
struct _IO_wide_data wd;
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
|
@ -127,6 +127,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Fortify support. */
|
||||
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
|
||||
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||
|
||||
|
||||
/* Support for flexible arrays. */
|
||||
#if __GNUC_PREREQ (2,97)
|
||||
/* GCC 2.97 supports C99 flexible array members. */
|
||||
|
@ -70,6 +70,7 @@
|
||||
# define INT_T int
|
||||
# define L_(Str) Str
|
||||
# define ISDIGIT(Ch) ((unsigned int) ((Ch) - '0') < 10)
|
||||
# define STR_LEN(Str) strlen (Str)
|
||||
|
||||
# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
|
||||
# define PAD(Padchar) \
|
||||
@ -86,6 +87,7 @@
|
||||
# define INT_T wint_t
|
||||
# define L_(Str) L##Str
|
||||
# define ISDIGIT(Ch) ((unsigned int) ((Ch) - L'0') < 10)
|
||||
# define STR_LEN(Str) __wcslen (Str)
|
||||
|
||||
# include "_itowa.h"
|
||||
|
||||
@ -219,6 +221,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
/* For the %m format we may need the current `errno' value. */
|
||||
int save_errno = errno;
|
||||
|
||||
/* 1 if format is in read-only memory, -1 if it is in writable memory,
|
||||
0 if unknown. */
|
||||
int readonly_format = 0;
|
||||
|
||||
/* This table maps a character into a number representing a
|
||||
class. In each step there is a destination label for each
|
||||
@ -877,6 +882,19 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
/* NOTREACHED */ \
|
||||
\
|
||||
LABEL (form_number): \
|
||||
if (s->_flags2 & _IO_FLAGS2_CHECK_PERCENT_N) \
|
||||
{ \
|
||||
if (! readonly_format) \
|
||||
{ \
|
||||
extern int __readonly_area (const void *, size_t) \
|
||||
attribute_hidden; \
|
||||
readonly_format \
|
||||
= __readonly_area (format, (STR_LEN (format) + 1) \
|
||||
* sizeof (CHAR_T)); \
|
||||
} \
|
||||
if (readonly_format < 0) \
|
||||
__chk_fail (); \
|
||||
} \
|
||||
/* Answer the count of characters written. */ \
|
||||
if (fspec == NULL) \
|
||||
{ \
|
||||
@ -2091,6 +2109,7 @@ buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format,
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
hp->_lock = NULL;
|
||||
#endif
|
||||
hp->_flags2 = s->_flags2;
|
||||
_IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps;
|
||||
|
||||
/* Now print to helper instead. */
|
||||
|
@ -23,7 +23,7 @@ subdir := string
|
||||
|
||||
headers := string.h strings.h memory.h endian.h bits/endian.h \
|
||||
argz.h envz.h byteswap.h bits/byteswap.h bits/string.h \
|
||||
bits/string2.h
|
||||
bits/string2.h bits/string3.h
|
||||
|
||||
routines := strcat strchr strcmp strcoll strcpy strcspn \
|
||||
strverscmp strdup strndup \
|
||||
|
167
string/bits/string3.h
Normal file
167
string/bits/string3.h
Normal file
@ -0,0 +1,167 @@
|
||||
/* 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. */
|
||||
|
||||
#ifndef _STRING_H
|
||||
# error "Never use <bits/string3.h> directly; include <string.h> instead."
|
||||
#endif
|
||||
|
||||
/* XXX This is temporarily. We should not redefine any of the symbols
|
||||
and instead integrate the error checking into the original
|
||||
definitions. */
|
||||
#undef memcpy
|
||||
#undef memmove
|
||||
#undef memset
|
||||
#undef strcat
|
||||
#undef strcpy
|
||||
#undef strncat
|
||||
#undef strncpy
|
||||
#ifdef __USE_GNU
|
||||
# undef mempcpy
|
||||
# undef stpcpy
|
||||
#endif
|
||||
#ifdef __USE_BSD
|
||||
# undef bcopy
|
||||
# undef bzero
|
||||
#endif
|
||||
|
||||
|
||||
#define memcpy(dest, src, len) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memcpy_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __memcpy_ichk (dest, src, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__memcpy_ichk (void *__restrict __dest, const void *__restrict __src,
|
||||
size_t __len)
|
||||
{
|
||||
return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
|
||||
}
|
||||
|
||||
|
||||
#define memmove(dest, src, len) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memmove_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __memmove_ichk (dest, src, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__memmove_ichk (void *__dest, const void *__src, size_t __len)
|
||||
{
|
||||
return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
|
||||
}
|
||||
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define mempcpy(dest, src, len) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___mempcpy_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __mempcpy_ichk (dest, src, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__mempcpy_ichk (void *__restrict __dest, const void *__restrict __src,
|
||||
size_t __len)
|
||||
{
|
||||
return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define memset(dest, ch, len) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memset_chk (dest, ch, len, __bos0 (dest)) \
|
||||
: __memset_ichk (dest, ch, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__memset_ichk (void *__dest, int __ch, size_t __len)
|
||||
{
|
||||
return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
|
||||
}
|
||||
|
||||
#ifdef __USE_BSD
|
||||
# define bcopy(src, dest, len) ((void) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memmove_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __memmove_ichk (dest, src, len)))
|
||||
# define bzero(dest, len) ((void) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memset_chk (dest, '\0', len, __bos0 (dest)) \
|
||||
: __memset_ichk (dest, '\0', len)))
|
||||
#endif
|
||||
|
||||
|
||||
#define strcpy(dest, src) \
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strcpy_chk (dest, src, __bos (dest)) \
|
||||
: __strcpy_ichk (dest, src))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strcpy_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
{
|
||||
return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
|
||||
}
|
||||
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define stpcpy(dest, src) \
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___stpcpy_chk (dest, src, __bos (dest)) \
|
||||
: __stpcpy_ichk (dest, src))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__stpcpy_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
{
|
||||
return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define strncpy(dest, src, len) \
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strncpy_chk (dest, src, len, __bos (dest)) \
|
||||
: __strncpy_ichk (dest, src, len))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strncpy_ichk (char *__restrict __dest, const char *__restrict __src,
|
||||
size_t __len)
|
||||
{
|
||||
return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
|
||||
}
|
||||
|
||||
|
||||
#define strcat(dest, src) \
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strcat_chk (dest, src, __bos (dest)) \
|
||||
: __strcat_ichk (dest, src))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strcat_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
{
|
||||
return __builtin___strcat_chk (__dest, __src, __bos (__dest));
|
||||
}
|
||||
|
||||
|
||||
#define strncat(dest, src, len) \
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strncat_chk (dest, src, len, __bos (dest)) \
|
||||
: __strncat_ichk (dest, src, len))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strncat_ichk (char *__restrict __dest, const char *__restrict __src,
|
||||
size_t __len)
|
||||
{
|
||||
return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
|
||||
}
|
@ -416,6 +416,11 @@ extern char *basename (__const char *__filename) __THROW __nonnull ((1));
|
||||
/* These are generic optimizations which do not add too much inline code. */
|
||||
# include <bits/string2.h>
|
||||
# endif
|
||||
|
||||
# if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
|
||||
/* Functions with security checks. */
|
||||
# include <bits/string3.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
66
sysdeps/generic/memcpy_chk.c
Normal file
66
sysdeps/generic/memcpy_chk.c
Normal file
@ -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;
|
||||
}
|
98
sysdeps/generic/memmove_chk.c
Normal file
98
sysdeps/generic/memmove_chk.c
Normal file
@ -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;
|
||||
}
|
67
sysdeps/generic/mempcpy_chk.c
Normal file
67
sysdeps/generic/mempcpy_chk.c
Normal file
@ -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;
|
||||
}
|
92
sysdeps/generic/memset_chk.c
Normal file
92
sysdeps/generic/memset_chk.c
Normal file
@ -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;
|
||||
}
|
29
sysdeps/generic/readonly-area.c
Normal file
29
sysdeps/generic/readonly-area.c
Normal file
@ -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;
|
||||
}
|
45
sysdeps/generic/stpcpy_chk.c
Normal file
45
sysdeps/generic/stpcpy_chk.c
Normal file
@ -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;
|
||||
}
|
58
sysdeps/generic/strcat_chk.c
Normal file
58
sysdeps/generic/strcat_chk.c
Normal file
@ -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;
|
||||
}
|
46
sysdeps/generic/strcpy_chk.c
Normal file
46
sysdeps/generic/strcpy_chk.c
Normal file
@ -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;
|
||||
}
|
100
sysdeps/generic/strncat_chk.c
Normal file
100
sysdeps/generic/strncat_chk.c
Normal file
@ -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;
|
||||
}
|
89
sysdeps/generic/strncpy_chk.c
Normal file
89
sysdeps/generic/strncpy_chk.c
Normal file
@ -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;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/* Copy memory block and return pointer to beginning of destination block
|
||||
For Intel 80x86, x>=6.
|
||||
This file is part of the GNU C Library.
|
||||
Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -31,6 +31,13 @@
|
||||
#define LEN SRC+PTR_SIZE
|
||||
|
||||
.text
|
||||
#if defined PIC && !defined NOT_IN_libc
|
||||
ENTRY (__memcpy_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb HIDDEN_JUMPTARGET (__chk_fail)
|
||||
END (__memcpy_chk)
|
||||
#endif
|
||||
ENTRY (BP_SYM (memcpy))
|
||||
ENTER
|
||||
|
||||
|
35
sysdeps/i386/i686/memcpy_chk.S
Normal file
35
sysdeps/i386/i686/memcpy_chk.S
Normal file
@ -0,0 +1,35 @@
|
||||
/* Checking memcpy for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in memcpy.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
memcpy bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__memcpy_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb __chk_fail
|
||||
jmp memcpy
|
||||
END (__memcpy_chk)
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
/* Copy memory block and return pointer to beginning of destination block
|
||||
For Intel 80x86, x>=6.
|
||||
This file is part of the GNU C Library.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -31,6 +31,13 @@
|
||||
#define LEN SRC+PTR_SIZE
|
||||
|
||||
.text
|
||||
#if defined PIC && !defined NOT_IN_libc
|
||||
ENTRY (__memmove_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb HIDDEN_JUMPTARGET (__chk_fail)
|
||||
END (__memmove_chk)
|
||||
#endif
|
||||
ENTRY (BP_SYM (memmove))
|
||||
ENTER
|
||||
|
||||
|
35
sysdeps/i386/i686/memmove_chk.S
Normal file
35
sysdeps/i386/i686/memmove_chk.S
Normal file
@ -0,0 +1,35 @@
|
||||
/* Checking memmove for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in memmove.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
memmove bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__memmove_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb __chk_fail
|
||||
jmp memmove
|
||||
END (__memmove_chk)
|
||||
#endif
|
@ -31,6 +31,13 @@
|
||||
#define LEN SRC+PTR_SIZE
|
||||
|
||||
.text
|
||||
#if defined PIC && !defined NOT_IN_libc
|
||||
ENTRY (__mempcpy_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb HIDDEN_JUMPTARGET (__chk_fail)
|
||||
END (__mempcpy_chk)
|
||||
#endif
|
||||
ENTRY (BP_SYM (__mempcpy))
|
||||
ENTER
|
||||
|
||||
|
35
sysdeps/i386/i686/mempcpy_chk.S
Normal file
35
sysdeps/i386/i686/mempcpy_chk.S
Normal file
@ -0,0 +1,35 @@
|
||||
/* Checking mempcpy for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in mempcpy.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
mempcpy bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__mempcpy_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb __chk_fail
|
||||
jmp mempcpy
|
||||
END (__mempcpy_chk)
|
||||
#endif
|
@ -39,6 +39,13 @@
|
||||
#endif
|
||||
|
||||
.text
|
||||
#if defined PIC && !defined NOT_IN_libc && !BZERO_P
|
||||
ENTRY (__memset_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb HIDDEN_JUMPTARGET (__chk_fail)
|
||||
END (__memset_chk)
|
||||
#endif
|
||||
ENTRY (BP_SYM (memset))
|
||||
ENTER
|
||||
|
||||
|
35
sysdeps/i386/i686/memset_chk.S
Normal file
35
sysdeps/i386/i686/memset_chk.S
Normal file
@ -0,0 +1,35 @@
|
||||
/* Checking memset for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in memset.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
memset bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__memset_chk)
|
||||
movl 12(%esp), %eax
|
||||
cmpl %eax, 16(%esp)
|
||||
jb __chk_fail
|
||||
jmp memset
|
||||
END (__memset_chk)
|
||||
#endif
|
90
sysdeps/unix/sysv/linux/readonly-area.c
Normal file
90
sysdeps/unix/sysv/linux/readonly-area.c
Normal file
@ -0,0 +1,90 @@
|
||||
/* 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. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libio/libioP.h"
|
||||
|
||||
/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
|
||||
Return -1 if it is writable. */
|
||||
|
||||
int
|
||||
__readonly_area (const char *ptr, size_t size)
|
||||
{
|
||||
const void *ptr_end = ptr + size;
|
||||
|
||||
FILE *fp = fopen ("/proc/self/maps", "rc");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
/* We need no locking. */
|
||||
__fsetlocking (fp, FSETLOCKING_BYCALLER);
|
||||
|
||||
char *line = NULL;
|
||||
size_t linelen = 0;
|
||||
|
||||
while (! feof_unlocked (fp))
|
||||
{
|
||||
if (_IO_getdelim (&line, &linelen, '\n', fp) <= 0)
|
||||
break;
|
||||
|
||||
char *p;
|
||||
uintptr_t from = strtoul (line, &p, 16);
|
||||
|
||||
if (p == line || *p++ != '-')
|
||||
break;
|
||||
|
||||
char *q;
|
||||
uintptr_t to = strtoul (p, &q, 16);
|
||||
|
||||
if (q == p || *q++ != ' ')
|
||||
break;
|
||||
|
||||
if (from < (uintptr_t) ptr_end && to > (uintptr_t) ptr)
|
||||
{
|
||||
/* Found an entry that at least partially covers the area. */
|
||||
if (*q++ != 'r' || *q++ != '-')
|
||||
break;
|
||||
|
||||
if (from <= (uintptr_t) ptr && to >= (uintptr_t) ptr_end)
|
||||
{
|
||||
size = 0;
|
||||
break;
|
||||
}
|
||||
else if (from <= (uintptr_t) ptr)
|
||||
size -= to - (uintptr_t) ptr;
|
||||
else if (to >= (uintptr_t) ptr_end)
|
||||
size -= (uintptr_t) ptr_end - from;
|
||||
else
|
||||
size -= to - from;
|
||||
|
||||
if (!size)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
free (line);
|
||||
|
||||
/* If the whole area between ptr and ptr_end is covered by read-only
|
||||
VMAs, return 1. Otherwise return -1. */
|
||||
return size == 0 ? 1 : -1;
|
||||
}
|
@ -29,6 +29,12 @@
|
||||
#define MEMPCPY_P (defined memcpy)
|
||||
|
||||
.text
|
||||
#if defined PIC && !defined NOT_IN_libc
|
||||
ENTRY (__memcpy_chk)
|
||||
cmpq %rdx, %rcx
|
||||
jb HIDDEN_JUMPTARGET (__chk_fail)
|
||||
END (__memcpy_chk)
|
||||
#endif
|
||||
ENTRY (BP_SYM (memcpy))
|
||||
/* Cutoff for the big loop is a size of 32 bytes since otherwise
|
||||
the loop will never be entered. */
|
||||
|
34
sysdeps/x86_64/memcpy_chk.S
Normal file
34
sysdeps/x86_64/memcpy_chk.S
Normal file
@ -0,0 +1,34 @@
|
||||
/* Checking memcpy for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in memcpy.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
memcpy bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__memcpy_chk)
|
||||
cmpq %rdx, %rcx
|
||||
jb __chk_fail
|
||||
jmp memcpy
|
||||
END (__memcpy_chk)
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
#define memcpy __mempcpy
|
||||
#define __memcpy_chk __mempcpy_chk
|
||||
#include <sysdeps/x86_64/memcpy.S>
|
||||
|
||||
libc_hidden_def (BP_SYM (__mempcpy))
|
||||
|
34
sysdeps/x86_64/mempcpy_chk.S
Normal file
34
sysdeps/x86_64/mempcpy_chk.S
Normal file
@ -0,0 +1,34 @@
|
||||
/* Checking mempcpy for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in memcpy.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
mempcpy bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__mempcpy_chk)
|
||||
cmpq %rdx, %rcx
|
||||
jb __chk_fail
|
||||
jmp mempcpy
|
||||
END (__mempcpy_chk)
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/* memset/bzero -- set memory area to CH/0
|
||||
Optimized version for x86-64.
|
||||
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Andreas Jaeger <aj@suse.de>.
|
||||
|
||||
@ -32,6 +32,12 @@
|
||||
#define LARGE $120000
|
||||
|
||||
.text
|
||||
#if !BZERO_P && defined PIC && !defined NOT_IN_libc
|
||||
ENTRY (__memset_chk)
|
||||
cmpq %rdx, %rcx
|
||||
jb HIDDEN_JUMPTARGET (__chk_fail)
|
||||
END (__memset_chk)
|
||||
#endif
|
||||
ENTRY (memset)
|
||||
#if BZERO_P
|
||||
mov %rsi,%rdx /* Adjust parameter. */
|
||||
|
34
sysdeps/x86_64/memset_chk.S
Normal file
34
sysdeps/x86_64/memset_chk.S
Normal file
@ -0,0 +1,34 @@
|
||||
/* Checking memset for x86-64.
|
||||
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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* For libc.so this is defined in memset.S.
|
||||
For libc.a, this is a separate source to avoid
|
||||
memset bringing in __chk_fail and all routines
|
||||
it calls. */
|
||||
.text
|
||||
ENTRY (__memset_chk)
|
||||
cmpq %rdx, %rcx
|
||||
jb __chk_fail
|
||||
jmp memset
|
||||
END (__memset_chk)
|
||||
#endif
|
3
sysdeps/x86_64/stpcpy_chk.S
Normal file
3
sysdeps/x86_64/stpcpy_chk.S
Normal file
@ -0,0 +1,3 @@
|
||||
#define USE_AS_STPCPY_CHK
|
||||
#define STRCPY_CHK __stpcpy_chk
|
||||
#include <sysdeps/x86_64/strcpy_chk.S>
|
211
sysdeps/x86_64/strcpy_chk.S
Normal file
211
sysdeps/x86_64/strcpy_chk.S
Normal file
@ -0,0 +1,211 @@
|
||||
/* strcpy/stpcpy checking implementation for x86-64.
|
||||
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Andreas Jaeger <aj@suse.de>, 2002.
|
||||
Adopted into checking version by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
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 <sysdep.h>
|
||||
#include "asm-syntax.h"
|
||||
#include "bp-sym.h"
|
||||
#include "bp-asm.h"
|
||||
|
||||
#ifndef USE_AS_STPCPY_CHK
|
||||
# define STRCPY_CHK __strcpy_chk
|
||||
#endif
|
||||
|
||||
.text
|
||||
ENTRY (STRCPY_CHK)
|
||||
movq %rsi, %rcx /* Source register. */
|
||||
andl $7, %ecx /* mask alignment bits */
|
||||
#ifndef USE_AS_STPCPY_CHK
|
||||
movq %rdi, %r10 /* Duplicate destination pointer. */
|
||||
#endif
|
||||
jz 5f /* aligned => start loop */
|
||||
|
||||
cmpq $8, %rdx /* Check if only few bytes left in
|
||||
destination. */
|
||||
jb 50f
|
||||
|
||||
subq $8, %rcx /* We need to align to 8 bytes. */
|
||||
addq %rcx, %rdx /* Subtract count of stored bytes
|
||||
in the cycle below from destlen. */
|
||||
|
||||
/* Search the first bytes directly. */
|
||||
0:
|
||||
movb (%rsi), %al /* Fetch a byte */
|
||||
testb %al, %al /* Is it NUL? */
|
||||
movb %al, (%rdi) /* Store it */
|
||||
jz 4f /* If it was NUL, done! */
|
||||
incq %rsi
|
||||
incq %rdi
|
||||
incl %ecx
|
||||
jnz 0b
|
||||
|
||||
5:
|
||||
movq $0xfefefefefefefeff,%r8
|
||||
cmpq $32, %rdx /* Are there enough bytes in destination
|
||||
for the next unrolled round? */
|
||||
jb 60f /* If not, avoid the unrolled loop. */
|
||||
|
||||
/* Now the sources is aligned. Unfortunatly we cannot force
|
||||
to have both source and destination aligned, so ignore the
|
||||
alignment of the destination. */
|
||||
.p2align 4
|
||||
1:
|
||||
/* 1st unroll. */
|
||||
movq (%rsi), %rax /* Read double word (8 bytes). */
|
||||
addq $8, %rsi /* Adjust pointer for next word. */
|
||||
movq %rax, %r9 /* Save a copy for NUL finding. */
|
||||
addq %r8, %r9 /* add the magic value to the word. We get
|
||||
carry bits reported for each byte which
|
||||
is *not* 0 */
|
||||
jnc 3f /* highest byte is NUL => return pointer */
|
||||
xorq %rax, %r9 /* (word+magic)^word */
|
||||
orq %r8, %r9 /* set all non-carry bits */
|
||||
incq %r9 /* add 1: if one carry bit was *not* set
|
||||
the addition will not result in 0. */
|
||||
|
||||
jnz 3f /* found NUL => return pointer */
|
||||
|
||||
movq %rax, (%rdi) /* Write value to destination. */
|
||||
addq $8, %rdi /* Adjust pointer. */
|
||||
|
||||
/* 2nd unroll. */
|
||||
movq (%rsi), %rax /* Read double word (8 bytes). */
|
||||
addq $8, %rsi /* Adjust pointer for next word. */
|
||||
movq %rax, %r9 /* Save a copy for NUL finding. */
|
||||
addq %r8, %r9 /* add the magic value to the word. We get
|
||||
carry bits reported for each byte which
|
||||
is *not* 0 */
|
||||
jnc 3f /* highest byte is NUL => return pointer */
|
||||
xorq %rax, %r9 /* (word+magic)^word */
|
||||
orq %r8, %r9 /* set all non-carry bits */
|
||||
incq %r9 /* add 1: if one carry bit was *not* set
|
||||
the addition will not result in 0. */
|
||||
|
||||
jnz 3f /* found NUL => return pointer */
|
||||
|
||||
movq %rax, (%rdi) /* Write value to destination. */
|
||||
addq $8, %rdi /* Adjust pointer. */
|
||||
|
||||
/* 3rd unroll. */
|
||||
movq (%rsi), %rax /* Read double word (8 bytes). */
|
||||
addq $8, %rsi /* Adjust pointer for next word. */
|
||||
movq %rax, %r9 /* Save a copy for NUL finding. */
|
||||
addq %r8, %r9 /* add the magic value to the word. We get
|
||||
carry bits reported for each byte which
|
||||
is *not* 0 */
|
||||
jnc 3f /* highest byte is NUL => return pointer */
|
||||
xorq %rax, %r9 /* (word+magic)^word */
|
||||
orq %r8, %r9 /* set all non-carry bits */
|
||||
incq %r9 /* add 1: if one carry bit was *not* set
|
||||
the addition will not result in 0. */
|
||||
|
||||
jnz 3f /* found NUL => return pointer */
|
||||
|
||||
movq %rax, (%rdi) /* Write value to destination. */
|
||||
addq $8, %rdi /* Adjust pointer. */
|
||||
|
||||
/* 4th unroll. */
|
||||
movq (%rsi), %rax /* Read double word (8 bytes). */
|
||||
addq $8, %rsi /* Adjust pointer for next word. */
|
||||
movq %rax, %r9 /* Save a copy for NUL finding. */
|
||||
addq %r8, %r9 /* add the magic value to the word. We get
|
||||
carry bits reported for each byte which
|
||||
is *not* 0 */
|
||||
jnc 3f /* highest byte is NUL => return pointer */
|
||||
xorq %rax, %r9 /* (word+magic)^word */
|
||||
orq %r8, %r9 /* set all non-carry bits */
|
||||
incq %r9 /* add 1: if one carry bit was *not* set
|
||||
the addition will not result in 0. */
|
||||
|
||||
jnz 3f /* found NUL => return pointer */
|
||||
|
||||
subq $32, %rdx /* Adjust destlen. */
|
||||
movq %rax, (%rdi) /* Write value to destination. */
|
||||
addq $8, %rdi /* Adjust pointer. */
|
||||
cmpq $32, %rdx /* Are there enough bytes in destination
|
||||
for the next unrolled round? */
|
||||
jae 1b /* Next iteration. */
|
||||
|
||||
60:
|
||||
cmpq $8, %rdx /* Are there enough bytes in destination
|
||||
for the next unrolled round? */
|
||||
jb 50f /* Now, copy and check byte by byte. */
|
||||
|
||||
movq (%rsi), %rax /* Read double word (8 bytes). */
|
||||
addq $8, %rsi /* Adjust pointer for next word. */
|
||||
movq %rax, %r9 /* Save a copy for NUL finding. */
|
||||
addq %r8, %r9 /* add the magic value to the word. We get
|
||||
carry bits reported for each byte which
|
||||
is *not* 0 */
|
||||
jnc 3f /* highest byte is NUL => return pointer */
|
||||
xorq %rax, %r9 /* (word+magic)^word */
|
||||
orq %r8, %r9 /* set all non-carry bits */
|
||||
incq %r9 /* add 1: if one carry bit was *not* set
|
||||
the addition will not result in 0. */
|
||||
|
||||
jnz 3f /* found NUL => return pointer */
|
||||
|
||||
subq $8, %rdx /* Adjust destlen. */
|
||||
movq %rax, (%rdi) /* Write value to destination. */
|
||||
addq $8, %rdi /* Adjust pointer. */
|
||||
jmp 60b /* Next iteration. */
|
||||
|
||||
/* Do the last few bytes. %rax contains the value to write.
|
||||
The loop is unrolled twice. */
|
||||
.p2align 4
|
||||
3:
|
||||
/* Note that stpcpy needs to return with the value of the NUL
|
||||
byte. */
|
||||
movb %al, (%rdi) /* 1st byte. */
|
||||
testb %al, %al /* Is it NUL. */
|
||||
jz 4f /* yes, finish. */
|
||||
incq %rdi /* Increment destination. */
|
||||
movb %ah, (%rdi) /* 2nd byte. */
|
||||
testb %ah, %ah /* Is it NUL?. */
|
||||
jz 4f /* yes, finish. */
|
||||
incq %rdi /* Increment destination. */
|
||||
shrq $16, %rax /* Shift... */
|
||||
jmp 3b /* and look at next two bytes in %rax. */
|
||||
|
||||
51:
|
||||
/* Search the bytes directly, checking for overflows. */
|
||||
incq %rsi
|
||||
incq %rdi
|
||||
decq %rdx
|
||||
jz HIDDEN_JUMPTARGET (__chk_fail)
|
||||
52:
|
||||
movb (%rsi), %al /* Fetch a byte */
|
||||
testb %al, %al /* Is it NUL? */
|
||||
movb %al, (%rdi) /* Store it */
|
||||
jnz 51b /* If it was NUL, done! */
|
||||
4:
|
||||
#ifdef USE_AS_STPCPY_CHK
|
||||
movq %rdi, %rax /* Destination is return value. */
|
||||
#else
|
||||
movq %r10, %rax /* Source is return value. */
|
||||
#endif
|
||||
retq
|
||||
|
||||
50:
|
||||
testq %rdx, %rdx
|
||||
jnz 52b
|
||||
jmp HIDDEN_JUMPTARGET (__chk_fail)
|
||||
|
||||
END (STRCPY_CHK)
|
Loading…
Reference in New Issue
Block a user