X-Git-Url: https://git.hcoop.net/hcoop/debian/exim4.git/blobdiff_plain/798bcb8a094a3a7399d04d760c882f4f25922f41..0c0c20aac64e1ef4037c144efec9a064add0d055:/debian/patches/84_19-Security-Avoid-decrement-of-dkim_collect_input-if-al.patch 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 +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 +(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 , 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 +