summaryrefslogtreecommitdiff
path: root/libio-Ensure-output-buffer-for-wchars-bug-28828.patch
diff options
context:
space:
mode:
Diffstat (limited to 'libio-Ensure-output-buffer-for-wchars-bug-28828.patch')
-rw-r--r--libio-Ensure-output-buffer-for-wchars-bug-28828.patch110
1 files changed, 110 insertions, 0 deletions
diff --git a/libio-Ensure-output-buffer-for-wchars-bug-28828.patch b/libio-Ensure-output-buffer-for-wchars-bug-28828.patch
new file mode 100644
index 0000000..6cb10d5
--- /dev/null
+++ b/libio-Ensure-output-buffer-for-wchars-bug-28828.patch
@@ -0,0 +1,110 @@
+From edc696a73a7cb07b1aa68792a845a98d036ee7eb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jobol@nonadev.net>
+Date: Tue, 8 Mar 2022 09:58:16 +0100
+Subject: [PATCH] libio: Ensure output buffer for wchars (bug #28828)
+
+The _IO_wfile_overflow does not check if the write pointer for wide
+data is valid before access, different than _IO_file_overflow. This
+leads to crash on some cases, as described by bug 28828.
+
+The minimal sequence to produce the crash was:
+
+ #include <stdio.h>
+ #include <wchar.h>
+ int main (int ac, char **av)
+ {
+ setvbuf (stdout, NULL, _IOLBF, 0);
+ fgetwc (stdin);
+ fputwc (10, stdout); /*CRASH HERE!*/
+ return 0;
+ }
+
+The "fgetwc(stdin);" is necessary since it triggers the bug by setting
+the flag _IO_CURRENTLY_PUTTING on stdout indirectly (file wfileops.c,
+function _IO_wfile_underflow, line 213).
+
+Signed-off-by: Jose Bollo <jobol@nonadev.net>
+---
+ libio/Makefile | 2 +-
+ libio/tst-bz28828.c | 32 ++++++++++++++++++++++++++++++++
+ libio/tst-bz28828.input | 1 +
+ libio/wfileops.c | 3 ++-
+ 4 files changed, 36 insertions(+), 2 deletions(-)
+ create mode 100644 libio/tst-bz28828.c
+ create mode 100644 libio/tst-bz28828.input
+
+diff --git a/libio/Makefile b/libio/Makefile
+index 0e5f348..e973877 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -66,7 +66,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
+ tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
+ tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
+ tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153 \
+- tst-wfile-sync
++ tst-wfile-sync tst-bz28828
+
+ tests-internal = tst-vtables tst-vtables-interposed
+
+diff --git a/libio/tst-bz28828.c b/libio/tst-bz28828.c
+new file mode 100644
+index 0000000..638a6e2
+--- /dev/null
++++ b/libio/tst-bz28828.c
+@@ -0,0 +1,32 @@
++/* Unit test for BZ#28828.
++ Copyright (C) 2022 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <support/xstdio.h>
++#include <support/check.h>
++#include <wchar.h>
++
++static int
++do_test (void)
++{
++ setvbuf (stdout, NULL, _IOLBF, 0);
++ fgetwc (stdin);
++ fputwc (10, stdout); /* It should not crash here. */
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/libio/tst-bz28828.input b/libio/tst-bz28828.input
+new file mode 100644
+index 0000000..ce01362
+--- /dev/null
++++ b/libio/tst-bz28828.input
+@@ -0,0 +1 @@
++hello
+diff --git a/libio/wfileops.c b/libio/wfileops.c
+index fb9d45b..b59a988 100644
+--- a/libio/wfileops.c
++++ b/libio/wfileops.c
+@@ -412,7 +412,8 @@ _IO_wfile_overflow (FILE *f, wint_t wch)
+ return WEOF;
+ }
+ /* If currently reading or no buffer allocated. */
+- if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
++ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0
++ || f->_wide_data->_IO_write_base == NULL)
+ {
+ /* Allocate a buffer if needed. */
+ if (f->_wide_data->_IO_write_base == 0)
+--
+1.8.3.1
+