public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [COMMITTED 1/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6246)
@ 2024-01-30 18:40 Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 2/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) Arjun Shankar
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Arjun Shankar @ 2024-01-30 18:40 UTC (permalink / raw)
  To: libc-alpha; +Cc: Arjun Shankar, Adhemerval Zanella, Carlos O'Donell

__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>
---
 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 42899c2b6c..c273ec6974 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.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [COMMITTED 2/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779)
  2024-01-30 18:40 [COMMITTED 1/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6246) Arjun Shankar
@ 2024-01-30 18:40 ` Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 3/4] syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780) Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 4/4] Document CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780 Arjun Shankar
  2 siblings, 0 replies; 4+ messages in thread
From: Arjun Shankar @ 2024-01-30 18:40 UTC (permalink / raw)
  To: libc-alpha; +Cc: Arjun Shankar, Carlos O'Donell

__vsyslog_internal used the return value of snprintf/vsnprintf to
calculate buffer sizes for memory allocation.  If these functions (for
any reason) failed and returned -1, the resulting buffer would be too
small to hold output.  This commit fixes that.

All snprintf/vsnprintf calls are checked for negative return values and
the function silently returns upon encountering them.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
---
 misc/syslog.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/misc/syslog.c b/misc/syslog.c
index 814d224a1e..53440e47ad 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -185,11 +185,13 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
   else
     l = __snprintf (bufs, sizeof bufs,
 		    SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+  if (l < 0)
+    goto out;
 
   char *pos;
   size_t len;
 
-  if (0 <= l && l < sizeof bufs)
+  if (l < sizeof bufs)
     {
       /* At this point, there is still a chance that we can print the
          remaining part of the log into bufs and use that.  */
@@ -215,12 +217,15 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
     __set_errno (saved_errno);
 
     vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
+    va_end (apc);
+
+    if (vl < 0)
+      goto out;
 
-    if (!(0 <= vl && vl < len))
+    if (vl >= len)
       buf = NULL;
 
     bufsize = l + vl;
-    va_end (apc);
   }
 
   if (buf == NULL)
@@ -231,25 +236,37 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
 	  /* Tell the cancellation handler to free this buffer.  */
 	  clarg.buf = buf;
 
+	  int cl;
 	  if (has_ts)
-	    __snprintf (buf, l + 1,
-			SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+	    cl = __snprintf (buf, l + 1,
+			     SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
 	  else
-	    __snprintf (buf, l + 1,
-			SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+	    cl = __snprintf (buf, l + 1,
+			     SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+	  if (cl != l)
+	    goto out;
 
 	  va_list apc;
 	  va_copy (apc, ap);
-	  __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
-				mode_flags);
+	  cl = __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+				     mode_flags);
 	  va_end (apc);
+
+	  if (cl != vl)
+	    goto out;
 	}
       else
         {
+          int bl;
 	  /* Nothing much to do but emit an error message.  */
-          bufsize = __snprintf (bufs, sizeof bufs,
-                                "out of memory[%d]", __getpid ());
+          bl = __snprintf (bufs, sizeof bufs,
+                           "out of memory[%d]", __getpid ());
+          if (bl < 0 || bl >= sizeof bufs)
+            goto out;
+
+          bufsize = bl;
           buf = bufs;
+          msgoff = 0;
         }
     }
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [COMMITTED 3/4] syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780)
  2024-01-30 18:40 [COMMITTED 1/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6246) Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 2/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) Arjun Shankar
@ 2024-01-30 18:40 ` Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 4/4] Document CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780 Arjun Shankar
  2 siblings, 0 replies; 4+ messages in thread
From: Arjun Shankar @ 2024-01-30 18:40 UTC (permalink / raw)
  To: libc-alpha; +Cc: Arjun Shankar, Carlos O'Donell

__vsyslog_internal calculated a buffer size by adding two integers, but
did not first check if the addition would overflow.  This commit fixes
that.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
---
 misc/syslog.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/misc/syslog.c b/misc/syslog.c
index 53440e47ad..4af87f54fd 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c	8.4 (Berkeley) 3/18/94";
 #include <sys/uio.h>
 #include <sys/un.h>
 #include <syslog.h>
+#include <limits.h>
 
 static int LogType = SOCK_DGRAM;	/* type of socket connection */
 static int LogFile = -1;		/* fd for log */
@@ -219,7 +220,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
     vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
     va_end (apc);
 
