diff options
author | Phil Pennock <phil+git@pennock-tech.com> | 2020-10-29 21:48:05 -0400 |
---|---|---|
committer | Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de> | 2021-05-27 21:30:29 +0200 |
commit | 0695aae1eb75b439862d0f7fbf099b5d08f55af0 (patch) | |
tree | e2ba05c3ee0d00311d4bd76577d27c68124f5e40 | |
parent | f07847e436d1130628717ef92e46b56b293d5fa1 (diff) |
SECURITY: Avoid integer overflow on too many recipients
(cherry picked from commit 323ff55e67b44e95f9d3cfaba155e385aa33c4bd)
(cherry picked from commit 3a54fcd1e303bf1cc49beca7ceac35d7448860a9)
-rw-r--r-- | doc/doc-txt/ChangeLog | 5 | ||||
-rw-r--r-- | src/src/receive.c | 7 |
2 files changed, 12 insertions, 0 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 89a60e757..3d0e638d2 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -280,6 +280,11 @@ PP/07 Refuse to allocate too little memory, block negative/zero allocations. PP/08 Change default for recipients_max from unlimited to 50,000. +PP/09 Fix security issue with too many recipients on a message (to remove a + known security problem if someone does set recipients_max to unlimited, + or if local additions add to the recipient list). + Fixes CVE-2020-RCPTL reported by Qualys. + Exim version 4.94 ----------------- diff --git a/src/src/receive.c b/src/src/receive.c index b0dacbd68..67971c3e4 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -486,11 +486,18 @@ Returns: nothing void receive_add_recipient(uschar *recipient, int pno) { +/* XXX This is a math limit; we should consider a performance/sanity limit too. */ +const int safe_recipients_limit = INT_MAX / sizeof(recipient_item) - 1; + if (recipients_count >= recipients_list_max) { recipient_item *oldlist = recipients_list; int oldmax = recipients_list_max; recipients_list_max = recipients_list_max ? 2*recipients_list_max : 50; + if ((recipients_list_max >= safe_recipients_limit) || (recipients_list_max < 0)) + { + log_write(0, LOG_MAIN|LOG_PANIC, "Too many recipients needed: %d not satisfiable", recipients_list_max); + } recipients_list = store_get(recipients_list_max * sizeof(recipient_item), FALSE); if (oldlist) memcpy(recipients_list, oldlist, oldmax * sizeof(recipient_item)); |