* wcsmbs/bits/wchar2.h: New file.

* include/bits/wchar2.h: New file.
	* wcsmbs/wchar.h: Include <bits/wchar2.h> if fortification is
	requested.
	* wcsmbs/wcsncpy.c: Add __wcsncpy alias.
	* string/bits/string3.h: Add fortified stpncpy definitions.
	* sysdeps/generic/stpncpy_chk.c: New file.
	* libio/vswprintf.c: Move _IO_wstrnfile definition to strfile.h.
	Export _IO_wstrn_jumps.
	* libio/strfile.h: Define _IO_wstrnfile and declare _IO_wstrn_jumps.
	* include/wchar.h: Declare __wcsncpy and __vswprintf_chk.
	* debug/fgetws_chk.c: New file.
	* debug/fgetws_u_chk.c: New file.
	* debug/fwprintf_chk.c: New file.
	* debug/swprintf_chk.c: New file.
	* debug/vfwprintf_chk.c: New file.
	* debug/vswprintf_chk.c: New file.
	* debug/vwprintf_chk.c: New file.
	* debug/wcpcpy_chk.c: New file.
	* debug/wcpncpy_chk.c: New file.
	* debug/wcscat_chk.c: New file.
	* debug/wcscpy_chk.c: New file.
	* debug/wcsncat_chk.c: New file.
	* debug/wcsncpy_chk.c: New file.
	* debug/wmemcpy_chk.c: New file.
	* debug/wmemmove_chk.c: New file.
	* debug/wmempcpy_chk.c: New file.
	* debug/wmemset_chk.c: New file.
	* debug/wprintf_chk.c: New file.
	* debug/tst-chk1.c: Add tests for new functions.
	* debug/Versions: Export new functions.
	* debug/Makefile (routines): Add new functions.
This commit is contained in:
Ulrich Drepper 2005-07-15 10:32:45 +00:00
parent f45729d8cd
commit 8215c9ecf2
31 changed files with 1563 additions and 25 deletions

View File

@ -1,3 +1,38 @@
2005-07-15 Ulrich Drepper <drepper@redhat.com>
* wcsmbs/bits/wchar2.h: New file.
* include/bits/wchar2.h: New file.
* wcsmbs/wchar.h: Include <bits/wchar2.h> if fortification is
requested.
* wcsmbs/wcsncpy.c: Add __wcsncpy alias.
* string/bits/string3.h: Add fortified stpncpy definitions.
* sysdeps/generic/stpncpy_chk.c: New file.
* libio/vswprintf.c: Move _IO_wstrnfile definition to strfile.h.
Export _IO_wstrn_jumps.
* libio/strfile.h: Define _IO_wstrnfile and declare _IO_wstrn_jumps.
* include/wchar.h: Declare __wcsncpy and __vswprintf_chk.
* debug/fgetws_chk.c: New file.
* debug/fgetws_u_chk.c: New file.
* debug/fwprintf_chk.c: New file.
* debug/swprintf_chk.c: New file.
* debug/vfwprintf_chk.c: New file.
* debug/vswprintf_chk.c: New file.
* debug/vwprintf_chk.c: New file.
* debug/wcpcpy_chk.c: New file.
* debug/wcpncpy_chk.c: New file.
* debug/wcscat_chk.c: New file.
* debug/wcscpy_chk.c: New file.
* debug/wcsncat_chk.c: New file.
* debug/wcsncpy_chk.c: New file.
* debug/wmemcpy_chk.c: New file.
* debug/wmemmove_chk.c: New file.
* debug/wmempcpy_chk.c: New file.
* debug/wmemset_chk.c: New file.
* debug/wprintf_chk.c: New file.
* debug/tst-chk1.c: Add tests for new functions.
* debug/Versions: Export new functions.
* debug/Makefile (routines): Add new functions.
2005-07-13 Ulrich Drepper <drepper@redhat.com> 2005-07-13 Ulrich Drepper <drepper@redhat.com>
* nscd/nscd_helper.c: Add a few __builtin_expect. * nscd/nscd_helper.c: Add a few __builtin_expect.

View File

@ -26,13 +26,18 @@ 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 \ memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
strcat_chk strcpy_chk strncat_chk strncpy_chk \ strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \ sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
printf_chk fprintf_chk vprintf_chk vfprintf_chk \ printf_chk fprintf_chk vprintf_chk vfprintf_chk \
gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \ gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \
read_chk pread_chk pread64_chk recv_chk recvfrom_chk \ read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
readlink_chk getwd_chk getcwd_chk realpath_chk ptsname_r_chk \ readlink_chk getwd_chk getcwd_chk realpath_chk ptsname_r_chk \
wctomb_chk stack_chk_fail \ wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
wcpncpy_chk \
swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
stack_chk_fail \
$(static-only-routines) $(static-only-routines)
static-only-routines := warning-nop stack_chk_fail_local static-only-routines := warning-nop stack_chk_fail_local
@ -48,6 +53,14 @@ CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-fgets_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-fgets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-fgets_u_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-fgets_u_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-swprintf_chk.c = -D_IO_MTSAFE_IO
CFLAGS-vswprintf_chk.c = -D_IO_MTSAFE_IO
CFLAGS-wprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-fwprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-vwprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-vfwprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-fgetws_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-fgetws_u_chk.c = -D_IO_MTSAFE_IO $(exceptions)
CFLAGS-read_chk.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-read_chk.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-pread_chk.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-pread_chk.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-pread64_chk.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-pread64_chk.c = -fexceptions -fasynchronous-unwind-tables

