]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/glibc-2.38/0042-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
glibc: Import latest patches from upstream
[ipfire-2.x.git] / src / patches / glibc-2.38 / 0042-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
1 From 23514c72b780f3da097ecf33a793b7ba9c2070d2 Mon Sep 17 00:00:00 2001
2 From: Arjun Shankar <arjun@redhat.com>
3 Date: Mon, 15 Jan 2024 17:44:43 +0100
4 Subject: [PATCH 42/44] syslog: Fix heap buffer overflow in __vsyslog_internal
5 (CVE-2023-6246)
6
7 __vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
8 containing a long program name failed to update the required buffer
9 size, leading to the allocation and overflow of a too-small buffer on
10 the heap. This commit fixes that. It also adds a new regression test
11 that uses glibc.malloc.check.
12
13 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
14 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
15 Tested-by: Carlos O'Donell <carlos@redhat.com>
16 (cherry picked from commit 6bd0e4efcc78f3c0115e5ea9739a1642807450da)
17 ---
18 misc/Makefile | 8 ++-
19 misc/syslog.c | 50 +++++++++++++------
20 misc/tst-syslog-long-progname.c | 39 +++++++++++++++
21 .../postclean.req | 0
22 4 files changed, 82 insertions(+), 15 deletions(-)
23 create mode 100644 misc/tst-syslog-long-progname.c
24 create mode 100644 misc/tst-syslog-long-progname.root/postclean.req
25
26 diff --git a/misc/Makefile b/misc/Makefile
27 index fe0d49c1de..90b31952c5 100644
28 --- a/misc/Makefile
29 +++ b/misc/Makefile
30 @@ -289,7 +289,10 @@ tests-special += $(objpfx)tst-error1-mem.out \
31 $(objpfx)tst-allocate_once-mem.out
32 endif
33
34 -tests-container := tst-syslog
35 +tests-container := \
36 + tst-syslog \
37 + tst-syslog-long-progname \
38 + # tests-container
39
40 CFLAGS-select.c += -fexceptions -fasynchronous-unwind-tables
41 CFLAGS-tsearch.c += $(uses-callbacks)
42 @@ -351,6 +354,9 @@ $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
43 $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
44 $(evaluate-test)
45
46 +tst-syslog-long-progname-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
47 + LD_PRELOAD=libc_malloc_debug.so.0
48 +
49 $(objpfx)tst-select: $(librt)
50 $(objpfx)tst-select-time64: $(librt)
51 $(objpfx)tst-pselect: $(librt)
52 diff --git a/misc/syslog.c b/misc/syslog.c
53 index 1b8cb722c5..814d224a1e 100644
54 --- a/misc/syslog.c
55 +++ b/misc/syslog.c
56 @@ -124,8 +124,9 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
57 {
58 /* Try to use a static buffer as an optimization. */
59 char bufs[1024];
60 - char *buf = NULL;
61 - size_t bufsize = 0;
62 + char *buf = bufs;
63 + size_t bufsize;
64 +
65 int msgoff;
66 int saved_errno = errno;
67
68 @@ -177,29 +178,50 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
69 #define SYSLOG_HEADER_WITHOUT_TS(__pri, __msgoff) \
70 "<%d>: %n", __pri, __msgoff
71
72 - int l;
73 + int l, vl;
74 if (has_ts)
75 l = __snprintf (bufs, sizeof bufs,
76 SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
77 else
78 l = __snprintf (bufs, sizeof bufs,
79 SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
80 +
81 + char *pos;
82 + size_t len;
83 +
84 if (0 <= l && l < sizeof bufs)
85 {
86 - va_list apc;
87 - va_copy (apc, ap);
88 + /* At this point, there is still a chance that we can print the
89 + remaining part of the log into bufs and use that. */
90 + pos = bufs + l;
91 + len = sizeof (bufs) - l;
92 + }
93 + else
94 + {
95 + buf = NULL;
96 + /* We already know that bufs is too small to use for this log message.
97 + The next vsnprintf into bufs is used only to calculate the total
98 + required buffer length. We will discard bufs contents and allocate
99 + an appropriately sized buffer later instead. */
100 + pos = bufs;
101 + len = sizeof (bufs);
102 + }
103
104 - /* Restore errno for %m format. */
105 - __set_errno (saved_errno);
106 + {
107 + va_list apc;
108 + va_copy (apc, ap);
109
110 - int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
111 - mode_flags);
112 - if (0 <= vl && vl < sizeof bufs - l)
113 - buf = bufs;
114 - bufsize = l + vl;
115 + /* Restore errno for %m format. */
116 + __set_errno (saved_errno);
117
118 - va_end (apc);
119 - }
120 + vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
121 +
122 + if (!(0 <= vl && vl < len))
123 + buf = NULL;
124 +
125 + bufsize = l + vl;
126 + va_end (apc);
127 + }
128
129 if (buf == NULL)
130 {
131 diff --git a/misc/tst-syslog-long-progname.c b/misc/tst-syslog-long-progname.c
132 new file mode 100644
133 index 0000000000..88f37a8a00
134 --- /dev/null
135 +++ b/misc/tst-syslog-long-progname.c
136 @@ -0,0 +1,39 @@
137 +/* Test heap buffer overflow in syslog with long __progname (CVE-2023-6246)
138 + Copyright (C) 2023 Free Software Foundation, Inc.
139 + This file is part of the GNU C Library.
140 +
141 + The GNU C Library is free software; you can redistribute it and/or
142 + modify it under the terms of the GNU Lesser General Public
143 + License as published by the Free Software Foundation; either
144 + version 2.1 of the License, or (at your option) any later version.
145 +
146 + The GNU C Library is distributed in the hope that it will be useful,
147 + but WITHOUT ANY WARRANTY; without even the implied warranty of
148 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
149 + Lesser General Public License for more details.
150 +
151 + You should have received a copy of the GNU Lesser General Public
152 + License along with the GNU C Library; if not, see
153 + <https://www.gnu.org/licenses/>. */
154 +
155 +#include <syslog.h>
156 +#include <string.h>
157 +
158 +extern char * __progname;
159 +
160 +static int
161 +do_test (void)
162 +{
163 + char long_progname[2048];
164 +
165 + memset (long_progname, 'X', sizeof (long_progname) - 1);
166 + long_progname[sizeof (long_progname) - 1] = '\0';
167 +
168 + __progname = long_progname;
169 +
170 + syslog (LOG_INFO, "Hello, World!");
171 +
172 + return 0;
173 +}
174 +
175 +#include <support/test-driver.c>
176 diff --git a/misc/tst-syslog-long-progname.root/postclean.req b/misc/tst-syslog-long-progname.root/postclean.req
177 new file mode 100644
178 index 0000000000..e69de29bb2
179 --
180 2.39.2
181