summaryrefslogtreecommitdiffstats
path: root/debian/patches/84_19-Security-Avoid-decrement-of-dkim_collect_input-if-al.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches/84_19-Security-Avoid-decrement-of-dkim_collect_input-if-al.patch59
1 files changed, 59 insertions, 0 deletions
diff --git a/debian/patches/84_19-Security-Avoid-decrement-of-dkim_collect_input-if-al.patch b/debian/patches/84_19-Security-Avoid-decrement-of-dkim_collect_input-if-al.patch
new file mode 100644
index 0000000..a2b52fe
--- /dev/null
+++ b/debian/patches/84_19-Security-Avoid-decrement-of-dkim_collect_input-if-al.patch
@@ -0,0 +1,59 @@
+From 031ae594f6e68511117f6d39ce238b0c5215d8d1 Mon Sep 17 00:00:00 2001
+From: Qualys Security Advisory <qsa@qualys.com>
+Date: Sun, 21 Feb 2021 22:19:42 -0800
+Subject: [PATCH 19/29] Security: Avoid decrement of dkim_collect_input if
+ already at 0
+
+Based on Heiko Schlittermann's commit bf2d6e58. This fixes:
+
+5/ receive_msg() calls dkim_exim_verify_finish(), which sets
+dkim_collect_input to 0 and calls pdkim_feed_finish(), which calls
+pdkim_header_complete(), which decreases dkim_collect_input to UINT_MAX,
+which reactivates the DKIM code.
+
+As a result, pdkim_feed() is called again (through receive_getc at the
+end of receive_msg()), but functions like pdkim_finish_bodyhash() and
+exim_sha_finish() have already been called (in pdkim_feed_finish()).
+This suggests a use-after-free.
+
+But it seems that a use-after-free would happen only with
+EVP_DigestFinal() (in exim_sha_finish()), which does not seem to be
+reachable via DKIM (no SHA3). But we checked OpenSSL only, not GnuTLS.
+
+Here is a proof of concept that triggers the bug (which came very close
+to a security vulnerability):
+
+(sleep 10; echo 'EHLO test'; sleep 3; echo 'MAIL FROM:<>'; sleep 3; echo 'RCPT TO:postmaster'; sleep 3; echo 'BDAT 42 LAST'; date >&2; sleep 30; printf 'not a valid header line\r\n
+DKIM-Signature:\r\nXXX'; sleep 30) | nc -n -v 192.168.56.102 25
+
+(gdb) print &dkim_collect_input
+$2 = (unsigned int *) 0x55e180386d90 <dkim_collect_input>
+(gdb) watch *(unsigned int *) 0x55e180386d90
+
+Hardware watchpoint 1: *(unsigned int *) 0x55e180386d90
+Old value = 0
+New value = 4294967295
+#0 0x000055e18031f805 in pdkim_header_complete (ctx=ctx@entry=0x55e181b9e8e0) at pdkim.c:1006
+#1 0x000055e18032106c in pdkim_feed_finish (ctx=0x55e181b9e8e0, return_signatures=0x55e180386d78 <dkim_signatures>, err=err@entry=0x7ffe443e1d00) at pdkim.c:1490
+#2 0x000055e1802a3280 in dkim_exim_verify_finish () at dkim.c:328
+#3 0x000055e1802c9d1d in receive_msg (extract_recip=extract_recip@entry=0) at receive.c:3409
+---
+ src/pdkim/pdkim.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/pdkim/pdkim.c b/src/pdkim/pdkim.c
+index e203311da..e3233e9f0 100644
+--- a/src/pdkim/pdkim.c
++++ b/src/pdkim/pdkim.c
+@@ -1010,7 +1010,7 @@ else
+ last_sig->next = sig;
+ }
+
+- if (--dkim_collect_input == 0)
++ if (dkim_collect_input && --dkim_collect_input == 0)
+ {
+ ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
+ ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
+--
+2.30.2
+