View File

@ -24,6 +24,11 @@ libc {
__readlink_chk; __getcwd_chk; __getwd_chk; __readlink_chk; __getcwd_chk; __getwd_chk;
__recv_chk; __recvfrom_chk; __recv_chk; __recvfrom_chk;
__realpath_chk; __ptsname_r_chk; __wctomb_chk; __realpath_chk; __ptsname_r_chk; __wctomb_chk;
__stpncpy_chk;
__wcscpy_chk; __wmemcpy_chk; __wmemmove_chk; __wmempcpy_chk; __wcpcpy_chk;
__wcsncpy_chk; __wcscat_chk; __wcsncat_chk; __wmemset_chk; __wcpncpy_chk;
__swprintf_chk; __vswprintf_chk; __wprintf_chk; __fwprintf_chk;
__vwprintf_chk; __vfwprintf_chk; __fgetws_chk; __fgetws_unlocked_chk;
__stack_chk_fail; __stack_chk_fail;
} }

54
debug/fgetws_chk.c Normal file
View File

@ -0,0 +1,54 @@
/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2001, 2005
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 "libioP.h"
#include <wchar.h>
#include <sys/param.h>
wchar_t *
__fgetws_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp)
{
_IO_size_t count;
wchar_t *result;
int old_error;
CHECK_FILE (fp, NULL);
if (n <= 0)
return NULL;
_IO_acquire_lock (fp);
/* 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. */
old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
fp->_IO_file_flags &= ~_IO_ERR_SEEN;
count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\n', 1);
/* If we read in some bytes and errno is EAGAIN, that error will
be reported for next read. */
if (count == 0 || (_IO_ferror_unlocked (fp) && errno != EAGAIN))
result = NULL;
else if (count >= size)
__chk_fail ();
else
{
buf[count] = '\0';
result = buf;
}
fp->_IO_file_flags |= old_error;
_IO_release_lock (fp);
return result;
}

61
debug/fgetws_u_chk.c Normal file
View File

@ -0,0 +1,61 @@
/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2005 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 "libioP.h"
#include <wchar.h>
#include <sys/param.h>
wchar_t *
__fgetws_unlocked_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp)
{
_IO_size_t count;
wchar_t *result;
int old_error;
CHECK_FILE (fp, NULL);
if (n <= 0)
return NULL;
/* 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. */
old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
fp->_IO_file_flags &= ~_IO_ERR_SEEN;
count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\n', 1);
/* If we read in some bytes and errno is EAGAIN, that error will
be reported for next read. */
if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN)
&& errno != EAGAIN))
result = NULL;
else if (count >= size)
__chk_fail ();
else
{
buf[count] = '\0';
result = buf;
}
fp->_IO_file_flags |= old_error;
return result;
}

45
debug/fwprintf_chk.c Normal file
View File

@ -0,0 +1,45 @@
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
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 <wchar.h>
#include "../libio/libioP.h"
/* Write formatted output to FP from the format string FORMAT. */
int
__fwprintf_chk (FILE *fp, int flag, const wchar_t *format, ...)
{
va_list ap;
int done;
_IO_acquire_lock (fp);
if (flag > 0)
fp->_flags2 |= _IO_FLAGS2_FORTIFY;
va_start (ap, format);
done = _IO_vfwprintf (fp, format, ap);
va_end (ap);
if (flag > 0)
fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
_IO_release_lock (fp);
return done;
}

37
debug/swprintf_chk.c Normal file
View File

@ -0,0 +1,37 @@
/* Copyright (C) 1991,1995,1997,1998,1999,2000,2003,2005
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 <wchar.h>
/* Write formatted output into S, according to the format string FORMAT. */
/* VARARGS5 */
int
__swprintf_chk (wchar_t *s, size_t n, int flag, size_t s_len,
const wchar_t *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = __vswprintf_chk (s, n, flag, s_len, format, arg);
va_end (arg);
return done;
}

View File

