This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! This patch fixes a few things: 1) mbstowcs and wcstombs with compile time known DST size, but compile time unknown LEN caused a segfault 2) mbstowcs/mbsrtowcs/mbsnrtowcs wouldn't detect buffer overflow say for #define _FORTIFY_SOURCE 2 #include <limits.h> #include <stdlib.h> #include <string.h> #include <wchar.h> size_t s2 = 2; int main (void) { mbstate_t s; wchar_t wb[10]; const char *cp = "ABCDEFGHIJKL"; memset (&s, 0, sizeof (s)); mbsrtowcs (wb, &cp, (size_t) SSIZE_MAX + 2, &s); cp = "ABCDEFGHIJKL"; mbsrtowcs (wb, &cp, (size_t) SSIZE_MAX + s2, &s); return 0; } 3) char enough[MB_CUR_MAX]; in tst-chk1.c is a VLA, which GCC doesn't handle (yet) in __bos - returns always (size_t) -1. This caused many tst-chk1.c tests to actually not test what they wanted to test. 2005-08-22 Jakub Jelinek <jakub@redhat.com> * stdlib/bits/stdlib.h (mbstowcs): Divide __bos (__dst) by sizeof (wchar_t) rather than multiplying __len by sizeof (wchar_t). Pass __bos (__dst) / sizeof (wchar_t) to the *_chk routine. * wcsmbs/bits/wchar2.h (mbsrtowcs, mbsnrtowcs): Likewise. * debug/mbsnrtowcs_chk.c (__mbsnrtowcs_chk): Don't multiply len by sizeof (wchar_t). * debug/mbsrtowcs_chk.c (__mbsrtowcs_chk): Likewise. * debug/mbstowcs_chk.c (__mbstowcs_chk): Likewise. Fix type of SRC argument. Pass &SRC rather than SRC to __mbsrtowcs. * debug/wcstombs_chk.c (__wcstombs_chk): Pass &SRC rather than SRC to __wcsrtombs. * debug/tst-chk1.c: Include assert.h. (do_test): Change enough array from VLA into a fixed size array. Assert that MB_CUR_MAX is <= sizeof (enough). Use FAIL () macro instead of print error details. Add several new tests. Kill some unused variable warnings. --- libc/stdlib/bits/stdlib.h.jj 2005-08-17 18:03:28.000000000 +0200 +++ libc/stdlib/bits/stdlib.h 2005-08-22 13:47:05.000000000 +0200 @@ -89,8 +89,9 @@ __NTH (mbstowcs (wchar_t *__restrict __d { if (__bos (__dst) != (size_t) -1 && (!__builtin_constant_p (__len) - || __len * sizeof (wchar_t) > __bos (__dst))) - return __mbstowcs_chk (__dst, __src, __len, __bos (__dst)); + || __len > __bos (__dst) / sizeof (wchar_t))) + return __mbstowcs_chk (__dst, __src, __len, + __bos (__dst) / sizeof (wchar_t)); return __mbstowcs_alias (__dst, __src, __len); } --- libc/wcsmbs/bits/wchar2.h.jj 2005-08-17 18:03:59.000000000 +0200 +++ libc/wcsmbs/bits/wchar2.h 2005-08-22 13:44:55.000000000 +0200 @@ -324,8 +324,9 @@ __NTH (mbsrtowcs (wchar_t *__restrict __ { if (__bos (__dst) != (size_t) -1 && (!__builtin_constant_p (__len) - || __len * sizeof (wchar_t) > __bos (__dst))) - return __mbsrtowcs_chk (__dst, __src, __len, __ps, __bos (__dst)); + || __len > __bos (__dst) / sizeof (wchar_t))) + return __mbsrtowcs_chk (__dst, __src, __len, __ps, + __bos (__dst) / sizeof (wchar_t)); return __mbsrtowcs_alias (__dst, __src, __len, __ps); } @@ -368,8 +369,9 @@ __NTH (mbsnrtowcs (wchar_t *__restrict _ { if (__bos (__dst) != (size_t) -1 && (!__builtin_constant_p (__len) - || __len * sizeof (wchar_t) > __bos (__dst))) - return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps, __bos (__dst)); + || __len > __bos (__dst) / sizeof (wchar_t))) + return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps, + __bos (__dst) / sizeof (wchar_t)); return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps); } --- libc/debug/mbsnrtowcs_chk.c.jj 2005-07-20 09:38:46.000000000 +0200 +++ libc/debug/mbsnrtowcs_chk.c 2005-08-22 14:17:18.000000000 +0200 @@ -24,7 +24,7 @@ size_t __mbsnrtowcs_chk (wchar_t *dst, __const char **src, size_t nmc, size_t len, mbstate_t *ps, size_t dstlen) { - if (__builtin_expect (dstlen < len * sizeof (wchar_t), 0)) + if (__builtin_expect (dstlen < len, 0)) __chk_fail (); return __mbsnrtowcs (dst, src, nmc, len, ps); --- libc/debug/mbstowcs_chk.c.jj 2005-07-25 23:37:32.000000000 +0200 +++ libc/debug/mbstowcs_chk.c 2005-08-22 14:31:28.000000000 +0200 @@ -22,14 +22,14 @@ size_t -__mbstowcs_chk (wchar_t *dst, const char **src, size_t len, size_t dstlen) +__mbstowcs_chk (wchar_t *dst, const char *src, size_t len, size_t dstlen) { - if (__builtin_expect (dstlen < len * sizeof (wchar_t), 0)) + if (__builtin_expect (dstlen < len, 0)) __chk_fail (); mbstate_t state; memset (&state, '\0', sizeof state); /* Return how many we wrote (or maybe an error). */ - return __mbsrtowcs (dst, src, len, &state); + return __mbsrtowcs (dst, &src, len, &state); } --- libc/debug/mbsrtowcs_chk.c.jj 2005-07-20 09:39:16.000000000 +0200 +++ libc/debug/mbsrtowcs_chk.c 2005-08-22 14:17:18.000000000 +0200 @@ -24,7 +24,7 @@ size_t __mbsrtowcs_chk (wchar_t *dst, __const char **src, size_t len, mbstate_t *ps, size_t dstlen) { - if (__builtin_expect (dstlen < len * sizeof (wchar_t), 0)) + if (__builtin_expect (dstlen < len, 0)) __chk_fail (); return __mbsrtowcs (dst, src, len, ps); --- libc/debug/wcstombs_chk.c.jj 2005-07-25 23:36:39.000000000 +0200 +++ libc/debug/wcstombs_chk.c 2005-08-22 14:17:18.000000000 +0200 @@ -32,5 +32,5 @@ __wcstombs_chk (char *dst, __const wchar memset (&state, '\0', sizeof state); /* Return how many we wrote (or maybe an error). */ - return __wcsrtombs (dst, src, len, &state); + return __wcsrtombs (dst, &src, len, &state); } --- libc/debug/tst-chk1.c.jj 2005-08-22 13:11:26.000000000 +0200 +++ libc/debug/tst-chk1.c 2005-08-22 14:44:32.000000000 +0200 @@ -17,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <assert.h> #include <fcntl.h> #include <locale.h> #include <paths.h> @@ -1030,23 +1031,27 @@ do_test (void) #if PATH_MAX > 0 char largebuf[PATH_MAX]; char *realres = realpath (".", largebuf); -#endif -#if __USE_FORTIFY_LEVEL >= 1 + if (realres != largebuf) + FAIL (); + +# if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char realbuf[1]; realres = realpath (".", realbuf); + if (realres != realbuf) + FAIL (); CHK_FAIL_END +# endif #endif if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL) { + assert (MB_CUR_MAX <= 10); + /* First a simple test. */ - char enough[MB_CUR_MAX]; + char enough[10]; if (wctomb (enough, L'A') != 1) - { - puts ("first wctomb test failed"); - ret = 1; - } + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 /* We know the wchar_t encoding is ISO 10646. So pick a @@ -1055,20 +1060,14 @@ do_test (void) CHK_FAIL_START char smallbuf[2]; if (wctomb (smallbuf, L'\x100') != 2) - { - puts ("second wctomb test failed"); - ret = 1; - } + FAIL (); CHK_FAIL_END #endif mbstate_t s; memset (&s, '\0', sizeof (s)); - if (wcrtomb (enough, L'A', &s) != 1) - { - puts ("first wcrtomb test failed"); - ret = 1; - } + if (wcrtomb (enough, L'D', &s) != 1 || enough[0] != 'D') + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 /* We know the wchar_t encoding is ISO 10646. So pick a @@ -1077,26 +1076,23 @@ do_test (void) CHK_FAIL_START char smallbuf[2]; if (wcrtomb (smallbuf, L'\x100', &s) != 2) - { - puts ("second wcrtomb test failed"); - ret = 1; - } + FAIL (); CHK_FAIL_END #endif wchar_t wenough[10]; memset (&s, '\0', sizeof (s)); const char *cp = "A"; - if (mbsrtowcs (wenough, &cp, 10, &s) != 1) - { - puts ("first mbsrtowcs test failed"); - ret = 1; - } + if (mbsrtowcs (wenough, &cp, 10, &s) != 1 + || wcscmp (wenough, L"A") != 0) + FAIL (); + + cp = "BC"; + if (mbsrtowcs (wenough, &cp, l0 + 10, &s) != 2 + || wcscmp (wenough, L"BC") != 0) + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 - /* We know the wchar_t encoding is ISO 10646. So pick a - character which has a multibyte representation which does not - fit. */ CHK_FAIL_START wchar_t wsmallbuf[2]; cp = "ABC"; @@ -1105,16 +1101,16 @@ do_test (void) #endif cp = "A"; - if (mbstowcs (wenough, cp, 10) != 1) - { - puts ("first mbstowcs test failed"); - ret = 1; - } + if (mbstowcs (wenough, cp, 10) != 1 + || wcscmp (wenough, L"A") != 0) + FAIL (); + + cp = "DEF"; + if (mbstowcs (wenough, cp, l0 + 10) != 3 + || wcscmp (wenough, L"DEF") != 0) + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 - /* We know the wchar_t encoding is ISO 10646. So pick a - character which has a multibyte representation which does not - fit. */ CHK_FAIL_START wchar_t wsmallbuf[2]; cp = "ABC"; @@ -1123,17 +1119,18 @@ do_test (void) #endif memset (&s, '\0', sizeof (s)); - cp = "A"; - if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1) - { - puts ("first mbsnrtowcs test failed"); - ret = 1; - } + cp = "ABC"; + wcscpy (wenough, L"DEF"); + if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1 + || wcscmp (wenough, L"AEF") != 0) + FAIL (); + + cp = "IJ"; + if (mbsnrtowcs (wenough, &cp, 1, l0 + 10, &s) != 1 + || wcscmp (wenough, L"IEF") != 0) + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 - /* We know the wchar_t encoding is ISO 10646. So pick a - character which has a multibyte representation which does not - fit. */ CHK_FAIL_START wchar_t wsmallbuf[2]; cp = "ABC"; @@ -1143,16 +1140,16 @@ do_test (void) memset (&s, '\0', sizeof (s)); const wchar_t *wcp = L"A"; - if (wcsrtombs (enough, &wcp, 10, &s) != 1) - { - puts ("first wcsrtombs test failed"); - ret = 1; - } + if (wcsrtombs (enough, &wcp, 10, &s) != 1 + || strcmp (enough, "A") != 0) + FAIL (); + + wcp = L"BC"; + if (wcsrtombs (enough, &wcp, l0 + 10, &s) != 2 + || strcmp (enough, "BC") != 0) + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 - /* We know the wchar_t encoding is ISO 10646. So pick a - character which has a multibyte representation which does not - fit. */ CHK_FAIL_START char smallbuf[2]; wcp = L"ABC"; @@ -1160,17 +1157,18 @@ do_test (void) CHK_FAIL_END #endif - wcp = L"A"; - if (wcstombs (enough, wcp, 10) != 1) - { - puts ("first wcstombs test failed"); - ret = 1; - } + memset (enough, 'Z', sizeof (enough)); + wcp = L"EF"; + if (wcstombs (enough, wcp, 10) != 2 + || strcmp (enough, "EF") != 0) + FAIL (); + + wcp = L"G"; + if (wcstombs (enough, wcp, l0 + 10) != 1 + || strcmp (enough, "G") != 0) + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 - /* We know the wchar_t encoding is ISO 10646. So pick a - character which has a multibyte representation which does not - fit. */ CHK_FAIL_START char smallbuf[2]; wcp = L"ABC"; @@ -1179,17 +1177,17 @@ do_test (void) #endif memset (&s, '\0', sizeof (s)); - wcp = L"A"; - if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1) - { - puts ("first wcsnrtombs test failed"); - ret = 1; - } + wcp = L"AB"; + if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1 + || strcmp (enough, "A") != 0) + FAIL (); + + wcp = L"BCD"; + if (wcsnrtombs (enough, &wcp, 1, l0 + 10, &s) != 1 + || strcmp (enough, "B") != 0) + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 - /* We know the wchar_t encoding is ISO 10646. So pick a - character which has a multibyte representation which does not - fit. */ CHK_FAIL_START char smallbuf[2]; wcp = L"ABC"; @@ -1208,38 +1206,36 @@ do_test (void) { char enough[1000]; if (ptsname_r (fd, enough, sizeof (enough)) != 0) - { - puts ("first ptsname_r failed"); - ret = 1; - } + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[2]; if (ptsname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0) - { - puts ("second ptsname_r somehow suceeded"); - ret = 1; - } + FAIL (); CHK_FAIL_END #endif close (fd); } +#if PATH_MAX > 0 confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf)); -#if __USE_FORTIFY_LEVEL >= 1 +# if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[1]; confstr (_CS_GNU_LIBC_VERSION, smallbuf, sizeof (largebuf)); CHK_FAIL_END +# endif #endif gid_t grpslarge[5]; int ngr = getgroups (5, grpslarge); + asm volatile ("" : : "r" (ngr)); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[1]; ngr = getgroups (5, (gid_t *) smallbuf); + asm volatile ("" : : "r" (ngr)); CHK_FAIL_END #endif @@ -1248,19 +1244,13 @@ do_test (void) { char enough[1000]; if (ttyname_r (fd, enough, sizeof (enough)) != 0) - { - puts ("first ttyname_r failed"); - ret = 1; - } + FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[2]; if (ttyname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0) - { - puts ("second ttyname_r somehow suceeded"); - ret = 1; - } + FAIL (); CHK_FAIL_END #endif close (fd); @@ -1286,10 +1276,12 @@ do_test (void) char domainnamelarge[1000]; int res = getdomainname (domainnamelarge, sizeof (domainnamelarge)); + asm volatile ("" : : "r" (res)); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[1]; res = getdomainname (smallbuf, sizeof (domainnamelarge)); + asm volatile ("" : : "r" (res)); CHK_FAIL_END #endif Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |