From 2fedcf1dab7b957313c5c75a47c72eb9e6a2b6f7 Mon Sep 17 00:00:00 2001 From: liqingqing_1229 Date: Tue, 9 Nov 2021 20:27:46 +0800 Subject: [PATCH] gconv: Do not emit spurious NUL character in ISO-2022-JP-3 this is also fix CVE-2021-43396 (cherry picked from commit 9856f5484bd605db15fa0f0da39de0445cbab73c) --- ...t-spurious-NUL-character-in-ISO-2022.patch | 172 ++++++++++++++++++ glibc.spec | 7 +- 2 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 backport-gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch diff --git a/backport-gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch b/backport-gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch new file mode 100644 index 0000000..d085fb9 --- /dev/null +++ b/backport-gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch @@ -0,0 +1,172 @@ +From b9ccd20a34e2b047499446db37ca10905adeffe9 Mon Sep 17 00:00:00 2001 +From: Nikita Popov +Date: Tue, 2 Nov 2021 13:21:42 +0500 +Subject: [PATCH] gconv: Do not emit spurious NUL character in ISO-2022-JP-3 + (bug 28524) + +Bugfix 27256 has introduced another issue: +In conversion from ISO-2022-JP-3 encoding, it is possible +to force iconv to emit extra NUL character on internal state reset. +To do this, it is sufficient to feed iconv with escape sequence +which switches active character set. +The simplified check 'data->__statep->__count != ASCII_set' +introduced by the aforementioned bugfix picks that case and +behaves as if '\0' character has been queued thus emitting it. + +To eliminate this issue, these steps are taken: +* Restore original condition +'(data->__statep->__count & ~7) != ASCII_set'. +It is necessary since bits 0-2 may contain +number of buffered input characters. +* Check that queued character is not NUL. +Similar step is taken for main conversion loop. + +Bundled test case follows following logic: +* Try to convert ISO-2022-JP-3 escape sequence +switching active character set +* Reset internal state by providing NULL as input buffer +* Ensure that nothing has been converted. + +Signed-off-by: Nikita Popov +--- + iconvdata/Makefile | 4 ++- + iconvdata/bug-iconv15.c | 60 +++++++++++++++++++++++++++++++++++++++ + iconvdata/iso-2022-jp-3.c | 27 ++++++++++++------ + 3 files changed, 82 insertions(+), 9 deletions(-) + create mode 100644 iconvdata/bug-iconv15.c + +diff --git a/iconvdata/Makefile b/iconvdata/Makefile +index 38c4f4d1..10614638 100644 +--- a/iconvdata/Makefile ++++ b/iconvdata/Makefile +@@ -74,7 +74,7 @@ ifeq (yes,$(build-shared)) + tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ + tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ + bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \ +- bug-iconv13 bug-iconv14 ++ bug-iconv13 bug-iconv14 bug-iconv15 + ifeq ($(have-thread-library),yes) + tests += bug-iconv3 + endif +@@ -324,6 +324,8 @@ $(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) ++$(objpfx)bug-iconv15.out: $(objpfx)gconv-modules \ ++ $(addprefix $(objpfx),$(modules.so)) + + $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) \ +diff --git a/iconvdata/bug-iconv15.c b/iconvdata/bug-iconv15.c +new file mode 100644 +index 00000000..cc04bd03 +--- /dev/null ++++ b/iconvdata/bug-iconv15.c +@@ -0,0 +1,60 @@ ++/* Bug 28524: Conversion from ISO-2022-JP-3 with iconv ++ may emit spurious NUL character on state reset. ++ Copyright (C) The GNU Toolchain Authors. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char in[] = "\x1b(I"; ++ char *inbuf = in; ++ size_t inleft = sizeof (in) - 1; ++ char out[1]; ++ char *outbuf = out; ++ size_t outleft = sizeof (out); ++ iconv_t cd; ++ ++ cd = iconv_open ("UTF8", "ISO-2022-JP-3"); ++ TEST_VERIFY_EXIT (cd != (iconv_t) -1); ++ ++ /* First call to iconv should alter internal state. ++ Now, JISX0201_Kana_set is selected and ++ state value != ASCII_set. */ ++ TEST_VERIFY (iconv (cd, &inbuf, &inleft, &outbuf, &outleft) != (size_t) -1); ++ ++ /* No bytes should have been added to ++ the output buffer at this point. */ ++ TEST_VERIFY (outbuf == out); ++ TEST_VERIFY (outleft == sizeof (out)); ++ ++ /* Second call shall emit spurious NUL character in unpatched glibc. */ ++ TEST_VERIFY (iconv (cd, NULL, NULL, &outbuf, &outleft) != (size_t) -1); ++ ++ /* No characters are expected to be produced. */ ++ TEST_VERIFY (outbuf == out); ++ TEST_VERIFY (outleft == sizeof (out)); ++ ++ TEST_VERIFY_EXIT (iconv_close (cd) != -1); ++ ++ return 0; ++} ++ ++#include +diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c +index 047fab8e..a37895cc 100644 +--- a/iconvdata/iso-2022-jp-3.c ++++ b/iconvdata/iso-2022-jp-3.c +@@ -81,20 +81,31 @@ enum + the output state to the initial state. This has to be done during the + flushing. */ + #define EMIT_SHIFT_TO_INIT \ +- if (data->__statep->__count != ASCII_set) \ ++ if ((data->__statep->__count & ~7) != ASCII_set) \ + { \ + if (FROM_DIRECTION) \ + { \ +- if (__glibc_likely (outbuf + 4 <= outend)) \ ++ uint32_t ch = data->__statep->__count >> 6; \ ++ \ ++ if (__glibc_unlikely (ch != 0)) \ + { \ +- /* Write out the last character. */ \ +- *((uint32_t *) outbuf) = data->__statep->__count >> 6; \ +- outbuf += sizeof (uint32_t); \ +- data->__statep->__count = ASCII_set; \ ++ if (__glibc_likely (outbuf + 4 <= outend)) \ ++ { \ ++ /* Write out the last character. */ \ ++ put32u (outbuf, ch); \ ++ outbuf += 4; \ ++ data->__statep->__count &= 7; \ ++ data->__statep->__count |= ASCII_set; \ ++ } \ ++ else \ ++ /* We don't have enough room in the output buffer. */ \ ++ status = __GCONV_FULL_OUTPUT; \ + } \ + else \ +- /* We don't have enough room in the output buffer. */ \ +- status = __GCONV_FULL_OUTPUT; \ ++ { \ ++ data->__statep->__count &= 7; \ ++ data->__statep->__count |= ASCII_set; \ ++ } \ + } \ + else \ + { \ +-- +2.23.0 + diff --git a/glibc.spec b/glibc.spec index 1308013..5723897 100644 --- a/glibc.spec +++ b/glibc.spec @@ -59,7 +59,7 @@ ############################################################################## Name: glibc Version: 2.28 -Release: 78 +Release: 79 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -137,6 +137,7 @@ Patch53: backport-CVE-2021-38604-0001-librt-add-test-bug-28213.patch Patch54: backport-CVE-2021-38604-0002-librt-fix-null-pointer-deference.patch Patch55: backport-ldconfig-avoid-leak-on-empty-paths-in-config-file.patch Patch56: backport-rtld-copy-terminating-null-in-tunables_strdup-bug-28.patch +Patch57: backport-gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch Provides: ldconfig rtld(GNU_HASH) bundled(gnulib) @@ -1161,6 +1162,10 @@ fi %doc hesiod/README.hesiod %changelog +* Tue Nov 9 2021 Qingqing Li - 2.28-79 +- gconv: Do not emit spurious NUL character in ISO-2022-JP-3 + this is also fix CVE-2021-43396 + * Wed Sep 29 2021 Lv Ying - 2.28-78 - ldconfig: avoid leak on empty paths in config file https://sourceware.org/git/?p=glibc.git;a=commit;h=a4f5a3103fc3e7974dbe35b411cba9f670807cde -- Gitee