@ -25,9 +25,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <wchar.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h>
char *temp_filename; char *temp_filename;
static void do_prepare (void); static void do_prepare (void);
@ -72,6 +73,7 @@ handler (int sig)
} }
char buf[10]; char buf[10];
wchar_t wbuf[10];
volatile size_t l0; volatile size_t l0;
volatile char *p; volatile char *p;
const char *str1 = "JIHGFEDCBA"; const char *str1 = "JIHGFEDCBA";
@ -79,6 +81,11 @@ const char *str2 = "F";
const char *str3 = "%s%n%s%n"; const char *str3 = "%s%n%s%n";
const char *str4 = "Hello, "; const char *str4 = "Hello, ";
const char *str5 = "World!\n"; const char *str5 = "World!\n";
const wchar_t *wstr1 = L"JIHGFEDCBA";
const wchar_t *wstr2 = L"F";
const wchar_t *wstr3 = L"%s%n%s%n";
const wchar_t *wstr4 = L"Hello, ";
const wchar_t *wstr5 = L"World!\n";
char buf2[10] = "%s"; char buf2[10] = "%s";
int num1 = 67; int num1 = 67;
int num2 = 987654; int num2 = 987654;
@ -123,6 +130,7 @@ do_test (void)
setenv ("LIBC_FATAL_STDERR_", "1", 1); setenv ("LIBC_FATAL_STDERR_", "1", 1);
struct A { char buf1[9]; char buf2[1]; } a; struct A { char buf1[9]; char buf2[1]; } a;
struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa;
printf ("Test checking routines at fortify level %d\n", printf ("Test checking routines at fortify level %d\n",
#ifdef __USE_FORTIFY_LEVEL #ifdef __USE_FORTIFY_LEVEL
@ -138,7 +146,8 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10)) if (memcmp (buf, "aabcdefghi", 10))
FAIL (); FAIL ();
if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10)) if (mempcpy (buf + 5, "abcde", 5) != buf + 10
|| memcmp (buf, "aabcdabcde", 10))
FAIL (); FAIL ();
memset (buf + 8, 'j', 2); memset (buf + 8, 'j', 2);
@ -169,7 +178,8 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10)) if (memcmp (buf, "aabcdefghi", 10))
FAIL (); FAIL ();
if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10)) if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
|| memcmp (buf, "aabcdabcde", 10))
FAIL (); FAIL ();
memset (buf + 8, 'j', l0 + 2); memset (buf + 8, 'j', l0 + 2);
@ -187,20 +197,24 @@ do_test (void)
if (memcmp (buf, "aabcEDX\0\0", 10)) if (memcmp (buf, "aabcEDX\0\0", 10))
FAIL (); FAIL ();
if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEDX67", 10)) if (stpncpy (buf + 5, "cd", l0 + 5) != buf + 7
|| memcmp (buf, "aabcEcd\0\0", 10))
FAIL (); FAIL ();
if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10)) if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10))
FAIL ();
if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEcd98", 10))
FAIL (); FAIL ();
buf[l0 + 8] = '\0'; buf[l0 + 8] = '\0';
strcat (buf, "A"); strcat (buf, "A");
if (memcmp (buf, "aabcEDX9A", 10)) if (memcmp (buf, "aabcEcd9A", 10))
FAIL (); FAIL ();
buf[l0 + 7] = '\0'; buf[l0 + 7] = '\0';
strncat (buf, "ZYXWV", l0 + 2); strncat (buf, "ZYXWV", l0 + 2);
if (memcmp (buf, "aabcEDXZY", 10)) if (memcmp (buf, "aabcEcdZY", 10))
FAIL (); FAIL ();
memcpy (a.buf1, "abcdefghij", l0 + 10); memcpy (a.buf1, "abcdefghij", l0 + 10);
@ -224,14 +238,16 @@ do_test (void)
if (memcmp (a.buf1, "aabcEDCBA", 10)) if (memcmp (a.buf1, "aabcEDCBA", 10))
FAIL (); FAIL ();
if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10)) if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9
|| memcmp (a.buf1, "aabcEDCBF", 10))
FAIL (); FAIL ();
strncpy (a.buf1 + 6, "X", l0 + 4); strncpy (a.buf1 + 6, "X", l0 + 4);
if (memcmp (a.buf1, "aabcEDX\0\0", 10)) if (memcmp (a.buf1, "aabcEDX\0\0", 10))
FAIL (); FAIL ();
if (sprintf (a.buf1 + 7, "%d", num1) != 2 || memcmp (a.buf1, "aabcEDX67", 10)) if (sprintf (a.buf1 + 7, "%d", num1) != 2
|| memcmp (a.buf1, "aabcEDX67", 10))
FAIL (); FAIL ();
if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6 if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
@ -281,6 +297,10 @@ do_test (void)
strncpy (buf + 7, "X", l0 + 4); strncpy (buf + 7, "X", l0 + 4);
CHK_FAIL_END CHK_FAIL_END
CHK_FAIL_START
stpncpy (buf + 6, "cd", l0 + 5);
CHK_FAIL_END
CHK_FAIL_START CHK_FAIL_START
sprintf (buf + 8, "%d", num1); sprintf (buf + 8, "%d", num1);
CHK_FAIL_END CHK_FAIL_END
@ -352,6 +372,215 @@ do_test (void)
CHK_FAIL_END CHK_FAIL_END
#endif #endif
/* These ops can be done without runtime checking of object size. */
wmemcpy (wbuf, L"abcdefghij", 10);
wmemmove (wbuf + 1, wbuf, 9);
if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL ();
if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
|| wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL ();
wmemset (wbuf + 8, L'j', 2);
if (wmemcmp (wbuf, L"aabcdabcjj", 10))
FAIL ();
wcscpy (wbuf + 4, L"EDCBA");
if (wmemcmp (wbuf, L"aabcEDCBA", 10))
FAIL ();
if (wcpcpy (wbuf + 8, L"F") != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
FAIL ();
wcsncpy (wbuf + 6, L"X", 4);
if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
FAIL ();
if (swprintf (wbuf + 7, 3, L"%ls", L"987654") >= 0
|| wmemcmp (wbuf, L"aabcEDX98", 10))
FAIL ();
/* These ops need runtime checking, but shouldn't __chk_fail. */
wmemcpy (wbuf, L"abcdefghij", l0 + 10);
wmemmove (wbuf + 1, wbuf, l0 + 9);
if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL ();
if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
|| wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL ();
wmemset (wbuf + 8, L'j', l0 + 2);
if (wmemcmp (wbuf, L"aabcdabcjj", 10))
FAIL ();
wcscpy (wbuf + 4, wstr1 + 5);
if (wmemcmp (wbuf, L"aabcEDCBA", 10))
FAIL ();
if (wcpcpy (wbuf + 8, wstr2) != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
FAIL ();
wcsncpy (wbuf + 6, L"X", l0 + 4);
if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
FAIL ();
if (wcpncpy (wbuf + 5, L"cd", l0 + 5) != wbuf + 7
|| wmemcmp (wbuf, L"aabcEcd\0\0", 10))
FAIL ();
if (swprintf (wbuf + 7, 3, L"%d", num2) >= 0
|| wmemcmp (wbuf, L"aabcEcd98", 10))
FAIL ();
wbuf[l0 + 8] = L'\0';
wcscat (wbuf, L"A");
if (wmemcmp (wbuf, L"aabcEcd9A", 10))
FAIL ();
wbuf[l0 + 7] = L'\0';
wcsncat (wbuf, L"ZYXWV", l0 + 2);
if (wmemcmp (wbuf, L"aabcEcdZY", 10))
FAIL ();
wmemcpy (wa.buf1, L"abcdefghij", l0 + 10);
wmemmove (wa.buf1 + 1, wa.buf1, l0 + 9);
if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
FAIL ();
if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
|| wmemcmp (wa.buf1, L"aabcdabcde", 10))
FAIL ();
wmemset (wa.buf1 + 8, L'j', l0 + 2);
if (wmemcmp (wa.buf1, L"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. */
wcscpy (wa.buf1 + 4, wstr1 + 5);
if (wmemcmp (wa.buf1, L"aabcEDCBA", 10))
FAIL ();
if (wcpcpy (wa.buf1 + 8, wstr2) != wa.buf1 + 9
|| wmemcmp (wa.buf1, L"aabcEDCBF", 10))
FAIL ();
wcsncpy (wa.buf1 + 6, L"X", l0 + 4);
if (wmemcmp (wa.buf1, L"aabcEDX\0\0", 10))
FAIL ();
if (swprintf (wa.buf1 + 7, 3, L"%d", num2) >= 0
|| wmemcmp (wa.buf1, L"aabcEDX98", 10))
FAIL ();
wa.buf1[l0 + 8] = L'\0';
wcscat (wa.buf1, L"A");
if (wmemcmp (wa.buf1, L"aabcEDX9A", 10))
FAIL ();
wa.buf1[l0 + 7] = L'\0';
wcsncat (wa.buf1, L"ZYXWV", l0 + 2);
if (wmemcmp (wa.buf1, L"aabcEDXZY", 10))
FAIL ();
#endif
#if __USE_FORTIFY_LEVEL >= 1
/* Now check if all buffer overflows are caught at runtime. */
CHK_FAIL_START
wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10);
CHK_FAIL_END
CHK_FAIL_START
wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
CHK_FAIL_END
CHK_FAIL_START
p = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
CHK_FAIL_END
CHK_FAIL_START
wmemset (wbuf + 9, L'j', l0 + 2);
CHK_FAIL_END
CHK_FAIL_START
wcscpy (wbuf + 5, wstr1 + 5);
CHK_FAIL_END
CHK_FAIL_START
p = wcpcpy (wbuf + 9, wstr2);
CHK_FAIL_END
CHK_FAIL_START
wcsncpy (wbuf + 7, L"X", l0 + 4);
CHK_FAIL_END
CHK_FAIL_START
wcpncpy (wbuf + 6, L"cd", l0 + 5);
CHK_FAIL_END
wmemcpy (wbuf, wstr1 + 2, l0 + 9);
CHK_FAIL_START
wcscat (wbuf, L"AB");
CHK_FAIL_END
wmemcpy (wbuf, wstr1 + 3, l0 + 8);
CHK_FAIL_START
wcsncat (wbuf, L"ZYXWV", l0 + 3);
CHK_FAIL_END
CHK_FAIL_START
wmemcpy (wa.buf1 + 1, L"abcdefghij", l0 + 10);
CHK_FAIL_END
CHK_FAIL_START
wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
CHK_FAIL_END
CHK_FAIL_START
p = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
CHK_FAIL_END
CHK_FAIL_START
wmemset (wa.buf1 + 9, L'j', l0 + 2);
CHK_FAIL_END
#if __USE_FORTIFY_LEVEL >= 2
# define O 0
#else
# define O 1
#endif
CHK_FAIL_START
wcscpy (wa.buf1 + (O + 4), wstr1 + 5);
CHK_FAIL_END
CHK_FAIL_START
p = wcpcpy (wa.buf1 + (O + 8), wstr2);
CHK_FAIL_END
CHK_FAIL_START
wcsncpy (wa.buf1 + (O + 6), L"X", l0 + 4);
CHK_FAIL_END
wmemcpy (wa.buf1, wstr1 + (3 - O), l0 + 8 + O);
CHK_FAIL_START
wcscat (wa.buf1, L"AB");
CHK_FAIL_END
wmemcpy (wa.buf1, wstr1 + (4 - O), l0 + 7 + O);
CHK_FAIL_START
wcsncat (wa.buf1, L"ZYXWV", l0 + 3);
CHK_FAIL_END
#endif
/* Now checks for %n protection. */ /* Now checks for %n protection. */
/* Constant literals passed directly are always ok /* Constant literals passed directly are always ok

42
debug/vfwprintf_chk.c Normal file
View File

@ -0,0 +1,42 @@
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
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 <wchar.h>
#include "../libio/libioP.h"
/* Write formatted output to FP from the format string FORMAT. */
int
__vfwprintf_chk (FILE *fp, int flag, const wchar_t *format, va_list ap)
{
int done;
_IO_acquire_lock (fp);
if (flag > 0)
fp->_flags2 |= _IO_FLAGS2_FORTIFY;
done = _IO_vfwprintf (fp, format, ap);
if (flag > 0)
fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
_IO_release_lock (fp);
return done;
}

75
debug/vswprintf_chk.c Normal file
View File

@ -0,0 +1,75 @@
/* Copyright (C) 1991,1995,1997,1998,2004,2005 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 <wchar.h>
#include "../libio/libioP.h"
#include "../libio/strfile.h"
/* Write formatted output into S, according to the format
string FORMAT, writing no more than MAXLEN characters. */
/* VARARGS5 */
int
__vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen,
const wchar_t *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_wstrnfile sf;
struct _IO_wide_data wd;
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 (__builtin_expect (maxlen == 0, 0))
/* Since we have to write at least the terminating L'\0' a buffer
length of zero always makes the function fail. */
return -1;
_IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps);
_IO_fwide (&sf.f._sbf._f, 1);
s[0] = L'\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_FORTIFY;
_IO_wstr_init_static (&sf.f._sbf._f, s, maxlen - 1, s);
ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args);
if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf)
/* ISO C99 requires swprintf/vswprintf to return an error if the
output does not fit int he provided buffer. */
return -1;
/* Terminate the string. */
*sf.f._sbf._f._wide_data->_IO_write_ptr = '\0';
return ret;
}
libc_hidden_def (__vswprintf_chk)

