SECURITY: Avoid decrement of dkim_collect_input if already at 0
Credits: Qualys
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\nDKIM-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
(cherry picked from commit
e3674091056ac05eb7ef1c504accce790c434bd7)