From 157426f0816f6c7c408f18475aa55b8057f676da Mon Sep 17 00:00:00 2001 From: Yang Yanchao Date: Tue, 30 Apr 2024 10:22:29 +0800 Subject: [PATCH] iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961) Signed-off-by: Yang Yanchao (cherry picked from commit c5850e240269534c8d2e3c22d4176a6765955f8a) --- glibc.spec | 8 +- ...N-EXT-fix-out-of-bound-writes-when-w.patch | 236 ++++++++++++++++++ 2 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch diff --git a/glibc.spec b/glibc.spec index 7d35089..b411316 100644 --- a/glibc.spec +++ b/glibc.spec @@ -62,7 +62,7 @@ ############################################################################## Name: glibc Version: 2.28 -Release: 99 +Release: 100 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -164,6 +164,7 @@ Patch77: backport-CVE-2024-33599-nscd-Stack-based-buffer-overflow-in-netgroup-ca Patch78: backport-CVE-2024-33600-nscd-Do-not-send-missing-not-found-response.patch Patch79: backport-CVE-2024-33600-nscd-Avoid-null-pointer-crash-after-not-found-response.patch Patch80: backport-CVE-2024-33601-CVE-2024-33602-nscd-Use-two-buffer-in-addgetnetgrentX.patch +Patch81: iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch Provides: ldconfig rtld(GNU_HASH) bundled(gnulib) @@ -1280,7 +1281,10 @@ fi %endif %changelog -* Mon Apr 29 2024 chengyechun - 2.38-99 +* Tue Apr 30 2024 Yang Yanchao - 2.28-100 +- iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961) + +* Mon Apr 29 2024 chengyechun - 2.28-99 - Type:CVE - ID:CVE-2024-33599 CVE-2024-33600 CVE-2024-33601 CVE-2024-33602 - SUG:NA diff --git a/iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch b/iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch new file mode 100644 index 0000000..9c1d8e6 --- /dev/null +++ b/iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch @@ -0,0 +1,236 @@ +From 3b741e99d4050fb6b8f76109b042f0ed419788b4 Mon Sep 17 00:00:00 2001 +From: Yang Yanchao +Date: Tue, 23 Apr 2024 10:45:52 +0800 +Subject: [PATCH] iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing + escape sequence (CVE-2024-2961) + +Signed-off-by: Chen Jun +--- + glibc.spec | 6 +- + ...N-EXT-fix-out-of-bound-writes-when-w.patch | 214 ++++++++++++++++++ + 2 files changed, 219 insertions(+), 1 deletion(-) + create mode 100644 iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch + +diff --git a/iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch b/iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch +new file mode 100644 +index 0000000..4e39cca +--- /dev/null ++++ b/iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch +@@ -0,0 +1,214 @@ ++From f9dc609e06b1136bb0408be9605ce7973a767ada Mon Sep 17 00:00:00 2001 ++From: Charles Fol ++Date: Thu, 28 Mar 2024 12:25:38 -0300 ++Subject: [PATCH] iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing ++ escape sequence (CVE-2024-2961) ++ ++ISO-2022-CN-EXT uses escape sequences to indicate character set changes ++(as specified by RFC 1922). While the SOdesignation has the expected ++bounds checks, neither SS2designation nor SS3designation have its; ++allowing a write overflow of 1, 2, or 3 bytes with fixed values: ++'$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'. ++ ++Checked on aarch64-linux-gnu. ++ ++Co-authored-by: Adhemerval Zanella ++Reviewed-by: Carlos O'Donell ++Tested-by: Carlos O'Donell ++--- ++ iconvdata/Makefile | 5 +- ++ iconvdata/iso-2022-cn-ext.c | 12 +++ ++ iconvdata/tst-iconv-iso-2022-cn-ext.c | 128 ++++++++++++++++++++++++++ ++ 3 files changed, 144 insertions(+), 1 deletion(-) ++ create mode 100644 iconvdata/tst-iconv-iso-2022-cn-ext.c ++ ++diff --git a/iconvdata/Makefile b/iconvdata/Makefile ++index ea019ce5c0..7196a8744b 100644 ++--- a/iconvdata/Makefile +++++ b/iconvdata/Makefile ++@@ -75,7 +75,8 @@ 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-iconv15 +++ bug-iconv13 bug-iconv14 bug-iconv15 \ +++ tst-iconv-iso-2022-cn-ext ++ ifeq ($(have-thread-library),yes) ++ tests += bug-iconv3 ++ endif ++@@ -330,6 +331,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \ ++ $(addprefix $(objpfx),$(modules.so)) ++ $(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \ ++ $(addprefix $(objpfx),$(modules.so)) +++$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \ +++ $(addprefix $(objpfx),$(modules.so)) ++ ++ $(objpfx)iconv-test.out: run-iconv-test.sh \ ++ $(addprefix $(objpfx), $(gconv-modules)) \ ++diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c ++index b34c8a36f4..cce29b1969 100644 ++--- a/iconvdata/iso-2022-cn-ext.c +++++ b/iconvdata/iso-2022-cn-ext.c ++@@ -574,6 +574,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); ++ { \ ++ const char *escseq; \ ++ \ +++ if (outptr + 4 > outend) \ +++ { \ +++ result = __GCONV_FULL_OUTPUT; \ +++ break; \ +++ } \ +++ \ ++ assert (used == CNS11643_2_set); /* XXX */ \ ++ escseq = "*H"; \ ++ *outptr++ = ESC; \ ++@@ -587,6 +593,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); ++ { \ ++ const char *escseq; \ ++ \ +++ if (outptr + 4 > outend) \ +++ { \ +++ result = __GCONV_FULL_OUTPUT; \ +++ break; \ +++ } \ +++ \ ++ assert ((used >> 5) >= 3 && (used >> 5) <= 7); \ ++ escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \ ++ *outptr++ = ESC; \ ++diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c ++new file mode 100644 ++index 0000000000..96a8765fd5 ++--- /dev/null +++++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c ++@@ -0,0 +1,128 @@ +++/* Verify ISO-2022-CN-EXT does not write out of the bounds. +++ Copyright (C) 2024 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 +++ . */ +++ +++#include +++#include +++ +++#include +++#include +++#include +++ +++#include +++#include +++#include +++ +++/* The test sets up a two memory page buffer with the second page marked +++ PROT_NONE to trigger a fault if the conversion writes beyond the exact +++ expected amount. Then we carry out various conversions and precisely +++ place the start of the output buffer in order to trigger a SIGSEGV if the +++ process writes anywhere between 1 and page sized bytes more (only one +++ PROT_NONE page is setup as a canary) than expected. These tests exercise +++ all three of the cases in ISO-2022-CN-EXT where the converter must switch +++ character sets and may run out of buffer space while doing the +++ operation. */ +++ +++static int +++do_test (void) +++{ +++ iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8"); +++ TEST_VERIFY_EXIT (cd != (iconv_t) -1); +++ +++ char *ntf; +++ size_t ntfsize; +++ char *outbufbase; +++ { +++ int pgz = getpagesize (); +++ TEST_VERIFY_EXIT (pgz > 0); +++ ntfsize = 2 * pgz; +++ +++ ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE +++ | MAP_ANONYMOUS, -1); +++ xmprotect (ntf + pgz, pgz, PROT_NONE); +++ +++ outbufbase = ntf + pgz; +++ } +++ +++ /* Check if SOdesignation escape sequence does not trigger an OOB write. */ +++ { +++ char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2"; +++ +++ for (int i = 0; i < 9; i++) +++ { +++ char *inp = inbuf; +++ size_t inleft = sizeof (inbuf) - 1; +++ +++ char *outp = outbufbase - i; +++ size_t outleft = i; +++ +++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) +++ == (size_t) -1); +++ TEST_COMPARE (errno, E2BIG); +++ +++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); +++ } +++ } +++ +++ /* Same as before for SS2designation. */ +++ { +++ char inbuf[] = "㴽 \xe3\xb4\xbd"; +++ +++ for (int i = 0; i < 14; i++) +++ { +++ char *inp = inbuf; +++ size_t inleft = sizeof (inbuf) - 1; +++ +++ char *outp = outbufbase - i; +++ size_t outleft = i; +++ +++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) +++ == (size_t) -1); +++ TEST_COMPARE (errno, E2BIG); +++ +++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); +++ } +++ } +++ +++ /* Same as before for SS3designation. */ +++ { +++ char inbuf[] = "劄 \xe5\x8a\x84"; +++ +++ for (int i = 0; i < 14; i++) +++ { +++ char *inp = inbuf; +++ size_t inleft = sizeof (inbuf) - 1; +++ +++ char *outp = outbufbase - i; +++ size_t outleft = i; +++ +++ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) +++ == (size_t) -1); +++ TEST_COMPARE (errno, E2BIG); +++ +++ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); +++ } +++ } +++ +++ TEST_VERIFY_EXIT (iconv_close (cd) != -1); +++ +++ xmunmap (ntf, ntfsize); +++ +++ return 0; +++} +++ +++#include ++-- ++2.33.0 ++ +-- +2.33.0 + -- Gitee