43
debug/vwprintf_chk.c Normal file
View File

@ -0,0 +1,43 @@
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
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 <wchar.h>
#include "../libio/libioP.h"
/* Write formatted output to stdout from the format string FORMAT. */
int
__vwprintf_chk (int flag, const wchar_t *format, va_list ap)
{
int done;
_IO_acquire_lock (stdout);
if (flag > 0)
stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
done = _IO_vfwprintf (stdout, format, ap);
if (flag > 0)
stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
_IO_release_lock (stdout);
return done;
}

45
debug/wcpcpy_chk.c Normal file
View File

@ -0,0 +1,45 @@
/* Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
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 <wchar.h>
#define __need_ptrdiff_t
#include <stddef.h>
/* Copy SRC to DEST, returning the address of the terminating L'\0' in
DEST. Check for overflows. */
wchar_t *
__wcpcpy_chk (wchar_t *dest, const wchar_t *src, size_t destlen)
{
wchar_t *wcp = (wchar_t *) dest - 1;
wint_t c;
const ptrdiff_t off = src - dest + 1;
do
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = wcp[off];
*++wcp = c;
}
while (c != L'\0');
return wcp;
}

33
debug/wcpncpy_chk.c Normal file
View File

@ -0,0 +1,33 @@
/* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
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 <wchar.h>
/* Copy no more than N wide-characters of SRC to DEST. */
wchar_t *
__wcpncpy_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen)
{
if (__builtin_expect (destlen < n, 0))
__chk_fail ();
/* This function is not often enough used to justify not using a
tail call. */
return __wcpncpy (dest, src, n);
}

55
debug/wcscat_chk.c Normal file
View File

@ -0,0 +1,55 @@
/* Copyright (C) 1995, 1996, 1997, 2001, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
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 <wchar.h>
/* Append SRC on the end of DEST. Check for overflows. */
wchar_t *
__wcscat_chk (wchar_t *dest, const wchar_t *src, size_t destlen)
{
register wchar_t *s1 = dest;
register const wchar_t *s2 = src;
wchar_t c;
/* Find the end of the string. */
do
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *s1++;
}
while (c != L'\0');
/* Make S1 point before the next character, so we can increment
it while memory is read (wins on pipelined cpus). */
s1 -= 2;
++destlen;
do
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *s2++;
*++s1 = c;
}
while (c != L'\0');
return dest;
}

61
debug/wcscpy_chk.c Normal file
View File

@ -0,0 +1,61 @@
/* Copyright (C) 1995, 1996, 1997, 2003, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
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 <wchar.h>
/* Copy SRC to DEST. */
wchar_t *
__wcscpy_chk (wchar_t *dest, const wchar_t *src, size_t n)
{
wint_t c;
wchar_t *wcp;
if (__alignof__ (wchar_t) >= sizeof (wchar_t))
{
const ptrdiff_t off = dest - src - 1;
wcp = (wchar_t *) src;
do
{
if (__builtin_expect (n-- == 0, 0))
__chk_fail ();
c = *wcp++;
wcp[off] = c;
}
while (c != L'\0');
}
else
{
wcp = dest;
do
{
if (__builtin_expect (n-- == 0, 0))
__chk_fail ();
c = *src++;
*wcp++ = c;
}
while (c != L'\0');
}
return dest;
}

96
debug/wcsncat_chk.c Normal file
View File

@ -0,0 +1,96 @@
/* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
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 <wchar.h>
/* Append no more than N wide-character of SRC onto DEST. */
wchar_t *
__wcsncat_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen)
{
wchar_t c;
wchar_t * const s = dest;
/* Find the end of DEST. */
do
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *dest++;
}
while (c != L'\0');
/* Make DEST point before next character, so we can increment
it while memory is read (wins on pipelined cpus). */
++destlen;
dest -= 2;
if (n >= 4)
{
size_t n4 = n >> 2;
do
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *src++;
*++dest = c;
if (c == L'\0')
return s;
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *src++;
*++dest = c;
if (c == L'\0')
return s;
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *src++;
*++dest = c;
if (c == L'\0')
return s;
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *src++;
*++dest = c;
if (c == L'\0')
return s;
} while (--n4 > 0);
n &= 3;
}
while (n > 0)
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
c = *src++;
*++dest = c;
if (c == L'\0')
return s;
n--;
}
if (c != L'\0')
{
if (__builtin_expect (destlen-- == 0, 0))
__chk_fail ();
*++dest = L'\0';
}
return s;
}

