Security
- Fixed catastrophic regex backtracking in the plain-text failure report fallback (GHSA-7grx-mj6g-qxmc, affects 8.2.0 through 11.0.3). A
text/plainmessage containingA message claiming to be from you has failedis parsed as an Exim/cPanel failure notice bytext_report_regex,\s*([a-zA-Z\s]+):\s(.+). Its leading\s*and the\sinside the field-name class can each consume the same whitespace, and the pattern is unanchored, so a run of whitespace is retried from every starting position and every way of splitting it: the cost grows cubically, about 8x per doubling — on CPython 3.12 (x86-64), 400 spaces took 0.06 s and 1600 spaces took 3.3 s. Anyone who can send mail to a monitored mailbox controls the body, so a message of about 100 KB would stall the mailbox watch loop for days, and since the message is never marked processed it would be re-parsed after every restart. The pattern is now anchored to the start of a line and its classes no longer overlap, so it runs in linear time. The pattern now requires a field name to start a line, with its words separated by single spaces, which is what Exim emits; notices with a tab, doubled space, or line break inside a field name were already rejected, because such names never produced the keys the parser looks up. Reported by mjatin2007. - Fixed quadratic regex backtracking when stripping XML schema tags from aggregate reports (GHSA-4h9r-c435-j834, affects 4.1.7 through 11.0.3).
parse_aggregate_report_xml()removed<xs:schema>tags with</??xs:schema.*>, whose unanchored greedy.*>scanned to the end of the line for every<xs:schemait found, so a line of repeated<xs:schematook quadratic time — 1 MB took 19 s. The pattern runs on report attachments after gzip and zip are inflated, up to the 100 MiB decompression cap, and about 194 KB of gzip inflates to that cap. The pattern now stops at the first>(</?xs:schema[^<>]*>) and runs in linear time. This also fixes a correctness bug: on a minified report with the whole document on one line, the greedy.*>deleted everything from the schema tag to the last>on the line, discarding the report.
Bug fixes
- Parsing a timestamp no longer takes quadratic time on whitespace.
human_timestamp_to_datetime()stripped parenthesized comments with the regex\s*\(.*\)\s*, whose leading\s*retried every whitespace run from each starting position. The function runs on every message'sDateheader, so a long folded header was enough: 200,000 spaces took 18.6 s. This is the same weakness as the two entries above, but a lesser one: the input is a header that mail servers cap in size (Postfix's default is 100 KB, about 5 s) rather than an attachment inflated to the 100 MiB decompression cap, so it is filed as a bug fix without an advisory. Comments are now removed by a single depth-counting pass, which is linear and also handles the nested comments and quoted-pairs that RFC 5322 section 3.2.2 allows and that the old regex only stripped by accident. - The Grafana dashboard's "Message sources by name and type" table no longer comes up empty when a message source has a name but no type. Whenever a source's reverse DNS base domain is not in
base_reverse_dns_map.csv,get_service_from_reverse_dns_base_domain()names the source after that base domain and leaves its typeNone; a source with no PTR record whose AS domain is not in the map is likewise named after its AS name with no type. For every such source the saved aggregate record has asource_namebut nosource_type. The panel nests atermsaggregation onsource_type.keywordunder one onsource_name.keyword, without amissingvalue, so such a source produced asource_namebucket with nosource_typesub-bucket, and Grafana's Elasticsearch data source then failed to build the table from the response. With Grafana 13.2.4 (bundled Elasticsearch data source 12.9.2) and the reports insamples/aggregate/, 12 sources had a name but no type and the table showed "No data"; withmissingset, it lists all 27 name/type rows. Thesource_type.keywordaggregation now setsmissingto-, the placeholder most of the dashboard's other tables already use for absent values, so those sources are listed with-as their type.