[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#991731: marked as done (unblock: fetchmail/6.4.16-4)



Your message dated Sat, 31 Jul 2021 15:43:31 +0000
with message-id <E1m9r99-0000Am-JX@respighi.debian.org>
and subject line unblock fetchmail
has caused the Debian Bug report #991731,
regarding unblock: fetchmail/6.4.16-4
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
991731: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=991731
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi RMs,

I would like to ask for unblocking fetchmail, fixing a security issue.

[ Reason ]
When logging long messages, fetchmail might segfault or leak
information to logs.

[ Impact ]
Normal logging in all cases.

[ Tests ]
Local tests.

[ Risks ]
None.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

unblock fetchmail/6.4.16-4

Thanks for considering,
Laszlo/GCS
diff -Nru fetchmail-6.4.16/debian/changelog fetchmail-6.4.16/debian/changelog
--- fetchmail-6.4.16/debian/changelog	2021-06-26 23:53:00.000000000 +0200
+++ fetchmail-6.4.16/debian/changelog	2021-07-29 00:18:56.000000000 +0200
@@ -1,3 +1,10 @@
+fetchmail (6.4.16-4) unstable; urgency=high
+
+  * Backport upstream security fix for CVE-2021-36386: denial of service or
+    information disclosure when logging long messages.
+
+ -- Laszlo Boszormenyi (GCS) <gcs@debian.org>  Thu, 29 Jul 2021 00:18:56 +0200
+
 fetchmail (6.4.16-3) unstable; urgency=medium
 
   * Fix operation autopkgtest.
diff -Nru fetchmail-6.4.16/debian/patches/11_fix_CVE-2021-38386.patch fetchmail-6.4.16/debian/patches/11_fix_CVE-2021-38386.patch
--- fetchmail-6.4.16/debian/patches/11_fix_CVE-2021-38386.patch	1970-01-01 01:00:00.000000000 +0100
+++ fetchmail-6.4.16/debian/patches/11_fix_CVE-2021-38386.patch	2021-07-29 00:18:56.000000000 +0200
@@ -0,0 +1,258 @@
+From c546c8299243a10a7b85c638e0e61396ecd5d8b5 Mon Sep 17 00:00:00 2001
+From: Matthias Andree <matthias.andree@gmx.de>
+Date: Wed, 7 Jul 2021 16:22:57 +0200
+Subject: [PATCH] Fix SIGSEGV when resizing report*() buffer.
+
+Reported (with a different patch suggestion) by
+Christian Herdtweck <christian.herdtweck@intra2net.com>.
+
+Note that vsnprintf() calls va_arg(), and depending on operating system,
+compiler, configuration, this will invalidate the va_list argument
+pointer, so that va_start has to be called again before a subsequent
+vsnprintf(). However, it is better to do away with the loop and the
+trial-and-error, and leverage the return value of vsnprintf instead for
+a direct one-off resizing, whilst taking into account that on SUSv2
+systems, the return value can be useless if the size argument to
+vsnprintf is 0.
+---
+ NEWS     |  18 ++++++++
+ report.c | 138 +++++++++++++++++++++++++++++++------------------------
+ 2 files changed, 95 insertions(+), 61 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 04239b16..67dc1f9e 100644
+--- a/NEWS
++++ b/NEWS
+@@ -64,6 +64,24 @@ removed from a 6.5.0 or newer release.)
+   for end-of-life OpenSSL versions may be removed even from patchlevel releases.
+ 
+ --------------------------------------------------------------------------------
++fetchmail-6.4.20 (not yet released):
++
++# SECURITY FIX:
++* When a log message exceeds c. 2 kByte in size, for instance, with very long 
++  header contents, and depending on verbosity option, fetchmail can crash or
++  misreport each first log message that requires a buffer reallocation.
++  fetchmail then reallocates memory and re-runs vsnprintf() without another 
++  call to va_start(), so it reads garbage. The exact impact depends on 
++  many factors around the compiler and operating system configurations used and 
++  the implementation details of the stdarg.h interfaces of the two functions
++  mentioned before. To fix CVE-2021-38386.
++
++  Reported by Christian Herdtweck of Intra2net AG, Tübingen, Germany.
++
++  He also offered a patch, which I could not take for fetchmail 6.4 because
++  it required a C99 system and I'd promised earlier that 6.4 would remain
++  compatible with C89 systems.
++--------------------------------------------------------------------------------
+ fetchmail-6.4.16 (released 2021-02-08, 27707 LoC):
+ 
+ # BUG FIXES
+diff --git a/report.c b/report.c
+index 1466802a..aea6b3ea 100644
+--- a/report.c
++++ b/report.c
+@@ -44,6 +44,8 @@ static unsigned int partial_message_size = 0;
+ static unsigned int partial_message_size_used = 0;
+ static char *partial_message;
+ static int partial_suppress_tag = 0;
++/* default size for the allocation of the report buffer */
++const size_t defaultsize = 4096;
+ 
+ static unsigned unbuffered;
+ static unsigned int use_syslog;
+@@ -177,6 +179,27 @@ void report_init(int mode /** 0: regular output, 1: unbuffered output, -1: syslo
+     }
+ }
+ 
++static void rep_ensuresize(size_t increment) {
++    if (partial_message_size == 0)
++    {
++	/* initialization */
++	partial_message_size_used = 0;
++	/* avoid too many small allocations initially */
++	if (increment < defaultsize) increment = defaultsize;
++	partial_message_size = increment;
++	partial_message = (char *)MALLOC (partial_message_size);
++    }
++    else /* already have buffer -> resize if too little room */
++    {
++	if (increment < defaultsize) increment = defaultsize;
++	if (partial_message_size - partial_message_size_used < increment)
++	{
++	    partial_message_size += increment;
++	    partial_message = (char *)REALLOC (partial_message, partial_message_size);
++	}
++    }
++}
++
+ /* Build an report message by appending MESSAGE, which is a printf-style
+    format string with optional args, to the existing report message (which may
+    be empty.)  The completed report message is finally printed (and reset to
+@@ -185,52 +208,37 @@ void report_init(int mode /** 0: regular output, 1: unbuffered output, -1: syslo
+    message exists, then, in an attempt to keep the messages in their proper
+    sequence, the partial message will be printed as-is (with a trailing 
+    newline) before report() prints its message. */
++
++
+ /* VARARGS */
++#ifdef HAVE_STDARG_H
++static int report_vgetsize(const char *message, va_list args)
++{
++    char tmp[1];
+ 
+-static void rep_ensuresize(void) {
+-    /* Make an initial guess for the size of any single message fragment.  */
+-    if (partial_message_size == 0)
+-    {
+-	partial_message_size_used = 0;
+-	partial_message_size = 2048;
+-	partial_message = (char *)MALLOC (partial_message_size);
+-    }
+-    else
+-	if (partial_message_size - partial_message_size_used < 1024)
+-	{
+-	    partial_message_size += 2048;
+-	    partial_message = (char *)REALLOC (partial_message, partial_message_size);
+-	}
++    return vsnprintf(tmp, 1, message, args);
+ }
+ 
+-#ifdef HAVE_STDARG_H
+-static void report_vbuild(const char *message, va_list args)
++/* note that report_vbuild assumes that the buffer was already allocated. */
++/* VARARGS */
++static int report_vbuild(const char *message, va_list args)
+ {
+     int n;
+ 
+-    for ( ; ; )
+-    {
+-	/*
+-	 * args has to be initialized before every call of vsnprintf(), 
+-	 * because vsnprintf() invokes va_arg macro and thus args is 
+-	 * undefined after the call.
+-	 */
+-	n = vsnprintf (partial_message + partial_message_size_used, partial_message_size - partial_message_size_used,
+-		       message, args);
+-
+-	/* output error, f. i. EILSEQ */
+-	if (n < 0) break;
+-
+-	if (n >= 0
+-	    && (unsigned)n < partial_message_size - partial_message_size_used)
+-        {
+-	    partial_message_size_used += n;
+-	    break;
+-	}
++    n = vsnprintf (partial_message + partial_message_size_used,
++		   partial_message_size - partial_message_size_used,
++		   message, args);
++
++    /* output error, f. i. EILSEQ */
++    if (n < 0)
++	    return -1;
+ 
+-	partial_message_size += 2048;
+-	partial_message = (char *)REALLOC (partial_message, partial_message_size);
++    if (n > 0)
++    {
++	partial_message_size_used += n;
+     }
++
++    return n;
+ }
+ #endif
+ 
+@@ -243,40 +251,45 @@ report_build (FILE *errfp, message, va_alist)
+      va_dcl
+ #endif
+ {
++    int n;
+ #ifdef VA_START
+     va_list args;
+-#else
+-    int n;
+ #endif
+ 
+-    rep_ensuresize();
++/* the logic is to first calculate the size,
++ * then reallocate, then fill the buffer
++ */
+ 
+ #if defined(VA_START)
+     VA_START(args, message);
+-    report_vbuild(message, args);
++    n = report_vgetsize(message, args);
+     va_end(args);
+-#else
+-    for ( ; ; )
+-    {
+-	n = snprintf (partial_message + partial_message_size_used,
+-		      partial_message_size - partial_message_size_used,
+-		      message, a1, a2, a3, a4, a5, a6, a7, a8);
+ 
+-	/* output error, f. i. EILSEQ */
+-	if (n < 0) break;
++    rep_ensuresize(n + 1);
+ 
+-	if (n >= 0
+-	    && (unsigned)n < partial_message_size - partial_message_size_used)
+-        {
+-	    partial_message_size_used += n;
+-	    break;
+-	}
++    VA_START(args, message);
++    n = report_vbuild(message, args);
++    va_end(args);
++#else
++    { 
++	char tmp[1];
++	/* note that SUSv2 specifies that with the 2nd argument zero, an 
++	 * unspecified value less than 1 were to be returned. This is not 
++	 * useful, so pass 1. */
++	n = snprintf (tmp, 1, 
++		      message, a1, a2, a3, a4, a5, a6, a7, a8);
+ 
+-	partial_message_size += 2048;
+-	partial_message = REALLOC (partial_message, partial_message_size);
++	if (n > 0)
++	    rep_ensuresize(n + 1);
+     }
++       
++    n = snprintf (partial_message + partial_message_size_used,
++		    partial_message_size - partial_message_size_used,
++		    message, a1, a2, a3, a4, a5, a6, a7, a8);
+ #endif
+ 
++    if (n > 0) partial_message_size_used += n;
++
+     if (unbuffered && partial_message_size_used != 0)
+     {
+ 	partial_message_size_used = 0;
+@@ -308,15 +321,18 @@ report_complete (FILE *errfp, message, va_alist)
+      va_dcl
+ #endif
+ {
++    int n;
+ #ifdef VA_START
+     va_list args;
+-#endif
+ 
+-    rep_ensuresize();
++    VA_START(args, message);
++    n = report_vgetsize(message, args);
++    va_end(args);
++
++    rep_ensuresize(n + 1);
+ 
+-#if defined(VA_START)
+     VA_START(args, message);
+-    report_vbuild(message, args);
++    n = report_vbuild(message, args);
+     va_end(args);
+ #else
+     report_build(errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
+-- 
+GitLab
+
diff -Nru fetchmail-6.4.16/debian/patches/series fetchmail-6.4.16/debian/patches/series
--- fetchmail-6.4.16/debian/patches/series	2021-06-24 19:00:48.000000000 +0200
+++ fetchmail-6.4.16/debian/patches/series	2021-07-29 00:18:56.000000000 +0200
@@ -4,3 +4,4 @@
 08_remove_forced_OpenSSL_check.patch
 09_fix_memory_leak_in_timeout_situation.patch
 10_update_manpage.patch
+11_fix_CVE-2021-38386.patch

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: