From: Timo Sirainen Date: Fri, 17 Apr 2026 13:55:48 +0000 (+0200) Subject: [PATCH 12/14] lib-mail: Limit total address count per message to 100 000 X-Git-Tag: archive/raspbian/1%2.4.1+dfsg1-6+rpi1+deb13u7^2~52 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0b03d253e419b2c7e6e17611ec45969cc26be0d5;p=dovecot.git [PATCH 12/14] lib-mail: Limit total address count per message to 100 000 A message with millions of addresses across all its envelope headers can exhaust memory when parsed (each struct message_address is ~100 bytes regardless of whether the raw address is only a few bytes long). Add remaining_addresses to struct message_part_data_limits, initialised to MESSAGE_PART_DATA_MAX_TOTAL_ADDRESSES (100 000). Pass the remaining budget as max_addresses to message_address_parse_full() so parsing stops at the limit, then deduct the actual count parsed from the budget. Co-Authored-By: Claude Sonnet 4.6 Gbp-Pq: Name 0012-lib-mail-Limit-total-address-count-per-message-to-10.patch --- diff --git a/src/lib-mail/message-part-data.c b/src/lib-mail/message-part-data.c index c302fe5..24e1a31 100644 --- a/src/lib-mail/message-part-data.c +++ b/src/lib-mail/message-part-data.c @@ -173,7 +173,7 @@ envelope_get_field(const char *name) void message_part_envelope_parse_from_header(pool_t pool, struct message_part_envelope **data, - struct message_part_data_limits *limits ATTR_UNUSED, + struct message_part_data_limits *limits, struct message_header_line *hdr) { struct message_part_envelope *d; @@ -238,9 +238,12 @@ void message_part_envelope_parse_from_header(pool_t pool, if (addr_p != NULL) { message_address_parse_full(pool, hdr->full_value, hdr->full_value_len, - UINT_MAX, + limits->remaining_addresses, MESSAGE_ADDRESS_PARSE_FLAG_FILL_MISSING, &new_addr); + i_assert(new_addr.count <= limits->remaining_addresses); + limits->remaining_addresses -= new_addr.count; + /* Merge multiple headers the same as if they were comma separated in a single line. This is better from security point of view, because attacker could intentionally write diff --git a/src/lib-mail/message-part-data.h b/src/lib-mail/message-part-data.h index 1514f0d..af09ea7 100644 --- a/src/lib-mail/message-part-data.h +++ b/src/lib-mail/message-part-data.h @@ -8,10 +8,14 @@ struct message_header_line; +#define MESSAGE_PART_DATA_MAX_TOTAL_ADDRESSES 100000 + struct message_part_data_limits { + unsigned int remaining_addresses; }; -#define MESSAGE_PART_DATA_LIMITS_INIT { } +#define MESSAGE_PART_DATA_LIMITS_INIT \ + { MESSAGE_PART_DATA_MAX_TOTAL_ADDRESSES } struct message_part_param { const char *name;