diff options
author | Zack Weinberg <zackw@panix.com> | 2018-03-07 14:32:03 -0500 |
---|---|---|
committer | Gabriel F. T. Gomes <gabriel@inconstante.eti.br> | 2018-12-05 18:15:43 -0200 |
commit | 4e2f43f842ef5e253cc23383645adbaa03cedb86 (patch) | |
tree | ca359423ba6ed4bb4d5ec247905a6ee13d456864 /debug | |
parent | 124fc732c15ef37b7ee9db25b1e9f9b20c799623 (diff) | |
download | glibc-4e2f43f842ef5e253cc23383645adbaa03cedb86.tar.gz glibc-4e2f43f842ef5e253cc23383645adbaa03cedb86.tar.xz glibc-4e2f43f842ef5e253cc23383645adbaa03cedb86.zip |
Use PRINTF_FORTIFY instead of _IO_FLAGS2_FORTIFY (bug 11319)
The _chk variants of all of the printf functions become much simpler. This is the last thing that we needed _IO_acquire_lock_clear_flags2 for, so it can go as well. I took the opportunity to make the headers included and the names of all local variables consistent across all the affected files. Since we ultimately want to get rid of __no_long_double as well, it must be possible to get all of the nontrivial effects of the _chk functions by calling the _internal functions with appropriate flags. For most of the __(v)xprintf_chk functions, this is covered by PRINTF_FORTIFY plus some up-front argument checks that can be duplicated. However, __(v)sprintf_chk installs a custom jump table so that it can crash instead of overflowing the output buffer. This functionality is moved to __vsprintf_internal, which now has a 'maxlen' argument like __vsnprintf_internal; to get the unsafe behavior of ordinary (v)sprintf, pass -1 for that argument. obstack_printf_chk and obstack_vprintf_chk are no longer in the same file. As a side-effect of the unification of both fortified and non-fortified vdprintf initialization, this patch fixes bug 11319 for __dprintf_chk and __vdprintf_chk, which was previously fixed only for dprintf and vdprintf by the commit commit 7ca890b88e6ab7624afb1742a9fffb37ad5b3fc3 Author: Ulrich Drepper <drepper@redhat.com> Date: Wed Feb 24 16:07:57 2010 -0800 Fix reporting of I/O errors in *dprintf functions. This patch adds a test case to avoid regressions. Tested for powerpc and powerpc64le.
Diffstat (limited to 'debug')
-rw-r--r-- | debug/Makefile | 2 | ||||
-rw-r--r-- | debug/asprintf_chk.c | 20 | ||||
-rw-r--r-- | debug/dprintf_chk.c | 20 | ||||
-rw-r--r-- | debug/fprintf_chk.c | 20 | ||||
-rw-r--r-- | debug/fwprintf_chk.c | 20 | ||||
-rw-r--r-- | debug/obprintf_chk.c | 96 | ||||
-rw-r--r-- | debug/printf_chk.c | 20 | ||||
-rw-r--r-- | debug/snprintf_chk.c | 24 | ||||
-rw-r--r-- | debug/sprintf_chk.c | 25 | ||||
-rw-r--r-- | debug/swprintf_chk.c | 27 | ||||
-rw-r--r-- | debug/vasprintf_chk.c | 68 | ||||
-rw-r--r-- | debug/vdprintf_chk.c | 37 | ||||
-rw-r--r-- | debug/vfprintf_chk.c | 21 | ||||
-rw-r--r-- | debug/vfwprintf_chk.c | 21 | ||||
-rw-r--r-- | debug/vobprintf_chk.c | 31 | ||||
-rw-r--r-- | debug/vprintf_chk.c | 20 | ||||
-rw-r--r-- | debug/vsnprintf_chk.c | 46 | ||||
-rw-r--r-- | debug/vsprintf_chk.c | 69 | ||||
-rw-r--r-- | debug/vswprintf_chk.c | 51 | ||||
-rw-r--r-- | debug/vwprintf_chk.c | 21 | ||||
-rw-r--r-- | debug/wprintf_chk.c | 21 |
21 files changed, 187 insertions, 493 deletions
diff --git a/debug/Makefile b/debug/Makefile index 506cebc3c4..2ef08cf23b 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -45,7 +45,7 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \ gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \ wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \ wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \ - vdprintf_chk obprintf_chk \ + vdprintf_chk obprintf_chk vobprintf_chk \ longjmp_chk ____longjmp_chk \ fdelt_chk poll_chk ppoll_chk \ explicit_bzero_chk \ diff --git a/debug/asprintf_chk.c b/debug/asprintf_chk.c index 9cd4143f2e..eb885c35ca 100644 --- a/debug/asprintf_chk.c +++ b/debug/asprintf_chk.c @@ -15,22 +15,24 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <libioP.h> #include <stdarg.h> -#include <stdio.h> +#include <libio/libioP.h> /* Write formatted output from FORMAT to a string which is allocated with malloc and stored in *STRING_PTR. */ int -__asprintf_chk (char **result_ptr, int flags, const char *format, ...) +__asprintf_chk (char **result_ptr, int flag, const char *format, ...) { - va_list arg; - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - va_start (arg, format); - done = __vasprintf_chk (result_ptr, flags, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vasprintf_internal (result_ptr, format, ap, mode); + va_end (ap); - return done; + return ret; } diff --git a/debug/dprintf_chk.c b/debug/dprintf_chk.c index df3867c61c..b5c62827c0 100644 --- a/debug/dprintf_chk.c +++ b/debug/dprintf_chk.c @@ -15,21 +15,23 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <libioP.h> #include <stdarg.h> -#include <stdio.h> +#include <libio/libioP.h> /* Write formatted output to D, according to the format string FORMAT. */ int -__dprintf_chk (int d, int flags, const char *format, ...) +__dprintf_chk (int d, int flag, const char *format, ...) { - va_list arg; - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - va_start (arg, format); - done = __vdprintf_chk (d, flags, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vdprintf_internal (d, format, ap, mode); + va_end (ap); - return done; + return ret; } diff --git a/debug/fprintf_chk.c b/debug/fprintf_chk.c index cff4438afb..14afc073b2 100644 --- a/debug/fprintf_chk.c +++ b/debug/fprintf_chk.c @@ -16,29 +16,23 @@ <http://www.gnu.org/licenses/>. */ #include <stdarg.h> -#include <stdio.h> -#include "../libio/libioP.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, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = vfprintf (fp, format, ap); + ret = __vfprintf_internal (fp, format, ap, mode); va_end (ap); - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return ret; } ldbl_strong_alias (___fprintf_chk, __fprintf_chk) diff --git a/debug/fwprintf_chk.c b/debug/fwprintf_chk.c index 63167c1839..10d84ce98b 100644 --- a/debug/fwprintf_chk.c +++ b/debug/fwprintf_chk.c @@ -16,28 +16,22 @@ <http://www.gnu.org/licenses/>. */ #include <stdarg.h> -#include <wchar.h> -#include "../libio/libioP.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, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = __vfwprintf_internal (fp, format, ap, 0); + ret = __vfwprintf_internal (fp, format, ap, mode); va_end (ap); - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return ret; } diff --git a/debug/obprintf_chk.c b/debug/obprintf_chk.c index 41dd481c34..c1a8f9e9a9 100644 --- a/debug/obprintf_chk.c +++ b/debug/obprintf_chk.c @@ -17,99 +17,23 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ - -#include <stdlib.h> -#include <libioP.h> -#include "../libio/strfile.h" -#include <assert.h> -#include <string.h> -#include <errno.h> -#include <obstack.h> +#include <libio/libioP.h> #include <stdarg.h> -#include <stdio_ext.h> - - -struct _IO_obstack_file -{ - struct _IO_FILE_plus file; - struct obstack *obstack; -}; - -extern const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden; - -int -__obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format, - va_list args) -{ - struct obstack_FILE - { - struct _IO_obstack_file ofile; - } new_f; - int result; - int size; - int room; - -#ifdef _IO_MTSAFE_IO - new_f.ofile.file.file._lock = NULL; -#endif - - _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; - room = obstack_room (obstack); - size = obstack_object_size (obstack) + room; - if (size == 0) - { - /* We have to handle the allocation a bit different since the - `_IO_str_init_static' function would handle a size of zero - different from what we expect. */ - - /* Get more memory. */ - obstack_make_room (obstack, 64); - - /* Recompute how much room we have. */ - room = obstack_room (obstack); - size = room; - - assert (size != 0); - } - - _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile, - obstack_base (obstack), - size, obstack_next_free (obstack)); - /* Now allocate the rest of the current chunk. */ - assert (size == (new_f.ofile.file.file._IO_write_end - - new_f.ofile.file.file._IO_write_base)); - assert (new_f.ofile.file.file._IO_write_ptr - == (new_f.ofile.file.file._IO_write_base - + obstack_object_size (obstack))); - obstack_blank_fast (obstack, room); - - new_f.ofile.obstack = obstack; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n - can only come from read-only format strings. */ - if (flags > 0) - new_f.ofile.file.file._flags2 |= _IO_FLAGS2_FORTIFY; - - result = __vfprintf_internal (&new_f.ofile.file.file, format, args, 0); - - /* Shrink the buffer to the space we really currently need. */ - obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr - - new_f.ofile.file.file._IO_write_end)); - - return result; -} -libc_hidden_def (__obstack_vprintf_chk) int -__obstack_printf_chk (struct obstack *obstack, int flags, const char *format, +__obstack_printf_chk (struct obstack *obstack, int flag, const char *format, ...) { - int result; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; + int ret; + va_start (ap, format); - result = __obstack_vprintf_chk (obstack, flags, format, ap); + ret = __obstack_vprintf_internal (obstack, format, ap, mode); va_end (ap); - return result; + + return ret; } diff --git a/debug/printf_chk.c b/debug/printf_chk.c index 426dc78386..e035b42590 100644 --- a/debug/printf_chk.c +++ b/debug/printf_chk.c @@ -16,29 +16,23 @@ <http://www.gnu.org/licenses/>. */ #include <stdarg.h> -#include <stdio.h> -#include "../libio/libioP.h" +#include <libio/libioP.h> /* Write formatted output to stdout from the format string FORMAT. */ int ___printf_chk (int flag, const char *format, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = vfprintf (stdout, format, ap); + ret = __vfprintf_internal (stdout, format, ap, mode); va_end (ap); - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return ret; } ldbl_strong_alias (___printf_chk, __printf_chk) diff --git a/debug/snprintf_chk.c b/debug/snprintf_chk.c index cddba37109..984b5e8932 100644 --- a/debug/snprintf_chk.c +++ b/debug/snprintf_chk.c @@ -15,25 +15,29 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <libioP.h> #include <stdarg.h> -#include <stdio.h> +#include <libio/libioP.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, +___snprintf_chk (char *s, size_t maxlen, int flag, size_t slen, const char *format, ...) { - va_list arg; - int done; + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); - va_start (arg, format); - done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg); - va_end (arg); + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - return done; + va_start (ap, format); + ret = __vsnprintf_internal (s, maxlen, format, ap, mode); + va_end (ap); + + return ret; } ldbl_strong_alias (___snprintf_chk, __snprintf_chk) diff --git a/debug/sprintf_chk.c b/debug/sprintf_chk.c index 78214563dd..649e8ab4d5 100644 --- a/debug/sprintf_chk.c +++ b/debug/sprintf_chk.c @@ -15,22 +15,27 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <libioP.h> #include <stdarg.h> -#include <stdio.h> +#include <libio/libioP.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, ...) +___sprintf_chk (char *s, int flag, size_t slen, const char *format, ...) { - va_list arg; - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; + + if (slen == 0) + __chk_fail (); - va_start (arg, format); - done = __vsprintf_chk (s, flags, slen, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vsprintf_internal (s, slen, format, ap, mode); + va_end (ap); - return done; + return ret; } ldbl_strong_alias (___sprintf_chk, __sprintf_chk) diff --git a/debug/swprintf_chk.c b/debug/swprintf_chk.c index 35887e48e2..186c17751c 100644 --- a/debug/swprintf_chk.c +++ b/debug/swprintf_chk.c @@ -16,20 +16,27 @@ <http://www.gnu.org/licenses/>. */ #include <stdarg.h> -#include <wchar.h> +#include <libio/libioP.h> -/* Write formatted output into S, according to the format string FORMAT. */ -/* VARARGS5 */ + +/* Write formatted output into S, according to the format string FORMAT, + writing no more than MAXLEN characters. */ int -__swprintf_chk (wchar_t *s, size_t n, int flag, size_t s_len, +__swprintf_chk (wchar_t *s, size_t maxlen, int flag, size_t slen, const wchar_t *format, ...) { - va_list arg; - int done; + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - va_start (arg, format); - done = __vswprintf_chk (s, n, flag, s_len, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vswprintf_internal (s, maxlen, format, ap, mode); + va_end (ap); - return done; + return ret; } diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c index dbfebff83f..f5975ea02a 100644 --- a/debug/vasprintf_chk.c +++ b/debug/vasprintf_chk.c @@ -24,72 +24,14 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include <malloc.h> -#include <string.h> -#include <stdio.h> -#include <stdio_ext.h> -#include "../libio/libioP.h" -#include "../libio/strfile.h" +#include <libio/libioP.h> int -__vasprintf_chk (char **result_ptr, int flags, const char *format, - va_list args) +__vasprintf_chk (char **result_ptr, int flag, const char *format, va_list ap) { - /* Initial size of the buffer to be used. Will be doubled each time an - overflow occurs. */ - const size_t init_string_size = 100; - char *string; - _IO_strfile sf; - int ret; - size_t needed; - size_t allocated; - /* No need to clear the memory here (unlike for open_memstream) since - we know we will never seek on the stream. */ - string = (char *) malloc (init_string_size); - if (string == NULL) - return -1; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; - _IO_str_init_static_internal (&sf, string, init_string_size, string); - sf._sbf._f._flags &= ~_IO_USER_BUF; - sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc; - sf._s._free_buffer_unused = (_IO_free_type) free; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ - if (flags > 0) - sf._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - ret = __vfprintf_internal (&sf._sbf._f, format, args, 0); - if (ret < 0) - { - free (sf._sbf._f._IO_buf_base); - return ret; - } - /* Only use realloc if the size we need is of the same (binary) - order of magnitude then the memory we allocated. */ - needed = sf._sbf._f._IO_write_ptr - sf._sbf._f._IO_write_base + 1; - allocated = sf._sbf._f._IO_write_end - sf._sbf._f._IO_write_base; - if ((allocated >> 1) <= needed) - *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); - else - { - *result_ptr = (char *) malloc (needed); - if (*result_ptr != NULL) - { - memcpy (*result_ptr, sf._sbf._f._IO_buf_base, needed - 1); - free (sf._sbf._f._IO_buf_base); - } - else - /* We have no choice, use the buffer we already have. */ - *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); - } - if (*result_ptr == NULL) - *result_ptr = sf._sbf._f._IO_buf_base; - (*result_ptr)[needed - 1] = '\0'; - return ret; + return __vasprintf_internal (result_ptr, format, ap, mode); } -libc_hidden_def (__vasprintf_chk) diff --git a/debug/vdprintf_chk.c b/debug/vdprintf_chk.c index 4386127cfe..e04514e355 100644 --- a/debug/vdprintf_chk.c +++ b/debug/vdprintf_chk.c @@ -24,41 +24,14 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include <libioP.h> -#include <stdio_ext.h> +#include <libio/libioP.h> int -__vdprintf_chk (int d, int flags, const char *format, va_list arg) +__vdprintf_chk (int d, int flag, const char *format, va_list ap) { - struct _IO_FILE_plus tmpfil; - struct _IO_wide_data wd; - int done; - -#ifdef _IO_MTSAFE_IO - tmpfil.file._lock = NULL; -#endif - _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); - _IO_JUMPS (&tmpfil) = &_IO_file_jumps; - _IO_new_file_init_internal (&tmpfil); - if (_IO_file_attach (&tmpfil.file, d) == NULL) - { - _IO_un_link (&tmpfil); - return EOF; - } - tmpfil.file._flags |= _IO_DELETE_DONT_CLOSE; - - _IO_mask_flags (&tmpfil.file, _IO_NO_READS, - _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ - if (flags > 0) - tmpfil.file._flags2 |= _IO_FLAGS2_FORTIFY; - - done = __vfprintf_internal (&tmpfil.file, format, arg, 0); - - _IO_FINISH (&tmpfil.file); + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - return done; + return __vdprintf_internal (d, format, ap, mode); } -libc_hidden_def (__vdprintf_chk) diff --git a/debug/vfprintf_chk.c b/debug/vfprintf_chk.c index 5babbf611e..44426e14fd 100644 --- a/debug/vfprintf_chk.c +++ b/debug/vfprintf_chk.c @@ -15,28 +15,17 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <stdio.h> -#include "../libio/libioP.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; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = vfprintf (fp, format, ap); - - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return __vfprintf_internal (fp, format, ap, mode); } -ldbl_hidden_def (___vfprintf_chk, __vfprintf_chk) ldbl_strong_alias (___vfprintf_chk, __vfprintf_chk) diff --git a/debug/vfwprintf_chk.c b/debug/vfwprintf_chk.c index abf2bd6517..3aed308156 100644 --- a/debug/vfwprintf_chk.c +++ b/debug/vfwprintf_chk.c @@ -15,27 +15,16 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <wchar.h> -#include "../libio/libioP.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; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = __vfwprintf_internal (fp, format, ap, 0); - - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return __vfwprintf_internal (fp, format, ap, mode); } -libc_hidden_def (__vfwprintf_chk) diff --git a/debug/vobprintf_chk.c b/debug/vobprintf_chk.c new file mode 100644 index 0000000000..bed2c98eac --- /dev/null +++ b/debug/vobprintf_chk.c @@ -0,0 +1,31 @@ +/* Print output of stream to given obstack. + Copyright (C) 2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <libio/libioP.h> + + +int +__obstack_vprintf_chk (struct obstack *obstack, int flag, const char *format, + va_list ap) +{ + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + + return __obstack_vprintf_internal (obstack, format, ap, mode); +} diff --git a/debug/vprintf_chk.c b/debug/vprintf_chk.c index b3b2c53df2..69fcb721ac 100644 --- a/debug/vprintf_chk.c +++ b/debug/vprintf_chk.c @@ -15,27 +15,17 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <stdio.h> -#include "../libio/libioP.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; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = vfprintf (stdout, format, ap); - - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return __vfprintf_internal (stdout, format, ap, mode); } ldbl_strong_alias (___vprintf_chk, __vprintf_chk) diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c index 95d286f416..666a83b701 100644 --- a/debug/vsnprintf_chk.c +++ b/debug/vsnprintf_chk.c @@ -15,56 +15,22 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <stdio.h> -#include "../libio/libioP.h" -#include "../libio/strfile.h" +#include <libio/libioP.h> -extern const struct _IO_jump_t _IO_strn_jumps libio_vtable 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) +___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t slen, + const char *format, va_list ap) { - /* 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 (__glibc_unlikely (slen < maxlen)) __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 (&sf.f._sbf) = &_IO_strn_jumps; - s[0] = '\0'; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 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_str_init_static_internal (&sf.f, s, maxlen - 1, s); - ret = __vfprintf_internal (&sf.f._sbf._f, format, args, 0); + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) - *sf.f._sbf._f._IO_write_ptr = '\0'; - return ret; + return __vsnprintf_internal (s, maxlen, format, ap, mode); } -ldbl_hidden_def (___vsnprintf_chk, __vsnprintf_chk) ldbl_strong_alias (___vsnprintf_chk, __vsnprintf_chk) diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c index 53f07236ae..c1b1a8da4f 100644 --- a/debug/vsprintf_chk.c +++ b/debug/vsprintf_chk.c @@ -15,75 +15,20 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <stdio.h> -#include "../libio/libioP.h" -#include "../libio/strfile.h" - - -static int _IO_str_chk_overflow (FILE *fp, int c) __THROW; - -static int -_IO_str_chk_overflow (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 libio_vtable = -{ - JUMP_INIT_DUMMY, - JUMP_INIT(finish, _IO_str_finish), - JUMP_INIT(overflow, _IO_str_chk_overflow), - JUMP_INIT(underflow, _IO_str_underflow), - JUMP_INIT(uflow, _IO_default_uflow), - JUMP_INIT(pbackfail, _IO_str_pbackfail), - JUMP_INIT(xsputn, _IO_default_xsputn), - JUMP_INIT(xsgetn, _IO_default_xsgetn), - JUMP_INIT(seekoff, _IO_str_seekoff), - JUMP_INIT(seekpos, _IO_default_seekpos), - JUMP_INIT(setbuf, _IO_default_setbuf), - JUMP_INIT(sync, _IO_default_sync), - JUMP_INIT(doallocate, _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) -}; - +#include <libio/libioP.h> int -___vsprintf_chk (char *s, int flags, size_t slen, const char *format, - va_list args) +___vsprintf_chk (char *s, int flag, size_t slen, const char *format, + va_list ap) { - _IO_strfile f; - int ret; -#ifdef _IO_MTSAFE_IO - f._sbf._f._lock = NULL; -#endif + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; if (slen == 0) __chk_fail (); - _IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&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_FORTIFY; - - ret = __vfprintf_internal (&f._sbf._f, format, args, 0); - - *f._sbf._f._IO_write_ptr = '\0'; - return ret; + return __vsprintf_internal (s, slen, format, ap, mode); } ldbl_hidden_def (___vsprintf_chk, __vsprintf_chk) ldbl_strong_alias (___vsprintf_chk, __vsprintf_chk) diff --git a/debug/vswprintf_chk.c b/debug/vswprintf_chk.c index 4d616f8835..2c6fadd463 100644 --- a/debug/vswprintf_chk.c +++ b/debug/vswprintf_chk.c @@ -15,60 +15,21 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <wchar.h> -#include "../libio/libioP.h" -#include "../libio/strfile.h" +#include <libio/libioP.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) +__vswprintf_chk (wchar_t *s, size_t maxlen, int flag, size_t slen, + const wchar_t *format, va_list ap) { - /* 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 (__glibc_unlikely (slen < maxlen)) __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 (__glibc_unlikely (maxlen == 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 + /* For flag > 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 = __vfwprintf_internal ((FILE *) &sf.f._sbf, format, args, 0); - - 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'; + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - return ret; + return __vswprintf_internal (s, maxlen, format, ap, mode); } -libc_hidden_def (__vswprintf_chk) diff --git a/debug/vwprintf_chk.c b/debug/vwprintf_chk.c index fedc7a46bf..f1e8878a54 100644 --- a/debug/vwprintf_chk.c +++ b/debug/vwprintf_chk.c @@ -15,27 +15,16 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <stdio.h> -#include <wchar.h> -#include "../libio/libioP.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; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = __vfwprintf_internal (stdout, format, ap, 0); - - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return __vfwprintf_internal (stdout, format, ap, mode); } diff --git a/debug/wprintf_chk.c b/debug/wprintf_chk.c index 819050e5af..9f406e95f8 100644 --- a/debug/wprintf_chk.c +++ b/debug/wprintf_chk.c @@ -16,29 +16,22 @@ <http://www.gnu.org/licenses/>. */ #include <stdarg.h> -#include <stdio.h> -#include <wchar.h> -#include "../libio/libioP.h" +#include <libio/libioP.h> /* Write formatted output to stdout from the format string FORMAT. */ int __wprintf_chk (int flag, const wchar_t *format, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = __vfwprintf_internal (stdout, format, ap, 0); + ret = __vfwprintf_internal (stdout, format, ap, mode); va_end (ap); - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return ret; } |