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

Bug#991119: marked as done (unblock: postsrsd/1.10-2)



Your message dated Sun, 1 Aug 2021 19:54:36 +0200
with message-id <ab06a6b5-9148-7f9d-4532-c672de8e03d6@debian.org>
and subject line Re: Bug#991119: postsrsd security update
has caused the Debian Bug report #991119,
regarding unblock: postsrsd/1.10-2
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.)


-- 
991119: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=991119
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

Please unblock package postsrsd

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

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

[ Tests ]
Tests from upstream backported, testsuite from upstream passes, manually tested 
functionality.

[ 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 testing

[ Other info ]
N/A

unblock postsrsd/1.10-2
diff -Nru postsrsd-1.10/debian/changelog postsrsd-1.10/debian/changelog
--- postsrsd-1.10/debian/changelog	2020-12-02 22:36:36.000000000 +0100
+++ postsrsd-1.10/debian/changelog	2021-07-14 21:21:11.000000000 +0200
@@ -1,4 +1,12 @@
-postsrsd (1.10-1) UNRELEASED; urgency=medium
+postsrsd (1.10-2) 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:21:11 +0200
+
+postsrsd (1.10-1) unstable; urgency=medium
 
   * New upstream release (Closes: #975633)
   * Drop patches integrated upstream
diff -Nru postsrsd-1.10/debian/patches/0002-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch postsrsd-1.10/debian/patches/0002-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch
--- postsrsd-1.10/debian/patches/0002-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch	1970-01-01 01:00:00.000000000 +0100
+++ postsrsd-1.10/debian/patches/0002-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch	2021-07-14 21:21:11.000000000 +0200
@@ -0,0 +1,211 @@
+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.
+
+Origin: https://github.com/roehling/postsrsd/commit/077be98d8c8a9847e4ae0c7dc09e7474cbe27db2
+Forwarded: not-needed
+Last-Update: 2021-07-14
+---
+ postsrsd.c              | 52 ++++++++++++++++++++++++++++++-------------------
+ run_postsrsd_tests.bats | 40 +++++++++++++++++++++++++++++++++----
+ 2 files changed, 68 insertions(+), 24 deletions(-)
+
+diff --git a/postsrsd.c b/postsrsd.c
+index c009d8f..5ebf7f6 100644
+--- a/postsrsd.c
++++ b/postsrsd.c
+@@ -518,9 +518,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) {
+@@ -540,41 +540,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) {
+-              fprintf (fp, "500 Invalid request\n");
+-              fflush(fp);
++              fprintf (fp_write, "500 Invalid request\n");
++              fflush(fp_write);
+               return EXIT_FAILURE;
+             }
+-            handler[sc](srs, fp, key, domain, excludes);
+-            fflush (fp);
+-            if (poll(fds, 1, timeout * 1000) <= 0) break;
+-            line = fgets(linebuf, sizeof(linebuf), fp);
++            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 --git a/run_postsrsd_tests.bats b/run_postsrsd_tests.bats
+index f4b04bb..3d52a50 100755
+--- a/run_postsrsd_tests.bats
++++ b/run_postsrsd_tests.bats
+@@ -2,9 +2,9 @@
+ # vim: filetype=bash:
+ 
+ if [ ! -x "$POSTSRSD" ]
+ then
+-	for builddir in . build* obj*
++	for builddir in . build* obj* _build*
+ 	do
+ 		if [ -x "${builddir}/postsrsd" ]
+ 		then
+ 			POSTSRSD="${builddir}/postsrsd"
+@@ -14,9 +14,9 @@ then
+ fi
+ if [ ! -x "$POSTSRSD" ]
+ then
+ 	cat>&2 <<- EOF
+-	cannot find postsrsd executable (looked in ., build*, obj*)
++	cannot find postsrsd executable (looked in ., build*, obj*, _build*)
+ 	please build the executable first, or set the POSTSRSD
+ 	environment variable if it is in a different location.
+ 
+ 	EOF
+@@ -25,14 +25,21 @@ fi
+ 
+ LANG=C.UTF-8
+ 
+ 
++fillchar()
++{
++        local count="$1"
++        local char="$2"
++        eval 'printf "'"$char"'%.0s" {1..'"$count"'}'
++}
++
+ start_postsrsd_at()
+ {
+ 	echo 'tops3cr3t' > "$BATS_TMPDIR/postsrsd.secret"
+ 	local faketime="$1"
+ 	shift
+-	faketime "${faketime}" ${POSTSRSD} -D -f 10001 -r 10002 -p "$BATS_TMPDIR/postsrsd.pid" -s "$BATS_TMPDIR/postsrsd.secret" -d example.com "$@"
++	faketime "${faketime}" ${POSTSRSD} -D -t1 -f 10001 -r 10002 -p "$BATS_TMPDIR/postsrsd.pid" -s "$BATS_TMPDIR/postsrsd.secret" -d example.com "$@"
+ }
+ 
+ stop_postsrsd()
+ {
+@@ -158,9 +165,9 @@ teardown()
+ 	read<&9 line
+ 	[[ "$line" =~ ^"500 Domain excluded" ]]
+ }
+ 
+-@test "SRS invalid requests" {
++@test "Malformed or invalid requests" {
+ 	start_postsrsd_at "2020-01-01 00:01:00 UTC"
+ 	exec 9<>/dev/tcp/127.0.0.1/10001
+ 	echo>&9 "get"
+ 	read<&9 line
+@@ -172,5 +179,30 @@ teardown()
+ 	exec 9<>/dev/tcp/127.0.0.1/10001
+ 	echo>&9 "get encoding%error@otherdomain.com"
+ 	read<&9 line
+ 	[[ "$line" =~ ^500 ]]
++	exec 9<>/dev/tcp/127.0.0.1/10001
++	# Try to overflow the input buffer
++	echo>&9 "get too_long@`fillchar 1024 a`.com"
++	read<&9 line
++	[[ "$line" =~ ^500 ]]
++}
++
++@test "Pipelining multiple requests" {
++	start_postsrsd_at "2020-01-01 00:01:00 UTC"
++	exec 9<>/dev/tcp/127.0.0.1/10001
++	# Send two requests at once and see if PostSRSd answers both
++	echo>&9 -e "get test@domain1.com\nget test@domain2.com"
++	read<&9 line
++	[[ "$line" =~ ^200 ]]
++	read<&9 line
++	[[ "$line" =~ ^200 ]]
++}
++
++@test "Session timeout" {
++	start_postsrsd_at "2020-01-01 00:01:00 UTC"
++	exec 9<>/dev/tcp/127.0.0.1/10001
++	# Wait until PostSRSd disconnects due to inactivity
++	sleep 2
++	echo >&9 "get test@example.com"
++	! read <&9 line
+ }
diff -Nru postsrsd-1.10/debian/patches/series postsrsd-1.10/debian/patches/series
--- postsrsd-1.10/debian/patches/series	2020-12-02 22:36:36.000000000 +0100
+++ postsrsd-1.10/debian/patches/series	2021-07-14 21:21:11.000000000 +0200
@@ -1 +1,2 @@
 0001-Run-as-postsrsd-user-by-default.patch
+0002-SECURITY-Fix-DoS-on-overly-long-input-from-Postfix.patch

--- End Message ---
--- Begin Message ---
Hi,

On 01-08-2021 09:43, Salvatore Bonaccorso wrote:
> Not sure if Tomasz is available, and given the window for aksing
> unblock requests is closing very quickly I uploaded your change.

unblocked, thanks.

Paul

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


--- End Message ---

Reply to: