stpncpy: fix size checking [BZ #18975]
I think the last clause of the conditional, || __n <= __bos (__dest) may be backward. The code should call the runtime-checking function if __n is not constant, or if __n is known to be LARGER than the size of the destination.
This commit is contained in:
parent
739babd775
commit
8ff5e0ec49
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
2015-08-15 Zack Weinberg <zackw@panix.com>
|
||||
|
||||
[BZ #18975]
|
||||
* string/bits/string3.h (stpncpy): Call __stpncpy_chk if the
|
||||
buffer length is known to be too large, not if it's known to be
|
||||
small enough.
|
||||
* debug/tst-chk1.c (do_test): Do all tests for catching a buffer
|
||||
overflow at runtime, involving a length parameter, twice: once
|
||||
with a compile-time constant length parameter, once without.
|
||||
|
||||
2015-08-14 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #18824]
|
||||
|
4
NEWS
4
NEWS
@ -10,8 +10,8 @@ Version 2.23
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
16517, 16519, 16520, 16734, 17905, 18086, 18265, 18480, 18525, 18618,
|
||||
18647, 18661, 18674, 18778, 18781, 18787, 18789, 18790, 18820, 18824.
|
||||
|
||||
18647, 18661, 18674, 18778, 18781, 18787, 18789, 18790, 18820, 18824,
|
||||
18975.
|
||||
|
||||
Version 2.22
|
||||
|
||||
|
169
debug/tst-chk1.c
169
debug/tst-chk1.c
@ -264,20 +264,38 @@ do_test (void)
|
||||
#endif
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
/* Now check if all buffer overflows are caught at runtime. */
|
||||
/* Now check if all buffer overflows are caught at runtime.
|
||||
N.B. All tests involving a length parameter need to be done
|
||||
twice: once with the length a compile-time constant, once without. */
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (buf + 1, "abcdefghij", 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (buf + 1, "abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (buf + 2, buf + 1, 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (buf + 2, buf + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (buf + 6, "abcde", 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (buf + 9, 'j', 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (buf + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
@ -290,10 +308,18 @@ do_test (void)
|
||||
p = stpcpy (buf + 9, str2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (buf + 7, "X", 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (buf + 7, "X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
stpncpy (buf + 6, "cd", 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
stpncpy (buf + 6, "cd", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
@ -303,6 +329,10 @@ do_test (void)
|
||||
sprintf (buf + 8, "%d", num1);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (buf + 8, 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (buf + 8, l0 + 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
@ -316,28 +346,49 @@ do_test (void)
|
||||
CHK_FAIL_END
|
||||
# endif
|
||||
|
||||
memcpy (buf, str1 + 2, l0 + 9);
|
||||
memcpy (buf, str1 + 2, 9);
|
||||
CHK_FAIL_START
|
||||
strcat (buf, "AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (buf, str1 + 3, l0 + 8);
|
||||
memcpy (buf, str1 + 3, 8);
|
||||
CHK_FAIL_START
|
||||
strncat (buf, "ZYXWV", 3);
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (buf, str1 + 3, 8);
|
||||
CHK_FAIL_START
|
||||
strncat (buf, "ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (a.buf1 + 1, "abcdefghij", 10);
|
||||
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, 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (a.buf1 + 9, 'j', 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (a.buf1 + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
@ -356,6 +407,10 @@ do_test (void)
|
||||
p = stpcpy (a.buf1 + (O + 8), str2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (a.buf1 + (O + 6), "X", 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (a.buf1 + (O + 6), "X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
@ -365,17 +420,21 @@ do_test (void)
|
||||
sprintf (a.buf1 + (O + 7), "%d", num1);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (a.buf1 + (O + 7), 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
# endif
|
||||
|
||||
memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
|
||||
memcpy (a.buf1, str1 + (3 - O), 8 + O);
|
||||
CHK_FAIL_START
|
||||
strcat (a.buf1, "AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O);
|
||||
memcpy (a.buf1, str1 + (4 - O), 7 + O);
|
||||
CHK_FAIL_START
|
||||
strncat (a.buf1, "ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
@ -504,24 +563,46 @@ do_test (void)
|
||||
#endif
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
/* Now check if all buffer overflows are caught at runtime. */
|
||||
/* Now check if all buffer overflows are caught at runtime.
|
||||
N.B. All tests involving a length parameter need to be done
|
||||
twice: once with the length a compile-time constant, once without. */
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemcpy (wbuf + 1, L"abcdefghij", 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemcpy (wbuf + 9, L"abcdefghij", 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemcpy (wbuf + 9, L"abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemmove (wbuf + 2, wbuf + 1, 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wbuf + 6, L"abcde", 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemset (wbuf + 9, L'j', 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemset (wbuf + 9, L'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
@ -534,6 +615,10 @@ do_test (void)
|
||||
wp = wcpcpy (wbuf + 9, wstr2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcsncpy (wbuf + 7, L"X", 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcsncpy (wbuf + 7, L"X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
@ -546,32 +631,52 @@ do_test (void)
|
||||
wcpncpy (wbuf + 9, L"XABCDEFGH", 8);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcpncpy (wbuf + 6, L"cd", 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcpncpy (wbuf + 6, L"cd", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
wmemcpy (wbuf, wstr1 + 2, l0 + 9);
|
||||
wmemcpy (wbuf, wstr1 + 2, 9);
|
||||
CHK_FAIL_START
|
||||
wcscat (wbuf, L"AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
wmemcpy (wbuf, wstr1 + 3, l0 + 8);
|
||||
wmemcpy (wbuf, wstr1 + 3, 8);
|
||||
CHK_FAIL_START
|
||||
wcsncat (wbuf, L"ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemcpy (wa.buf1 + 1, L"abcdefghij", 10);
|
||||
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, 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemset (wa.buf1 + 9, L'j', 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemset (wa.buf1 + 9, L'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
@ -590,16 +695,20 @@ do_test (void)
|
||||
wp = wcpcpy (wa.buf1 + (O + 8), wstr2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcsncpy (wa.buf1 + (O + 6), L"X", 4);
|
||||
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);
|
||||
wmemcpy (wa.buf1, wstr1 + (3 - O), 8 + O);
|
||||
CHK_FAIL_START
|
||||
wcscat (wa.buf1, L"AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
wmemcpy (wa.buf1, wstr1 + (4 - O), l0 + 7 + O);
|
||||
wmemcpy (wa.buf1, wstr1 + (4 - O), 7 + O);
|
||||
CHK_FAIL_START
|
||||
wcsncat (wa.buf1, L"ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
@ -884,6 +993,11 @@ do_test (void)
|
||||
if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
|
||||
@ -904,6 +1018,12 @@ do_test (void)
|
||||
!= sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
|
||||
!= sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
|
||||
@ -924,6 +1044,12 @@ do_test (void)
|
||||
!= sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
|
||||
!= sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||
@ -1435,23 +1561,38 @@ do_test (void)
|
||||
|
||||
fd_set s;
|
||||
FD_ZERO (&s);
|
||||
|
||||
FD_SET (FD_SETSIZE - 1, &s);
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
FD_SET (FD_SETSIZE, &s);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
FD_SET (l0 + FD_SETSIZE, &s);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
FD_CLR (FD_SETSIZE - 1, &s);
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
FD_CLR (FD_SETSIZE, &s);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
FD_SET (l0 + FD_SETSIZE, &s);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
FD_ISSET (FD_SETSIZE - 1, &s);
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
FD_ISSET (FD_SETSIZE, &s);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
FD_ISSET (l0 + FD_SETSIZE, &s);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
struct pollfd fds[1];
|
||||
@ -1462,12 +1603,20 @@ do_test (void)
|
||||
CHK_FAIL_START
|
||||
poll (fds, 2, 0);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
poll (fds, l0 + 2, 0);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
ppoll (fds, 1, NULL, NULL);
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
ppoll (fds, 2, NULL, NULL);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
ppoll (fds, l0 + 2, NULL, NULL);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
@ -136,7 +136,7 @@ __fortify_function char *
|
||||
__NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||
{
|
||||
if (__bos (__dest) != (size_t) -1
|
||||
&& (!__builtin_constant_p (__n) || __n <= __bos (__dest)))
|
||||
&& (!__builtin_constant_p (__n) || __n > __bos (__dest)))
|
||||
return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||
return __stpncpy_alias (__dest, __src, __n);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user