Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: amavisd-...@packages.debian.org, b...@debian.org
Control: affects -1 + src:amavisd-new

[ Reason ]

* Fix race condition on initial install. Closes: #1064349.
* Fix CVE-2024-28054.

[ Impact ]

Without this path:

* Possible errors on initial installation.
* CVE-2024-28054 won't be fixed, and amavisd-new could potentially let through 
mallacious emails.

[ Tests ]

No tests.

[ Risks ]

Patch could break with risk that geniune emails get blocked.

[ Checklist ]
  [X] *all* changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in (old)stable
  [X] the issue is verified as fixed in unstable

[ Changes ]

As below.

[ Other info ]

I hope I am doing this right :-)


=== debdiff ===

root@08c7f517533c:/tmp/brian/tmp5u_5mq1q/build# debdiff 
old/amavisd-new_2.13.0-3.dsc  amd64/amavisd-new_2.13.0-3+deb12u1.dsc
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 <b...@debian.org>  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 <br...@linuxpenguins.xyz>
+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+ (?<param>\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

Reply via email to