summaryrefslogtreecommitdiff
path: root/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-10-09 03:36:26 +0000
committerCoprDistGit <infra@openeuler.org>2024-10-09 03:36:26 +0000
commitdb43dfdfa8bc2b938582aef3d87e43594c13ee50 (patch)
tree47b95b2f6ac8d8b7e6fa373a5bd7d661bf7234df /0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
parentb933872de72b006230559f77acc3ccfb38a1f343 (diff)
automatic import of glibcopeneuler20.03
Diffstat (limited to '0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch')
-rw-r--r--0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch181
1 files changed, 181 insertions, 0 deletions
diff --git a/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
new file mode 100644
index 0000000..395b520
--- /dev/null
+++ b/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
@@ -0,0 +1,181 @@
+From 23514c72b780f3da097ecf33a793b7ba9c2070d2 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:43 +0100
+Subject: [PATCH 1/3] syslog: Fix heap buffer overflow in __vsyslog_internal
+ (CVE-2023-6246)
+
+__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
+containing a long program name failed to update the required buffer
+size, leading to the allocation and overflow of a too-small buffer on
+the heap. This commit fixes that. It also adds a new regression test
+that uses glibc.malloc.check.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 6bd0e4efcc78f3c0115e5ea9739a1642807450da)
+---
+ misc/Makefile | 8 ++-
+ misc/syslog.c | 50 +++++++++++++------
+ misc/tst-syslog-long-progname.c | 39 +++++++++++++++
+ .../postclean.req | 0
+ 4 files changed, 82 insertions(+), 15 deletions(-)
+ create mode 100644 misc/tst-syslog-long-progname.c
+ create mode 100644 misc/tst-syslog-long-progname.root/postclean.req
+
+diff --git a/misc/Makefile b/misc/Makefile
+index fe0d49c1de..90b31952c5 100644
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -289,7 +289,10 @@ tests-special += $(objpfx)tst-error1-mem.out \
+ $(objpfx)tst-allocate_once-mem.out
+ endif
+
+-tests-container := tst-syslog
++tests-container := \
++ tst-syslog \
++ tst-syslog-long-progname \
++ # tests-container
+
+ CFLAGS-select.c += -fexceptions -fasynchronous-unwind-tables
+ CFLAGS-tsearch.c += $(uses-callbacks)
+@@ -351,6 +354,9 @@ $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
+ $(evaluate-test)
+
++tst-syslog-long-progname-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
++ LD_PRELOAD=libc_malloc_debug.so.0
++
+ $(objpfx)tst-select: $(librt)
+ $(objpfx)tst-select-time64: $(librt)
+ $(objpfx)tst-pselect: $(librt)
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 1b8cb722c5..814d224a1e 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -124,8 +124,9 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ {
+ /* Try to use a static buffer as an optimization. */
+ char bufs[1024];
+- char *buf = NULL;
+- size_t bufsize = 0;
++ char *buf = bufs;
++ size_t bufsize;
++
+ int msgoff;
+ int saved_errno = errno;
+
+@@ -177,29 +178,50 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ #define SYSLOG_HEADER_WITHOUT_TS(__pri, __msgoff) \
+ "<%d>: %n", __pri, __msgoff
+
+- int l;
++ int l, vl;
+ if (has_ts)
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ else
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++
++ char *pos;
++ size_t len;
++
+ if (0 <= l && l < sizeof bufs)
+ {
+- va_list apc;
+- va_copy (apc, ap);
++ /* At this point, there is still a chance that we can print the
++ remaining part of the log into bufs and use that. */
++ pos = bufs + l;
++ len = sizeof (bufs) - l;
++ }
++ else
++ {
++ buf = NULL;
++ /* We already know that bufs is too small to use for this log message.
++ The next vsnprintf into bufs is used only to calculate the total
++ required buffer length. We will discard bufs contents and allocate
++ an appropriately sized buffer later instead. */
++ pos = bufs;
++ len = sizeof (bufs);
++ }
+
+- /* Restore errno for %m format. */
+- __set_errno (saved_errno);
++ {
++ va_list apc;
++ va_copy (apc, ap);
+
+- int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
+- mode_flags);
+- if (0 <= vl && vl < sizeof bufs - l)
+- buf = bufs;
+- bufsize = l + vl;
++ /* Restore errno for %m format. */
++ __set_errno (saved_errno);
+
+- va_end (apc);
+- }
++ vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
++
++ if (!(0 <= vl && vl < len))
++ buf = NULL;
++
++ bufsize = l + vl;
++ va_end (apc);
++ }
+
+ if (buf == NULL)
+ {
+diff --git a/misc/tst-syslog-long-progname.c b/misc/tst-syslog-long-progname.c
+new file mode 100644
+index 0000000000..88f37a8a00
+--- /dev/null
++++ b/misc/tst-syslog-long-progname.c
+@@ -0,0 +1,39 @@
++/* Test heap buffer overflow in syslog with long __progname (CVE-2023-6246)
++ Copyright (C) 2023 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 <syslog.h>
++#include <string.h>
++
++extern char * __progname;
++
++static int
++do_test (void)
++{
++ char long_progname[2048];
++
++ memset (long_progname, 'X', sizeof (long_progname) - 1);
++ long_progname[sizeof (long_progname) - 1] = '\0';
++
++ __progname = long_progname;
++
++ syslog (LOG_INFO, "Hello, World!");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/misc/tst-syslog-long-progname.root/postclean.req b/misc/tst-syslog-long-progname.root/postclean.req
+new file mode 100644
+index 0000000000..e69de29bb2
+--
+2.33.0
+