Version in base suite: 2.13.0-3 Base version: amavisd-new_2.13.0-3 Target version: amavisd-new_2.13.0-3+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/a/amavisd-new/amavisd-new_2.13.0-3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/a/amavisd-new/amavisd-new_2.13.0-3+deb12u1.dsc amavisd-new.postinst | 2 changelog | 8 gbp.conf | 2 patches/0010-Apply-fix-for-CVE-2024-28054.patch | 213 ++++++++++++++++++++++++ patches/series | 1 rules | 12 - 6 files changed, 232 insertions(+), 6 deletions(-) diff -Nru amavisd-new-2.13.0/debian/amavisd-new.postinst amavisd-new-2.13.0/debian/amavisd-new.postinst --- amavisd-new-2.13.0/debian/amavisd-new.postinst 2023-02-23 04:59:36.000000000 +0000 +++ amavisd-new-2.13.0/debian/amavisd-new.postinst 2024-02-29 22:56:51.000000000 +0000 @@ -95,6 +95,8 @@ fi done fi + + deb-systemd-invoke start amavis amavis-mc amavisd-snmp-subagent ;; abort-upgrade|abort-remove|abort-deconfigure) diff -Nru amavisd-new-2.13.0/debian/changelog amavisd-new-2.13.0/debian/changelog --- amavisd-new-2.13.0/debian/changelog 2023-05-11 22:52:23.000000000 +0000 +++ amavisd-new-2.13.0/debian/changelog 2024-02-29 22:56:51.000000000 +0000 @@ -1,3 +1,11 @@ +amavisd-new (1:2.13.0-3+deb12u1) stable; urgency=medium + + * Fix race condition in postinst. Closes: #1064349. + * CVE-2024-28054: Handle multiple boundary parameters that contain + conflicting values. + + -- Brian May Fri, 01 Mar 2024 09:56:51 +1100 + amavisd-new (1:2.13.0-3) unstable; urgency=medium * Fix failure to purge without adduser. Closes: #1035841. diff -Nru amavisd-new-2.13.0/debian/gbp.conf amavisd-new-2.13.0/debian/gbp.conf --- amavisd-new-2.13.0/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ amavisd-new-2.13.0/debian/gbp.conf 2024-02-29 22:56:51.000000000 +0000 @@ -0,0 +1,2 @@ +[DEFAULT] +debian-branch=debian/bookworm diff -Nru amavisd-new-2.13.0/debian/patches/0010-Apply-fix-for-CVE-2024-28054.patch amavisd-new-2.13.0/debian/patches/0010-Apply-fix-for-CVE-2024-28054.patch --- amavisd-new-2.13.0/debian/patches/0010-Apply-fix-for-CVE-2024-28054.patch 1970-01-01 00:00:00.000000000 +0000 +++ amavisd-new-2.13.0/debian/patches/0010-Apply-fix-for-CVE-2024-28054.patch 2024-02-29 22:56:51.000000000 +0000 @@ -0,0 +1,213 @@ +From: Brian May +Date: Tue, 12 Mar 2024 09:34:58 +1100 +Subject: Apply fix for CVE-2024-28054 + +--- + README_FILES/README.CVE-2024-28054 | 54 ++++++++++++++++++++++++++++++++++++++ + conf/amavisd.conf | 1 + + lib/Amavis.pm | 8 +++--- + lib/Amavis/Conf.pm | 2 ++ + lib/Amavis/Unpackers.pm | 5 ++-- + lib/Amavis/Unpackers/MIME.pm | 19 ++++++++++++++ + lib/Amavis/Unpackers/Part.pm | 3 ++- + 7 files changed, 86 insertions(+), 6 deletions(-) + create mode 100644 README_FILES/README.CVE-2024-28054 + +diff --git a/README_FILES/README.CVE-2024-28054 b/README_FILES/README.CVE-2024-28054 +new file mode 100644 +index 0000000..757c5c1 +--- /dev/null ++++ b/README_FILES/README.CVE-2024-28054 +@@ -0,0 +1,54 @@ ++# Problem description ++ ++Emails which consist of multiple parts (`Content-Type: multipart/*`) ++incorporate boundary information stating at which point one part ends and the ++next part begins. ++ ++A boundary is announced by an Content-Type header's `boundary` parameter. To ++our current knowledge, RFC2046 and RFC2045 do not explicitly specify how a ++parser should handle multiple boundary parameters that contain conflicting ++values. As a result, there is no canonical choice which of the values should or ++should not be used for mime part decomposition. ++ ++It turns out that MIME::Parser from MIME-tools chooses the last `boundary` ++parameter of a Content-Type-header, while several mail user agents choose the ++first occuring one. As a consequence, Amavis will apply some of its routines to ++content that a receiving MUA will not see, and vice-versa will not apply them ++to content that the receiving MUA will see. Such routines are at least ++- the banned-files check, and ++- the virus check, unless ++ - Amavis feeds the whole email into the virus scanner, and ++ - the virus scanner implements its own email parsing that aligns with the ++ receiving MUA's parser implementation. ++ ++MIME::Parser does not provide a choice which of multiple `boundary` parameters ++shall be used for parsing, but it will give feedback in such a case [1], which ++Amavis can react to. ++Emails with ambiguous content, like multiple `boundary` parameters as described ++above, will be categorized as `CC_UNCHECKED,3`, since Amavis has no information ++about the recipient's MUA's parser implementation. ++ ++# Recommendation ++ ++Legitimate emails are not expected to have ambiguous content, so an Amavis setup ++should treat them harshly. The new default configuration for `CC_UNCHECKED,3` is ++defanging: ++ ++``` ++$defang_by_ccat{CC_UNCHECKED.",3"} = 1; # ambiguous content (e.g. multipart boundary) ++``` ++ ++Another possibility would be quarantining, e.g. via ++ ++``` ++$quarantine_to_maps_by_ccat{CC_UNCHECKED.",3"} = [1]; ++$quarantine_method_by_ccat{CC_UNCHECKED.",3"} = 'local:unchecked-ambiguous-%m'; ++``` ++ ++and/or discarding/rejecting the email: ++ ++``` ++$final_destiny_maps_by_ccat{CC_UNCHECKED.",3"} = D_REJECT; # or D_DISCARD ++``` ++ ++[1] https://metacpan.org/release/DSKOLL/MIME-tools-5.514/changes +diff --git a/conf/amavisd.conf b/conf/amavisd.conf +index f9de495..0a63cd9 100644 +--- a/conf/amavisd.conf ++++ b/conf/amavisd.conf +@@ -148,6 +148,7 @@ $defang_banned = 1; # MIME-wrap passed mail containing banned name + $defang_by_ccat{CC_BADH.",3"} = 1; # NUL or CR character in header + $defang_by_ccat{CC_BADH.",5"} = 1; # header line longer than 998 characters + $defang_by_ccat{CC_BADH.",6"} = 1; # header field syntax error ++$defang_by_ccat{CC_UNCHECKED.",3"} = 1; # ambiguous content (e.g. multipart boundary) + + # TLS verification example + # $tls_security_level_out = 'may'; +diff --git a/lib/Amavis.pm b/lib/Amavis.pm +index f49135f..5c7519b 100644 +--- a/lib/Amavis.pm ++++ b/lib/Amavis.pm +@@ -2483,16 +2483,18 @@ sub check_mail($$) { + + $which_section = "parts_decode_ext"; + snmp_count('OpsDec'); +- my($any_encrypted,$over_levels); +- ($hold, $any_undecipherable, $any_encrypted, $over_levels) = ++ my($any_encrypted,$over_levels,$ambiguous); ++ ($hold, $any_undecipherable, $any_encrypted, $over_levels, $ambiguous) = + Amavis::Unpackers::decompose_mail($msginfo->mail_tempdir, + $file_generator_object); +- $any_undecipherable ||= ($any_encrypted || $over_levels); ++ $any_undecipherable ||= ($any_encrypted || $over_levels || $ambiguous); + if ($any_undecipherable) { + $msginfo->add_contents_category(CC_UNCHECKED,0); + $msginfo->add_contents_category(CC_UNCHECKED,1) if $any_encrypted; + $msginfo->add_contents_category(CC_UNCHECKED,2) if $over_levels; ++ $msginfo->add_contents_category(CC_UNCHECKED,3) if $ambiguous; + for my $r (@{$msginfo->per_recip_data}) { ++ $r->add_contents_category(CC_UNCHECKED,3) if $ambiguous; + next if $r->bypass_virus_checks; + $r->add_contents_category(CC_UNCHECKED,0); + $r->add_contents_category(CC_UNCHECKED,1) if $any_encrypted; +diff --git a/lib/Amavis/Conf.pm b/lib/Amavis/Conf.pm +index 7259cca..77fd671 100644 +--- a/lib/Amavis/Conf.pm ++++ b/lib/Amavis/Conf.pm +@@ -1134,6 +1134,7 @@ BEGIN { + CC_UNCHECKED, 'Unchecked', + CC_UNCHECKED.',1', 'UncheckedEncrypted', + CC_UNCHECKED.',2', 'UncheckedOverLimits', ++ CC_UNCHECKED.',3', 'UncheckedAmbiguousContent', + CC_BANNED, 'Banned', + CC_VIRUS, 'Virus', + ); +@@ -1608,6 +1609,7 @@ BEGIN { + CC_BANNED, 'id=%n - BANNED: %F', + CC_UNCHECKED.',1', 'id=%n - UNCHECKED: encrypted', + CC_UNCHECKED.',2', 'id=%n - UNCHECKED: over limits', ++ CC_UNCHECKED.',3', 'id=%n - UNCHECKED: ambiguous content', + CC_UNCHECKED, 'id=%n - UNCHECKED', + CC_SPAM, 'id=%n - spam', + CC_SPAMMY.',1', 'id=%n - spammy (tag3)', +diff --git a/lib/Amavis/Unpackers.pm b/lib/Amavis/Unpackers.pm +index 8d6684b..f36edb5 100644 +--- a/lib/Amavis/Unpackers.pm ++++ b/lib/Amavis/Unpackers.pm +@@ -280,7 +280,7 @@ sub decompose_mail($$) { + my($tempdir,$file_generator_object) = @_; + + my $hold; my(@parts); my $depth = 1; +- my($any_undecipherable, $any_encrypted, $over_levels) = (0,0,0); ++ my($any_undecipherable, $any_encrypted, $over_levels, $ambiguous) = (0,0,0,0); + my $which_section = "parts_decode"; + # fetch all not-yet-visited part names, and start a new cycle + TIER: +@@ -342,13 +342,14 @@ TIER: + if (defined $attr) { + $any_undecipherable++ if index($attr, 'U') >= 0; + $any_encrypted++ if index($attr, 'C') >= 0; ++ $ambiguous++ if index($attr, 'B') >= 0; + } + } + last TIER if defined $hold; + $depth++; + } + section_time($which_section); prolong_timer($which_section); +- ($hold, $any_undecipherable, $any_encrypted, $over_levels); ++ ($hold, $any_undecipherable, $any_encrypted, $over_levels, $ambiguous); + } + + # Decompose one part +diff --git a/lib/Amavis/Unpackers/MIME.pm b/lib/Amavis/Unpackers/MIME.pm +index 181421f..49e035e 100644 +--- a/lib/Amavis/Unpackers/MIME.pm ++++ b/lib/Amavis/Unpackers/MIME.pm +@@ -59,6 +59,24 @@ sub mime_decode_pre_epi($$$$$) { + } + } + ++sub ambiguous_content { ++ my $entity = shift; ++ if ($entity->can('ambiguous_content')) { ++ return $entity->ambiguous_content; ++ } else { ++ return unless $entity->is_multipart; ++ my $content_type = $entity->head->get('Content-Type'); ++ if ($content_type && $content_type =~ m{^multipart/\w+(.+)}x) { ++ my ($params, $num) = ($1, 0); ++ while ($params =~ m{\G ; \s+ (?\w+) = (?: \w+ | "(?:\\.|[^"\\])*" )}gx) { ++ $num++ if lc($+{param}) eq 'boundary'; ++ } ++ return $num > 1; ++ } ++ return; ++ } ++} ++ + # traverse MIME::Entity object depth-first, + # extracting preambles and epilogues as extra (pseudo)parts, and + # filling-in additional information into Amavis::Unpackers::Part objects +@@ -73,6 +91,7 @@ sub mime_traverse($$$$$) { + if (!defined($body)) { # a MIME container only contains parts, no bodypart + # create pseudo-part objects for MIME containers (e.g. multipart/* ) + $part = Amavis::Unpackers::Part->new(undef,$parent_obj,1); ++ $part->attributes_add('B') if ambiguous_content($entity); + # $part->type_short('no-file'); + do_log(2, "%s %s Content-Type: %s", $part->base_name, $placement, $mt); + +diff --git a/lib/Amavis/Unpackers/Part.pm b/lib/Amavis/Unpackers/Part.pm +index 0cb188e..83c1450 100644 +--- a/lib/Amavis/Unpackers/Part.pm ++++ b/lib/Amavis/Unpackers/Part.pm +@@ -65,7 +65,8 @@ sub exists + sub attributes # a string of characters representing attributes + { @_<2 ? shift->{attr} : ($_[0]->{attr} = $_[1]) }; + +-sub attributes_add { # U=undecodable, C=crypted, D=directory,S=special,L=link ++sub attributes_add { # U=undecodable, C=crypted, B=ambiguous-content, ++ # D=directory, S=special, L=link + my $self = shift; my $a = $self->{attr}; $a = '' if !defined $a; + for my $arg (@_) { $a .= $arg if $arg ne '' && index($a,$arg) < 0 } + $self->{attr} = $a; diff -Nru amavisd-new-2.13.0/debian/patches/series amavisd-new-2.13.0/debian/patches/series --- amavisd-new-2.13.0/debian/patches/series 2023-02-23 04:59:36.000000000 +0000 +++ amavisd-new-2.13.0/debian/patches/series 2024-02-29 22:56:51.000000000 +0000 @@ -7,3 +7,4 @@ 85-clarify_fqdn_error.patch 90_fix_snmp_subagent_warning 95_amavisd_helpers_fixes +0010-Apply-fix-for-CVE-2024-28054.patch diff -Nru amavisd-new-2.13.0/debian/rules amavisd-new-2.13.0/debian/rules --- amavisd-new-2.13.0/debian/rules 2023-02-23 23:13:24.000000000 +0000 +++ amavisd-new-2.13.0/debian/rules 2024-02-29 22:56:51.000000000 +0000 @@ -13,12 +13,12 @@ mv debian/amavisd-new/usr/bin debian/amavisd-new/usr/sbin override_dh_installsystemd: - dh_installsystemd --name=amavis - dh_installsystemd --name=amavis-mc --no-enable - dh_installsystemd --name=amavisd-snmp-subagent --no-enable - dh_installinit --name=amavis - dh_installinit --name=amavis-mc --no-enable - dh_installinit --name=amavisd-snmp-subagent --no-enable + dh_installsystemd --name=amavis --no-start + dh_installsystemd --name=amavis-mc --no-start --no-enable + dh_installsystemd --name=amavisd-snmp-subagent --no-start --no-enable + dh_installinit --name=amavis --no-start + dh_installinit --name=amavis-mc --no-start --no-enable + dh_installinit --name=amavisd-snmp-subagent --no-start --no-enable override_dh_installchangelogs: dh_installchangelogs -k RELEASE_NOTES