glibc/libio
Peter Ammon 18596c5415 libio: Fix crash in fputws [BZ #20632]
This fixes a buffer overflow in wide character string output, reproducing
when output fails, such as if the output fd is closed or is redirected
to a full device.

Wide character output data attempts to maintain the invariant that
`_IO_buf_base <= _IO_write_base <= _IO_write_end <= _IO_buf_end` (that is,
that the write region is a sub-region of `_IO_buf`). Prior to this commit,
this invariant is violated by the `_IO_wfile_overflow` function as so:

1. `_IO_wsetg` is called, assigning `_IO_write_base` to `_IO_buf_base`
2. `_IO_doallocbuf` is called, which jumps to `_IO_wfile_doallocate` via
    the _IO_wfile_jumps vtable. This function then assigns the wide data
    `_IO_buf_base` and `_IO_buf_end` to a malloc'd buffer.

Thus the invariant is violated. The fix is simply to reverse the order:
malloc the `_IO_buf` first and then assign `_IO_write_base` to it.

We also take this opportunity to defensively guard the initialization of
the number of unwritten characters via pointer arithmetic. We now check
that the buffer end is not before the buffer beginning; this matches a
similar defensive check in the narrow analogue `fileops.c`.

Add a test which fails without the fix.

Signed-off-by: Peter Ammon <corydoras@ridiculousfish.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2024-10-25 15:05:06 -03:00
..
bits
__fbufsize.c
__flbf.c
__fpending.c
__fpurge.c
__freadable.c
__freading.c
__fsetlocking.c
__fwritable.c
__fwriting.c
bug-fopena+.c
bug-fseek.c
bug-ftell.c
bug-memstream1.c
bug-mmap-fflush.c
bug-rewind2.c
bug-rewind.c
bug-ungetc2.c
bug-ungetc3.c
bug-ungetc4.c
bug-ungetc.c
bug-ungetwc1.c
bug-ungetwc2.c
bug-wfflush.c
bug-wmemstream1.c
bug-wsetpos.c
clearerr_u.c
clearerr.c
Depend
fcloseall.c
feof_u.c
feof.c
ferror_u.c
ferror.c
filedoalloc.c
fileno.c
fileops.c
fmemopen.c
fputc_u.c
fputc.c
fputwc_u.c
fputwc.c
freopen64.c Fix freopen handling of ,ccs= (bug 23675) 2024-09-05 20:08:10 +00:00
freopen.c Fix freopen handling of ,ccs= (bug 23675) 2024-09-05 20:08:10 +00:00
fseek.c
fseeko64.c
fseeko.c
ftello64.c
ftello.c
fwide.c
fwprintf.c
fwscanf.c
genops.c
getc_u.c
getc.c
getchar_u.c
getchar.c
getwc_u.c
getwc.c
getwchar_u.c
getwchar.c
iofclose.c
iofdopen.c
iofflush_u.c
iofflush.c
iofgetpos64.c
iofgetpos.c
iofgets_u.c
iofgets.c
iofgetws_u.c
iofgetws.c
iofopen64.c
iofopen.c
iofopncook.c
iofputs_u.c
iofputs.c
iofputws_u.c
iofputws.c
iofread_u.c
iofread.c
iofsetpos64.c
iofsetpos.c
ioftell.c
iofwide.c
iofwrite_u.c
iofwrite.c
iogetdelim.c
iogetline.c
iogets.c
iogetwline.c
iolibio.h
iopadn.c
iopopen.c libio: Fix a deadlock after fork in popen 2024-10-23 13:40:16 +02:00
ioputs.c
ioseekoff.c
ioseekpos.c
iosetbuffer.c
iosetvbuf.c
ioungetc.c
ioungetwc.c
iovdprintf.c
iovsprintf.c
iovsscanf.c
iovswscanf.c
iowpadn.c
libc_fatal.c
libio-macros.sym
libio.h
libioP.h libio: Fix a deadlock after fork in popen 2024-10-23 13:40:16 +02:00
Makefile libio: Fix crash in fputws [BZ #20632] 2024-10-25 15:05:06 -03:00
memstream.c
obprintf.c
oldfileops.c libio: Set _vtable_offset before calling _IO_link_in [BZ #32148] 2024-10-01 07:31:25 +08:00
oldfmemopen.c
oldiofclose.c
oldiofdopen.c
oldiofgetpos64.c
oldiofgetpos.c
oldiofopen.c
oldiofsetpos64.c
oldiofsetpos.c
oldiopopen.c
oldpclose.c
oldstdfiles.c
oldtmpfile.c
pclose.c
peekc.c
putc_u.c
putc.c
putchar_u.c
putchar.c
putwc_u.c
putwc.c
putwchar_u.c
putwchar.c
rewind.c
setbuf.c
setlinebuf.c
stdfiles.c
stdio.c
stdio.h
strfile.h
strops.c
swprintf.c
swscanf.c
test-fmemopen.c
test-fputs-unbuffered-full.c libio: Fix crash in fputws [BZ #20632] 2024-10-25 15:05:06 -03:00
test-fputws-unbuffered-full.c libio: Fix crash in fputws [BZ #20632] 2024-10-25 15:05:06 -03:00
test-freopen.c
test-freopen.sh
tst_getwc.c
tst_getwc.input
tst_putwc.c
tst_swprintf.c
tst_swscanf.c
tst_wprintf2.c
tst_wprintf.c
tst_wscanf.c
tst_wscanf.input
tst-atime.c
tst-bz22415.c
tst-bz24051.c
tst-bz24153.c
tst-bz24228.c
tst-bz24228.map
tst-bz28828.c
tst-bz28828.input
tst-cleanup-default-static.c
tst-cleanup-default.c
tst-cleanup-nostart-stop-gc-static.c
tst-cleanup-nostart-stop-gc.c
tst-cleanup-start-stop-gc-static.c
tst-cleanup-start-stop-gc.c
tst-cleanup.c
tst-cleanup.exp
tst-closeall.c
tst-eof.c
tst-ext2.c
tst-ext.c
tst-fclose-unopened2.c Add another test for fclose on an unopened file 2024-09-20 10:32:35 -04:00
tst-fclose-unopened2.input Add another test for fclose on an unopened file 2024-09-20 10:32:35 -04:00
tst-fclose-unopened.c Add another test for fclose on an unopened file 2024-09-20 10:32:35 -04:00
tst-fdopen-seek-failure.c
tst-fgetc-after-eof.c
tst-fgetwc.c
tst-fgetwc.input
tst-fgetws.c
tst-fopen-compat.c libio: Set _vtable_offset before calling _IO_link_in [BZ #32148] 2024-10-01 07:31:25 +08:00
tst-fopenloc2.c
tst-fopenloc.c
tst-fputws.c
tst-freopen.c
tst-fseek.c
tst-ftell-active-handler.c
tst-ftell-append.c
tst-ftell-partial-wide.c
tst-fwrite-error.c
tst-getdelim.c
tst-memstream1.c
tst-memstream2.c
tst-memstream3.c
tst-memstream4.c
tst-memstream.h
tst-mmap2-eofsync.c
tst-mmap-eofsync.c
tst-mmap-fflushsync.c
tst-mmap-offend.c
tst-mmap-setvbuf.c
tst-popen1.c
tst-popen-fork.c libio: Fix a deadlock after fork in popen 2024-10-23 13:40:16 +02:00
tst-setvbuf1.c
tst-sprintf-chk-ub.c
tst-sprintf-ub.c
tst-sscanf.c
tst-stderr-compat.c
tst-swscanf.c
tst-ungetwc1.c
tst-ungetwc2.c
tst-vtables-common.c
tst-vtables-interposed.c
tst-vtables.c
tst-wfile-sync.c
tst-widetext.c
tst-widetext.input
tst-wmemstream1.c
tst-wmemstream2.c
tst-wmemstream3.c
tst-wmemstream4.c
tst-wmemstream5.c
vasprintf.c
Versions
vscanf.c
vsnprintf.c
vswprintf.c
vtables.c
vwprintf.c
vwscanf.c
wfiledoalloc.c
wfileops.c libio: Fix crash in fputws [BZ #20632] 2024-10-25 15:05:06 -03:00
wgenops.c
wmemstream.c
wprintf.c
wscanf.c
wstrops.c