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

Bug#991120: buster-pu: package postsrsd/1.5-2+deb10u2



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]
Security fix for CVE-2021-35525.

[ Impact ]
Package is vulnerable to a potential DoS attack.

[ Tests ]
The version in buster didn't have any integration tests nor autopkgtests, so I 
didn't backport those. However, I did run the test suite from the package in 
testing against the buster version and it passes (except some tests for new 
features that aren't present in buster). I've also manually verified that the 
package still works.

[ Risks ]
Fix is a one-to-one backport from upstream, modulus formatting changes.

[ 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 (old)stable
  [ ] the issue is verified as fixed in unstable

As of writing the fix isn't in unstable yet, since I don't have upload rights. 
I've asked my sponsor to upload the fix for both stable and unstable at the 
same time -- it seemed unnecessary to add another roundtrip delay, as it's 
exactly the same fix.

[ Changes ]
Add patch with security fix for CVE-2021-35525.

[ Other info ]
N/A.
diff -Nru postsrsd-1.5/debian/changelog postsrsd-1.5/debian/changelog
--- postsrsd-1.5/debian/changelog	2020-12-19 01:36:37.000000000 +0100
+++ postsrsd-1.5/debian/changelog	2021-07-14 21:37:55.000000000 +0200
@@ -1,3 +1,11 @@
+postsrsd (1.5-2+deb10u2) UNRELEASED; urgency=medium
+
+  * Fix CVE-2021-35525: potential DoS when Postfix sends certain long data
+    fields such as multiple concatenated email addresses. Fix backported from
+    upstream commit 077be98d8c8. (Closes: #990439)
+
+ -- Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>  Wed, 14 Jul 2021 21:37:55 +0200
+
 postsrsd (1.5-2+deb10u1) buster; urgency=medium
 
   * CVE-2020-35573: Ensure timestamp tags aren't too long before trying to
diff -Nru postsrsd-1.5/debian/patches/0005-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch postsrsd-1.5/debian/patches/0005-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch
--- postsrsd-1.5/debian/patches/0005-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch	1970-01-01 01:00:00.000000000 +0100
+++ postsrsd-1.5/debian/patches/0005-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch	2021-07-14 21:37:55.000000000 +0200
@@ -0,0 +1,120 @@
+From: =?utf-8?q?Timo_R=C3=B6hling?= <timo@gaussglocke.de>
+Date: Sun, 21 Mar 2021 15:27:55 +0100
+Subject: SECURITY: Fix DoS on overly long input from Postfix
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Thanks to Mateusz Jończyk who reported this issue and gave valuable
+feedback for its resolution.
+
+PostSRSd would hang on an overly long GET request, because the
+fread()/fwrite() logic in the subprocess would get confused by the
+remaining input line in its buffer.
+
+Theoretically, this error should never occur, as Postfix is supposed to
+send valid email addresses only, which are shorter than the buffer, even
+assuming every single character is percent-encoded. However, Postfix
+sometimes does seem to send malformed request with multiple concatenated
+email addresses. I'm not sure if there's a reliable way to trigger this
+condition by an external attacker, but it is a security bug in PostSRSd
+nevertheless.
+
+Fixes CVE-2021-35525.
+
+Tests not backported, as v1.5 did not have them yet.
+
+Origin: https://github.com/roehling/postsrsd/commit/077be98d8c8a9847e4ae0c7dc09e7474cbe27db2
+Forwarded: not-needed
+Last-Update: 2021-07-14
+---
+ postsrsd.c | 54 +++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 35 insertions(+), 19 deletions(-)
+
+diff --git a/postsrsd.c b/postsrsd.c
+index a6fd118..64e1ad0 100644
+--- a/postsrsd.c
++++ b/postsrsd.c
+@@ -501,9 +501,9 @@ int main (int argc, char **argv)
+     fds[sc].events = POLLIN;
+   }
+   while(TRUE) {
+     int conn;
+-    FILE *fp;
++    FILE *fp_read, *fp_write;
+     char linebuf[1024], *line;
+     char keybuf[1024], *key;
+ 
+     if (poll(fds, socket_count, 1000) < 0) {
+@@ -523,37 +523,53 @@ int main (int argc, char **argv)
+           int i;
+           // close listen sockets so that we don't stop the main daemon process from restarting
+           for (i = 0; i < socket_count; ++i) close (sockets[i]);
+ 
+-          fp = fdopen(conn, "r+");
+-          if (fp == NULL) exit(EXIT_FAILURE);
+-          fds[0].fd = conn;
+-          fds[0].events = POLLIN;
+-          if (poll(fds, 1, timeout * 1000) <= 0) return EXIT_FAILURE;
+-          line = fgets(linebuf, sizeof(linebuf), fp);
+-          while (line) {
+-            fseek (fp, 0, SEEK_CUR); /* Workaround for Solaris */
++          /* create separate input/output streams */
++          fp_read = fdopen(conn, "r");
++          if (fp_read == NULL)
++            return EXIT_FAILURE;
++          fp_write = fdopen(dup(conn), "w");
++          if (fp_write == NULL) return EXIT_FAILURE;
++          errno = 0;
++          alarm(timeout);
++          if (errno != 0)
++              return EXIT_FAILURE;
++          while ((line = fgets(linebuf, sizeof(linebuf), fp_read))) {
+             char* token;
++            alarm(0);
++            if (strlen(line) >= sizeof(linebuf) - 1) {
++              fprintf(fp_write, "500 Invalid request\n");
++              fflush(fp_write);
++              return EXIT_FAILURE;
++            }
+             token = strtok(line, " \r\n");
+             if (token == NULL || strcmp(token, "get") != 0) {
+-              fprintf (fp, "500 Invalid request\n");
+-              fflush (fp);
++              fprintf (fp_write, "500 Invalid request\n");
++              fflush (fp_write);
+               return EXIT_FAILURE;
+             }
+             token = strtok(NULL, "\r\n");
+             if (!token) {
+-              fprintf (fp, "500 Invalid request\n");
+-              fflush (fp);
++              fprintf (fp_write, "500 Invalid request\n");
++              fflush (fp_write);
+               return EXIT_FAILURE;
+             }
+             key = url_decode(keybuf, sizeof(keybuf), token);
+-            if (!key) break;
+-            handler[sc](srs, fp, key, domain, excludes);
+-            fflush (fp);
+-            if (poll(fds, 1, timeout * 1000) <= 0) break;
+-            line = fgets(linebuf, sizeof(linebuf), fp);
++            if (!key) {
++              fprintf (fp_write, "500 Invalid request\n");
++              fflush(fp_write);
++              return EXIT_FAILURE;
++            }
++            handler[sc](srs, fp_write, key, domain, excludes);
++            fflush (fp_write);
++            errno = 0;
++            alarm(timeout);
++            if (errno != 0)
++              return EXIT_FAILURE;
+           }
+-          fclose (fp);
++          fclose (fp_write);
++          fclose (fp_read);
+           return EXIT_SUCCESS;
+         }
+         close (conn);
+       }
diff -Nru postsrsd-1.5/debian/patches/series postsrsd-1.5/debian/patches/series
--- postsrsd-1.5/debian/patches/series	2020-12-19 01:36:37.000000000 +0100
+++ postsrsd-1.5/debian/patches/series	2021-07-14 21:37:55.000000000 +0200
@@ -2,3 +2,4 @@
 0002-Increase-hash-length-for-unit-tests.patch
 0003-Hook-up-endianness-sizeof-long-detection-code-in-SHA.patch
 0004-SECURITY-Fix-potential-denial-of-service-attack-agai.patch
+0005-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch

Reply to: