diff options
Diffstat (limited to 'debian/patches/84_21-Security-Avoid-modification-of-constant-data-in-dkim.patch')
-rw-r--r-- | debian/patches/84_21-Security-Avoid-modification-of-constant-data-in-dkim.patch | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/debian/patches/84_21-Security-Avoid-modification-of-constant-data-in-dkim.patch b/debian/patches/84_21-Security-Avoid-modification-of-constant-data-in-dkim.patch new file mode 100644 index 0000000..b723d0f --- /dev/null +++ b/debian/patches/84_21-Security-Avoid-modification-of-constant-data-in-dkim.patch @@ -0,0 +1,89 @@ +From a4e1b7755ebbdee2689d40683ba69f09e38a8d7f Mon Sep 17 00:00:00 2001 +From: Qualys Security Advisory <qsa@qualys.com> +Date: Sun, 21 Feb 2021 22:30:03 -0800 +Subject: [PATCH 21/29] Security: Avoid modification of constant data in dkim + handling + +Based on Heiko Schlittermann's commits f880c7f3 and c118c7f4. This +fixes: + +6/ In src/pdkim/pdkim.c, pdkim_update_ctx_bodyhash() is sometimes called +with a global orig_data and hence canon_data, and the following line can +therefore modify data that should be constant: + + 773 canon_data->len = b->bodylength - b->signed_body_bytes; + +For example, the following proof of concept sets lineending.len to 0 +(this should not be possible): + +(sleep 10; echo 'EHLO test'; sleep 3; echo 'MAIL FROM:<>'; sleep 3; echo 'RCPT TO:postmaster'; sleep 3; echo 'DATA'; date >&2; sleep 30; printf 'DKIM-Signature:a=rsa-sha1;c=simple/simple;l=0\r\n\r\n\r\nXXX\r\n.\r\n'; sleep 30) | nc -n -v 192.168.56.102 25 + +(gdb) print lineending +$1 = {data = 0x55e18035b2ad "\r\n", len = 2} +(gdb) print &lineending.len +$3 = (size_t *) 0x55e180385948 <lineending+8> +(gdb) watch *(size_t *) 0x55e180385948 + +Hardware watchpoint 1: *(size_t *) 0x55e180385948 +Old value = 2 +New value = 0 +(gdb) print lineending +$5 = {data = 0x55e18035b2ad "\r\n", len = 0} +--- + src/pdkim/pdkim.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/src/pdkim/pdkim.c b/src/pdkim/pdkim.c +index e3233e9f0..512a3e352 100644 +--- a/src/pdkim/pdkim.c ++++ b/src/pdkim/pdkim.c +@@ -107,7 +107,7 @@ pdkim_combined_canon_entry pdkim_combined_canons[] = { + }; + + +-static blob lineending = {.data = US"\r\n", .len = 2}; ++static const blob lineending = {.data = US"\r\n", .len = 2}; + + /* -------------------------------------------------------------------------- */ + uschar * +@@ -719,9 +719,11 @@ return NULL; + If we have to relax the data for this sig, return our copy of it. */ + + static blob * +-pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data) ++pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, const blob * orig_data, blob * relaxed_data) + { +-blob * canon_data = orig_data; ++const blob * canon_data = orig_data; ++size_t left; ++ + /* Defaults to simple canon (no further treatment necessary) */ + + if (b->canon_method == PDKIM_CANON_RELAXED) +@@ -767,16 +769,17 @@ if (b->canon_method == PDKIM_CANON_RELAXED) + } + + /* Make sure we don't exceed the to-be-signed body length */ ++left = canon_data->len; + if ( b->bodylength >= 0 +- && b->signed_body_bytes + (unsigned long)canon_data->len > b->bodylength ++ && left > (unsigned long)b->bodylength - b->signed_body_bytes + ) +- canon_data->len = b->bodylength - b->signed_body_bytes; ++ left = (unsigned long)b->bodylength - b->signed_body_bytes; + +-if (canon_data->len > 0) ++if (left > 0) + { +- exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, canon_data->len); +- b->signed_body_bytes += canon_data->len; +- DEBUG(D_acl) pdkim_quoteprint(canon_data->data, canon_data->len); ++ exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, left); ++ b->signed_body_bytes += left; ++ DEBUG(D_acl) pdkim_quoteprint(canon_data->data, left); + } + + return relaxed_data; +-- +2.30.2 + |