-    if (vl < 0)
+    if (vl < 0 || vl >= INT_MAX - l)
       goto out;
 
     if (vl >= len)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [COMMITTED 4/4] Document CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780
  2024-01-30 18:40 [COMMITTED 1/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6246) Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 2/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) Arjun Shankar
  2024-01-30 18:40 ` [COMMITTED 3/4] syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780) Arjun Shankar
@ 2024-01-30 18:40 ` Arjun Shankar
  2 siblings, 0 replies; 4+ messages in thread
From: Arjun Shankar @ 2024-01-30 18:40 UTC (permalink / raw)
  To: libc-alpha; +Cc: Arjun Shankar

This commit adds "advisories" entries for the above three CVEs.
---
 advisories/GLIBC-SA-2024-0001 | 15 +++++++++++++++
 advisories/GLIBC-SA-2024-0002 | 15 +++++++++++++++
 advisories/GLIBC-SA-2024-0003 | 13 +++++++++++++
 3 files changed, 43 insertions(+)
 create mode 100644 advisories/GLIBC-SA-2024-0001
 create mode 100644 advisories/GLIBC-SA-2024-0002
 create mode 100644 advisories/GLIBC-SA-2024-0003

diff --git a/advisories/GLIBC-SA-2024-0001 b/advisories/GLIBC-SA-2024-0001
new file mode 100644
index 0000000000..28931c75ae
--- /dev/null
+++ b/advisories/GLIBC-SA-2024-0001
@@ -0,0 +1,15 @@
+syslog: Heap buffer overflow in __vsyslog_internal
+
+__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.
+
+CVE-Id: CVE-2023-6246
+Public-Date: 2024-01-30
+Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
+Fix-Commit: 6bd0e4efcc78f3c0115e5ea9739a1642807450da (2.39)
+Fix-Commit: 23514c72b780f3da097ecf33a793b7ba9c2070d2 (2.38-42)
+Fix-Commit: 97a4292aa4a2642e251472b878d0ec4c46a0e59a (2.37-57)
+Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
+Fix-Commit: d1a83b6767f68b3cb5b4b4ea2617254acd040c82 (2.36-126)
diff --git a/advisories/GLIBC-SA-2024-0002 b/advisories/GLIBC-SA-2024-0002
new file mode 100644
index 0000000000..940bfcf2fc
--- /dev/null
+++ b/advisories/GLIBC-SA-2024-0002
@@ -0,0 +1,15 @@
+syslog: Heap buffer overflow in __vsyslog_internal
+
+__vsyslog_internal used the return value of snprintf/vsnprintf to
+calculate buffer sizes for memory allocation.  If these functions (for
+any reason) failed and returned -1, the resulting buffer would be too
+small to hold output.
+
+CVE-Id: CVE-2023-6779
+Public-Date: 2024-01-30
+Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
+Fix-Commit: 7e5a0c286da33159d47d0122007aac016f3e02cd (2.39)
+Fix-Commit: d0338312aace5bbfef85e03055e1212dd0e49578 (2.38-43)
+Fix-Commit: 67062eccd9a65d7fda9976a56aeaaf6c25a80214 (2.37-58)
+Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
+Fix-Commit: 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 (2.36-127)
diff --git a/advisories/GLIBC-SA-2024-0003 b/advisories/GLIBC-SA-2024-0003
new file mode 100644
index 0000000000..b43a5150ab
--- /dev/null
+++ b/advisories/GLIBC-SA-2024-0003
@@ -0,0 +1,13 @@
+syslog: Integer overflow in __vsyslog_internal
+
+__vsyslog_internal calculated a buffer size by adding two integers, but
+did not first check if the addition would overflow.
+
+CVE-Id: CVE-2023-6780
+Public-Date: 2024-01-30
+Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
+Fix-Commit: ddf542da94caf97ff43cc2875c88749880b7259b (2.39)
+Fix-Commit: d37c2b20a4787463d192b32041c3406c2bd91de0 (2.38-44)
+Fix-Commit: 2b58cba076e912961ceaa5fa58588e4b10f791c0 (2.37-59)
+Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
+Fix-Commit: b9b7d6a27aa0632f334352fa400771115b3c69b7 (2.36-128)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-01-30 18:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-30 18:40 [COMMITTED 1/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6246) Arjun Shankar
2024-01-30 18:40 ` [COMMITTED 2/4] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) Arjun Shankar
2024-01-30 18:40 ` [COMMITTED 3/4] syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780) Arjun Shankar
2024-01-30 18:40 ` [COMMITTED 4/4] Document CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780 Arjun Shankar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).