33
debug/wcsncpy_chk.c Normal file
View File

@ -0,0 +1,33 @@
/* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
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 <wchar.h>
/* Copy no more than N wide-characters of SRC to DEST. */
wchar_t *
__wcsncpy_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen)
{
if (__builtin_expect (destlen < n, 0))
__chk_fail ();
/* This function is not often enough used to justify not using a
tail call. */
return __wcsncpy (dest, src, n);
}

30
debug/wmemcpy_chk.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 1996, 1997, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
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 <wchar.h>
#include <string.h>
wchar_t *
__wmemcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
{
if (__builtin_expect (ns1 < n, 0))
__chk_fail ();
return (wchar_t *) memcpy ((char *) s1, (char *) s2, n * sizeof (wchar_t));
}

30
debug/wmemmove_chk.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 1996, 1997, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
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 <wchar.h>
#include <string.h>
wchar_t *
__wmemmove_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
{
if (__builtin_expect (ns1 < n, 0))
__chk_fail ();
return (wchar_t *) memmove ((char *) s1, (char *) s2, n * sizeof (wchar_t));
}

31
debug/wmempcpy_chk.c Normal file
View File

@ -0,0 +1,31 @@
/* Copyright (C) 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 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. */
#include <wchar.h>
#include <string.h>
wchar_t *
__wmempcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
{
if (__builtin_expect (ns1 < n, 0))
__chk_fail ();
return (wchar_t *) __mempcpy ((char *) s1, (char *) s2,
n * sizeof (wchar_t));
}

30
debug/wmemset_chk.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 1996,97,99,2002,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
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 <wchar.h>
wchar_t *
__wmemset_chk (wchar_t *s, wchar_t c, size_t n, size_t dstlen)
{
if (__builtin_expect (dstlen < n, 0))
__chk_fail ();
return wmemset (s, c, n);
}

46
debug/wprintf_chk.c Normal file
View File

@ -0,0 +1,46 @@
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
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 <wchar.h>
#include "../libio/libioP.h"
/* Write formatted output to stdout from the format string FORMAT. */
int
__wprintf_chk (int flag, const wchar_t *format, ...)
{
va_list ap;
int done;
_IO_acquire_lock (stdout);
if (flag > 0)
stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
va_start (ap, format);
done = _IO_vfwprintf (stdout, format, ap);
va_end (ap);
if (flag > 0)
stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
_IO_release_lock (stdout);
return done;
}

1
include/bits/wchar2.h Normal file
View File

@ -0,0 +1 @@
#include <wcsmbs/bits/wchar2.h>

View File

