[exim-cvs] SECURITY: Avoid integer overflow on too many reci…

Startseite
Nachricht löschen
Nachricht beantworten
Autor: Exim Git Commits Mailing List
Datum:  
To: exim-cvs
Betreff: [exim-cvs] SECURITY: Avoid integer overflow on too many recipients
Gitweb: https://git.exim.org/exim.git/commitdiff/0695aae1eb75b439862d0f7fbf099b5d08f55af0
Commit:     0695aae1eb75b439862d0f7fbf099b5d08f55af0
Parent:     f07847e436d1130628717ef92e46b56b293d5fa1
Author:     Phil Pennock <phil+git@???>
AuthorDate: Thu Oct 29 21:48:05 2020 -0400
Committer:  Heiko Schlittermann (HS12-RIPE) <hs@???>
CommitDate: Thu May 27 21:30:29 2021 +0200


    SECURITY: Avoid integer overflow on too many recipients


    (cherry picked from commit 323ff55e67b44e95f9d3cfaba155e385aa33c4bd)
    (cherry picked from commit 3a54fcd1e303bf1cc49beca7ceac35d7448860a9)
---
 doc/doc-txt/ChangeLog | 5 +++++
 src/src/receive.c     | 7 +++++++
 2 files changed, 12 insertions(+)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 89a60e7..3d0e638 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 b0dacbd..67971c3 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));