wok-current view glibc/stuff/glibc-2.28-CVE-2024-2961.patch @ rev 25775
Patch glibc (CVE-2025-4802)
| author | Stanislas Leduc <shann@slitaz.org> |
|---|---|
| date | Thu May 22 19:19:31 2025 +0000 (5 months ago) |
| parents | 12b90a723e05 |
| children |
line source
1 From 682ad4c8623e611a971839990ceef00346289cc9 Mon Sep 17 00:00:00 2001
2 From: Charles Fol <folcharles@gmail.com>
3 Date: Thu, 28 Mar 2024 12:25:38 -0300
4 Subject: [PATCH] iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing
5 escape sequence (CVE-2024-2961)
7 ISO-2022-CN-EXT uses escape sequences to indicate character set changes
8 (as specified by RFC 1922). While the SOdesignation has the expected
9 bounds checks, neither SS2designation nor SS3designation have its;
10 allowing a write overflow of 1, 2, or 3 bytes with fixed values:
11 '$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'.
13 Checked on aarch64-linux-gnu.
15 Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
16 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
17 Tested-by: Carlos O'Donell <carlos@redhat.com>
19 (cherry picked from commit f9dc609e06b1136bb0408be9605ce7973a767ada)
20 ---
21 iconvdata/Makefile | 5 +-
22 iconvdata/iso-2022-cn-ext.c | 12 +++
23 iconvdata/tst-iconv-iso-2022-cn-ext.c | 128 ++++++++++++++++++++++++++
24 3 files changed, 144 insertions(+), 1 deletion(-)
25 create mode 100644 iconvdata/tst-iconv-iso-2022-cn-ext.c
27 diff --git a/iconvdata/Makefile b/iconvdata/Makefile
28 index b67b4feeb4..8fc126c210 100644
29 --- a/iconvdata/Makefile
30 +++ b/iconvdata/Makefile
31 @@ -73,7 +73,7 @@
32 ifeq (yes,$(build-shared))
33 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
34 tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
35 - bug-iconv10 bug-iconv11 bug-iconv12
36 + bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-iso-2022-cn-ext
37 ifeq ($(have-thread-library),yes)
38 tests += bug-iconv3
39 endif
40 @@ -316,6 +316,8 @@
41 $(addprefix $(objpfx),$(modules.so))
42 $(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
43 $(addprefix $(objpfx),$(modules.so))
44 +$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \
45 + $(addprefix $(objpfx),$(modules.so))
47 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
48 $(addprefix $(objpfx),$(modules.so)) \
49 diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
50 index 947b807421..34e1010bed 100644
51 --- a/iconvdata/iso-2022-cn-ext.c
52 +++ b/iconvdata/iso-2022-cn-ext.c
53 @@ -575,6 +575,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
54 { \
55 const char *escseq; \
56 \
57 + if (outptr + 4 > outend) \
58 + { \
59 + result = __GCONV_FULL_OUTPUT; \
60 + break; \
61 + } \
62 + \
63 assert (used == CNS11643_2_set); /* XXX */ \
64 escseq = "*H"; \
65 *outptr++ = ESC; \
66 @@ -588,6 +594,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
67 { \
68 const char *escseq; \
69 \
70 + if (outptr + 4 > outend) \
71 + { \
72 + result = __GCONV_FULL_OUTPUT; \
73 + break; \
74 + } \
75 + \
76 assert ((used >> 5) >= 3 && (used >> 5) <= 7); \
77 escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \
78 *outptr++ = ESC; \
79 diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c
80 new file mode 100644
81 index 0000000000..96a8765fd5
82 --- /dev/null
83 +++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c
84 @@ -0,0 +1,128 @@
85 +/* Verify ISO-2022-CN-EXT does not write out of the bounds.
86 + Copyright (C) 2024 Free Software Foundation, Inc.
87 + This file is part of the GNU C Library.
88 +
89 + The GNU C Library is free software; you can redistribute it and/or
90 + modify it under the terms of the GNU Lesser General Public
91 + License as published by the Free Software Foundation; either
92 + version 2.1 of the License, or (at your option) any later version.
93 +
94 + The GNU C Library is distributed in the hope that it will be useful,
95 + but WITHOUT ANY WARRANTY; without even the implied warranty of
96 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
97 + Lesser General Public License for more details.
98 +
99 + You should have received a copy of the GNU Lesser General Public
100 + License along with the GNU C Library; if not, see
101 + <https://www.gnu.org/licenses/>. */
102 +
103 +#include <stdio.h>
104 +#include <string.h>
105 +
106 +#include <errno.h>
107 +#include <iconv.h>
108 +#include <sys/mman.h>
109 +
110 +#include <support/xunistd.h>
111 +#include <support/check.h>
112 +#include <support/support.h>
113 +
114 +/* The test sets up a two memory page buffer with the second page marked
115 + PROT_NONE to trigger a fault if the conversion writes beyond the exact
116 + expected amount. Then we carry out various conversions and precisely
117 + place the start of the output buffer in order to trigger a SIGSEGV if the
118 + process writes anywhere between 1 and page sized bytes more (only one
119 + PROT_NONE page is setup as a canary) than expected. These tests exercise
120 + all three of the cases in ISO-2022-CN-EXT where the converter must switch
121 + character sets and may run out of buffer space while doing the
122 + operation. */
123 +
124 +static int
125 +do_test (void)
126 +{
127 + iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8");
128 + TEST_VERIFY_EXIT (cd != (iconv_t) -1);
129 +
130 + char *ntf;
131 + size_t ntfsize;
132 + char *outbufbase;
133 + {
134 + int pgz = getpagesize ();
135 + TEST_VERIFY_EXIT (pgz > 0);
136 + ntfsize = 2 * pgz;
137 +
138 + ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE
139 + | MAP_ANONYMOUS, -1);
140 + xmprotect (ntf + pgz, pgz, PROT_NONE);
141 +
142 + outbufbase = ntf + pgz;
143 + }
144 +
145 + /* Check if SOdesignation escape sequence does not trigger an OOB write. */
146 + {
147 + char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2";
148 +
149 + for (int i = 0; i < 9; i++)
150 + {
151 + char *inp = inbuf;
152 + size_t inleft = sizeof (inbuf) - 1;
153 +
154 + char *outp = outbufbase - i;
155 + size_t outleft = i;
156 +
157 + TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
158 + == (size_t) -1);
159 + TEST_COMPARE (errno, E2BIG);
160 +
161 + TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
162 + }
163 + }
164 +
165 + /* Same as before for SS2designation. */
166 + {
167 + char inbuf[] = "ã´½ \xe3\xb4\xbd";
168 +
169 + for (int i = 0; i < 14; i++)
170 + {
171 + char *inp = inbuf;
172 + size_t inleft = sizeof (inbuf) - 1;
173 +
174 + char *outp = outbufbase - i;
175 + size_t outleft = i;
176 +
177 + TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
178 + == (size_t) -1);
179 + TEST_COMPARE (errno, E2BIG);
180 +
181 + TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
182 + }
183 + }
184 +
185 + /* Same as before for SS3designation. */
186 + {
187 + char inbuf[] = "å \xe5\x8a\x84";
188 +
189 + for (int i = 0; i < 14; i++)
190 + {
191 + char *inp = inbuf;
192 + size_t inleft = sizeof (inbuf) - 1;
193 +
194 + char *outp = outbufbase - i;
195 + size_t outleft = i;
196 +
197 + TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
198 + == (size_t) -1);
199 + TEST_COMPARE (errno, E2BIG);
200 +
201 + TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
202 + }
203 + }
204 +
205 + TEST_VERIFY_EXIT (iconv_close (cd) != -1);
206 +
207 + xmunmap (ntf, ntfsize);
208 +
209 + return 0;
210 +}
211 +
212 +#include <support/test-driver.c>
213 --
214 2.39.3