@ -82,6 +82,8 @@ extern size_t __wcsnrtombs (char *__restrict __dst,
__const wchar_t **__restrict __src, __const wchar_t **__restrict __src,
size_t __nwc, size_t __len, size_t __nwc, size_t __len,
__mbstate_t *__restrict __ps); __mbstate_t *__restrict __ps);
extern wchar_t *__wcsncpy (wchar_t *__restrict __dest,
__const wchar_t *__restrict __src, size_t __n);
extern wchar_t *__wcpcpy (wchar_t *__dest, __const wchar_t *__src); extern wchar_t *__wcpcpy (wchar_t *__dest, __const wchar_t *__src);
extern wchar_t *__wcpncpy (wchar_t *__dest, __const wchar_t *__src, extern wchar_t *__wcpncpy (wchar_t *__dest, __const wchar_t *__src,
size_t __n); size_t __n);
@ -112,6 +114,13 @@ extern int __vfwprintf (__FILE *__restrict __s,
/* __attribute__ ((__format__ (__wprintf__, 3, 0))) */; /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
int __flag, size_t __s_len,
__const wchar_t *__restrict __format,
__gnuc_va_list __arg)
/* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
libc_hidden_proto (__vswprintf_chk)
/* Internal functions. */ /* Internal functions. */
extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len, extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len,
mbstate_t *ps, __locale_t l) attribute_hidden; mbstate_t *ps, __locale_t l) attribute_hidden;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. /* Copyright (C) 1993, 1997, 1998, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -73,3 +73,14 @@ typedef struct
} _IO_strnfile; } _IO_strnfile;
extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden; extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
typedef struct
{
_IO_strfile f;
/* This is used for the characters which do not fit in the buffer
provided by the user. */
wchar_t overflow_buf[64];
} _IO_wstrnfile;
extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1994,1997,1999-2002,2004 Free Software Foundation, Inc. /* Copyright (C) 1994,1997,1999-2002,2004,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -29,15 +29,6 @@
#include "strfile.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. */
wchar_t overflow_buf[64];
} _IO_wstrnfile;
static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW; static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW;
static wint_t static wint_t
@ -75,7 +66,7 @@ _IO_wstrn_overflow (fp, c)
} }
static const struct _IO_jump_t _IO_wstrn_jumps = const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden =
{ {
JUMP_INIT_DUMMY, JUMP_INIT_DUMMY,
JUMP_INIT(finish, _IO_wstr_finish), JUMP_INIT(finish, _IO_wstr_finish),

View File

@ -144,6 +144,22 @@ __strncpy_ichk (char *__restrict __dest, const char *__restrict __src,
} }
// XXX We have no corresponding builtin yet.
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
size_t __destlen) __THROW;
extern char *__REDIRECT (__stpncpy_alias, (char *__dest, const char *__src,
size_t __n), stpncpy)__THROW;
extern __always_inline char *
stpncpy (char *__dest, const char *__src, size_t __n)
{
if (__bos (__dest) != (size_t) -1
&& (!__builtin_constant_p (__n) || __n <= __bos (__dest)))
return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
return __stpncpy_alias (__dest, __src, __n);
}
#define strcat(dest, src) \ #define strcat(dest, src) \
((__bos (dest) != (size_t) -1) \ ((__bos (dest) != (size_t) -1) \
? __builtin___strcat_chk (dest, src, __bos (dest)) \ ? __builtin___strcat_chk (dest, src, __bos (dest)) \

View File

@ -0,0 +1,85 @@
/* Copyright (C) 1993,1995,1996,1997,2002,2005 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. */
/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */
#include <string.h>
/* Copy no more than N characters of SRC to DEST, returning the address of
the terminating '\0' in DEST, if any, or else DEST + N. */
char *
__stpncpy_chk (char *dest, const char *src, size_t n, size_t destlen)
{
char c;
char *s = dest;
if (__builtin_expect (destlen < n, 0))
__chk_fail ();
if (n >= 4)
{
size_t n4 = n >> 2;
for (;;)
{
c = *src++;
*dest++ = c;
if (c == '\0')
break;
c = *src++;
*dest++ = c;
if (c == '\0')
break;
c = *src++;
*dest++ = c;
if (c == '\0')
break;
c = *src++;
*dest++ = c;
if (c == '\0')
break;
if (--n4 == 0)
goto last_chars;
}
n -= dest - s;
goto zero_fill;
}
last_chars:
n &= 3;
if (n == 0)
return dest;
for (;;)
{
c = *src++;
--n;
*dest++ = c;
if (c == '\0')
break;
if (n == 0)
return dest;
}
zero_fill:
while (n-- > 0)
dest[n] = '\0';
return dest - 1;
}

288
wcsmbs/bits/wchar2.h Normal file
View File

@ -0,0 +1,288 @@
/* Checking macros for wchar functions.
Copyright (C) 2005 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 _WCHAR_H
# error "Never include <bits/wchar.h> directly; use <wchar.h> instead."
#endif
extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
__const wchar_t *__restrict __s2, size_t __n,
size_t __ns1) __THROW;
extern wchar_t *__REDIRECT (__wmemcpy_alias, (wchar_t *__restrict __s1,
__const wchar_t *__restrict __s2,
size_t __n), wmemcpy) __THROW;
extern __always_inline wchar_t *
wmemcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
size_t __n)
{
if (__bos0 (__s1) != (size_t) -1)
return __wmemcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
return __wmemcpy_alias (__s1, __s2, __n);
}
extern wchar_t *__wmemmove_chk (wchar_t *__s1, __const wchar_t *__s2,
size_t __n, size_t __ns1) __THROW;
extern wchar_t *__REDIRECT (__wmemmove_alias, (wchar_t *__s1,
__const wchar_t *__s2,
size_t __n), wmemmove) __THROW;
extern __always_inline wchar_t *
wmemmove (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
size_t __n)
{
if (__bos0 (__s1) != (size_t) -1)
return __wmemmove_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
return __wmemmove_alias (__s1, __s2, __n);
}
#ifdef __USE_GNU
extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1,
__const wchar_t *__restrict __s2, size_t __n,
size_t __ns1) __THROW;
extern wchar_t *__REDIRECT (__wmempcpy_alias,
(wchar_t *__restrict __s1,
__const wchar_t *__restrict __s2,
size_t __n), wmempcpy) __THROW;
extern __always_inline wchar_t *
wmempcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
size_t __n)
{
if (__bos0 (__s1) != (size_t) -1)
return __wmempcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
return __wmempcpy_alias (__s1, __s2, __n);
}
#endif
extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
size_t __ns) __THROW;
extern wchar_t *__REDIRECT (__wmemset_alias, (wchar_t *__s, wchar_t __c,
size_t __n), wmemset) __THROW;
extern __always_inline wchar_t *
wmemset (wchar_t *__restrict __s, wchar_t __c, size_t __n)
{
if (__bos0 (__s) != (size_t) -1)
return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
return __wmemset_alias (__s, __c, __n);
}
extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest,
__const wchar_t *__restrict __src,
size_t __n) __THROW;
extern wchar_t *__REDIRECT (__wcscpy_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src), wcscpy)
__THROW;
extern __always_inline wchar_t *
wcscpy (wchar_t *__dest, __const wchar_t *__src)
{
if (__bos (__dest) != (size_t) -1)
return __wcscpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
return __wcscpy_alias (__dest, __src);
}
extern wchar_t *__wcpcpy_chk (wchar_t *__dest, __const wchar_t *__src,
size_t __destlen) __THROW;
extern wchar_t *__REDIRECT (__wcpcpy_alias, (wchar_t *__dest,
__const wchar_t *__src), wcpcpy)
__THROW;
extern __always_inline wchar_t *
wcpcpy (wchar_t *__dest, __const wchar_t *__src)
{
if (__bos (__dest) != (size_t) -1)
return __wcpcpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
return __wcpcpy_alias (__dest, __src);
}
extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest,
__const wchar_t *__restrict __src, size_t __n,
size_t __destlen) __THROW;
extern wchar_t *__REDIRECT (__wcsncpy_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src, size_t __n),
wcsncpy) __THROW;
extern __always_inline wchar_t *
wcsncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n)
{
if (__bos (__dest) != (size_t) -1
&& (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
return __wcsncpy_chk (__dest, __src, __n,
__bos (__dest) / sizeof (wchar_t));
return __wcsncpy_alias (__dest, __src, __n);
}
extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest,
__const wchar_t *__restrict __src, size_t __n,
size_t __destlen) __THROW;
extern wchar_t *__REDIRECT (__wcpncpy_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src, size_t __n),
wcpncpy) __THROW;
extern __always_inline wchar_t *
wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n)
{
if (__bos (__dest) != (size_t) -1
&& (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
return __wcpncpy_chk (__dest, __src, __n,
__bos (__dest) / sizeof (wchar_t));
return __wcpncpy_alias (__dest, __src, __n);
}
extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest,
__const wchar_t *__restrict __src,
size_t __destlen) __THROW;
extern wchar_t *__REDIRECT (__wcscat_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src), wcscat)
__THROW;
extern __always_inline wchar_t *
wcscat (wchar_t *__dest, __const wchar_t *__src)
{
if (__bos (__dest) != (size_t) -1)
return __wcscat_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
return __wcscat_alias (__dest, __src);
}
extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest,
__const wchar_t *__restrict __src,
size_t __n, size_t __destlen) __THROW;
extern wchar_t *__REDIRECT (__wcsncat_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src, size_t __n),
wcsncat) __THROW;
extern __always_inline wchar_t *
wcsncat (wchar_t *__dest, __const wchar_t *__src, size_t __n)
{
if (__bos (__dest) != (size_t) -1)
return __wcsncat_chk (__dest, __src, __n,
__bos (__dest) / sizeof (wchar_t));
return __wcsncat_alias (__dest, __src, __n);
}
extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
int __flag, size_t __s_len,
__const wchar_t *__restrict __format, ...)
__THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
/* XXX We might want to have support in gcc for swprintf. */
#define swprintf(s, n, format, ...) \
(__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \
? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), format, \
__VA_ARGS__) \
: swprintf (s, n, format, __VA_ARGS__))
extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
int __flag, size_t __s_len,
__const wchar_t *__restrict __format,
__gnuc_va_list __arg)
__THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
extern int __REDIRECT (__vswprintf_alias,
(wchar_t *__restrict __s, size_t __n,
__const wchar_t *__restrict __format,
__gnuc_va_list __arg), vswprintf)
__THROW /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
extern __always_inline int
vswprintf (wchar_t *__s, size_t __n, __const wchar_t *__format,
__gnuc_va_list __arg)
{
if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
__format, __arg);
return vswprintf (__s, __n, __format, __arg);
}
#if __USE_FORTIFY_LEVEL > 1
extern int __fwprintf_chk (FILE *__restrict __stream, int __flag,
__const wchar_t *__restrict __format, ...);
extern int __wprintf_chk (int __flag, __const wchar_t *__restrict __format,
...);
extern int __vfwprintf_chk (FILE *__restrict __stream, int __flag,
__const wchar_t *__restrict __format,
_G_va_list __ap);
extern int __vwprintf_chk (int __flag, __const wchar_t *__restrict __format,
_G_va_list __ap);
# define wprintf(...) \
__wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# define fwprintf(stream, ...) \
__fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# define vwprintf(format, ap) \
__vwprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
# define vfwprintf(stream, format, ap) \
__vfwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
#endif
extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
FILE *__restrict __stream) __wur;
extern wchar_t *__REDIRECT (__fgetws_alias,
(wchar_t *__restrict __s, int __n,
FILE *__restrict __stream), fgetws) __wur;
extern __always_inline __wur wchar_t *
fgetws (wchar_t *__restrict __s, int __n, FILE *__restrict __stream)
{
if (__bos (__s) != (size_t) -1
&& (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
return __fgetws_chk (__s, __bos (__s), __n, __stream);
return __fgetws_alias (__s, __n, __stream);
}
#ifdef __USE_GNU
extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size,
int __n, FILE *__restrict __stream)
__wur;
extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
(wchar_t *__restrict __s, int __n,
FILE *__restrict __stream), fgetws_unlocked)
__wur;
extern __always_inline __wur wchar_t *
fgetws_unlocked (wchar_t *__restrict __s, int __n, FILE *__restrict __stream)
{
if (__bos (__s) != (size_t) -1
&& (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
return __fgetws_unlocked_chk (__s, __bos (__s), __n, __stream);
return __fgetws_unlocked_alias (__s, __n, __stream);
}
#endif

View File

@ -833,6 +833,13 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
# include <wctype.h> # include <wctype.h>
#endif #endif
/* Define some macros helping to catch buffer overflows. */
#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
# include <bits/wchar2.h>
#endif
__END_DECLS __END_DECLS
#endif /* _WCHAR_H defined */ #endif /* _WCHAR_H defined */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. /* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
@ -22,7 +22,7 @@
/* Copy no more than N wide-characters of SRC to DEST. */ /* Copy no more than N wide-characters of SRC to DEST. */
wchar_t * wchar_t *
wcsncpy (dest, src, n) __wcsncpy (dest, src, n)
wchar_t *dest; wchar_t *dest;
const wchar_t *src; const wchar_t *src;
size_t n; size_t n;
@ -84,3 +84,4 @@ wcsncpy (dest, src, n)
return s; return s;
} }
weak_alias (__wcsncpy, wcsncpy)