Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: cyrus-im...@packages.debian.org, y...@debian.org
Control: affects -1 + src:cyrus-imapd
User: release.debian....@packages.debian.org
Usertags: pu

[ Reason ]
There was a regression introduced by CVE-2024-34055 which breaks
Cyrus-Imapd's murder (RC bug #1075853).

[ Impact ]
Installations with murder (more than one backend node) maybe broken.

[ Tests ]
No new test in these patches, however test and autopkgtest passed
(https://salsa.debian.org/debian/cyrus-imapd/-/pipelines/708722)

[ Risks ]
Low risk, patch is not so big

[ 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 ]
I chose to keep patches as given in upstream release with upstream
comments

Best regards,
Xavier
diff --git a/debian/changelog b/debian/changelog
index 39736966..8b7809d3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+cyrus-imapd (3.6.1-4+deb12u3) bookworm; urgency=medium
+
+  * Fix regression introduced in CVE-2024-34055 fix (Closes: #1075853)
+
+ -- Yadd <y...@debian.org>  Mon, 29 Jul 2024 12:43:50 +0400
+
 cyrus-imapd (3.6.1-4+deb12u2) bookworm-security; urgency=medium
 
   * Fix unbounded memory allocation (Closes: CVE-2024-34055)
diff --git a/debian/patches/CVE-2024-34055-regressions-1.patch 
b/debian/patches/CVE-2024-34055-regressions-1.patch
new file mode 100644
index 00000000..f0d4e80c
--- /dev/null
+++ b/debian/patches/CVE-2024-34055-regressions-1.patch
@@ -0,0 +1,57 @@
+Description: Instance: check backend sync to mupdate during murder shutdown
+Author: ellie timoney <el...@fastmail.com>
+Origin: upstream, https://github.com/cyrusimap/cyrus-imapd/commits/846f1f49
+Forwarded: not-needed
+Applied-Upstream: 3.6.6
+Reviewed-By: Yadd <y...@debian.org>
+Last-Update: 2024-07-29
+
+--- a/cassandane/Cassandane/Instance.pm
++++ b/cassandane/Cassandane/Instance.pm
+@@ -1378,6 +1378,38 @@
+     return;
+ }
+ 
++sub _check_mupdate
++{
++    my ($self) = @_;
++
++    my $mupdate_server = $self->{config}->get('mupdate_server');
++    return if not $mupdate_server; # not in a murder
++
++    my $serverlist = $self->{config}->get('serverlist');
++    return if $serverlist; # don't sync mboxlist on frontends
++
++    # Run ctl_mboxlist -m to sync backend mailboxes with mupdate.
++    #
++    # You typically run this from START, and we do, but at test start
++    # there's no mailboxes yet, so there's nothing to sync, and if
++    # something is broken it probably won't be detected.
++    my $basedir = $self->{basedir};
++    eval {
++        $self->run_command({
++                redirects => { stdout => "$basedir/ctl_mboxlist.out",
++                               stderr => "$basedir/ctl_mboxlist.err",
++                             },
++                cyrus => 1,
++            }, 'ctl_mboxlist', '-m');
++    };
++    if ($@) {
++        my @err = slurp_file("$basedir/ctl_mboxlist.err");
++        chomp for @err;
++        xlog "ctl_mboxlist -m failed: " . Dumper \@err;
++        return "unable to sync local mailboxes with mupdate";
++    }
++}
++
+ sub _check_sanity
+ {
+     my ($self) = @_;
+@@ -1516,6 +1548,7 @@
+     my @errors;
+ 
+     push @errors, $self->_check_sanity();
++    push @errors, $self->_check_mupdate();
+ 
+     xlog "stop $self->{description}: basedir $self->{basedir}";
+ 
diff --git a/debian/patches/CVE-2024-34055-regressions-2.patch 
b/debian/patches/CVE-2024-34055-regressions-2.patch
new file mode 100644
index 00000000..9ea66400
--- /dev/null
+++ b/debian/patches/CVE-2024-34055-regressions-2.patch
@@ -0,0 +1,142 @@
+Description: imapparse: add getmstring() for mupdate-specific parsing
+ The mupdate protocol uses LITERAL+ in server->client communications, whereas
+ in the IMAP protocol this is only permitted in client->server communications.
+ Adds a parser flag and corresponding macro to switch behaviours.
+ Fixes #4932
+Author: ellie timoney <el...@fastmail.com>
+Origin: upstream, https://github.com/cyrusimap/cyrus-imapd/commits/e35707e7
+Forwarded: not-needed
+Applied-Upstream: 3.6.6
+Reviewed-By: Yadd <y...@debian.org>
+Last-Update: 2024-07-29
+
+--- a/imap/imapparse.c
++++ b/imap/imapparse.c
+@@ -153,7 +153,10 @@
+         buf_reset(buf);
+         c = getint32(pin, &len);
+ 
+-        if (pin->isclient && c == '+') {
++        /* For IMAP, LITERAL+ is only valid from client->server.  For MUPDATE
++         * it's valid in either direction.
++         */
++        if ((pin->isclient || (flags & GXS_MUPDATE)) && c == '+') {
+             /* LITERAL- says maximum size is 4096! */
+             if (lminus && len > 4096) {
+                 /* Fail per RFC 7888, Section 4, choice 2 */
+--- a/imap/imapparse.h
++++ b/imap/imapparse.h
+@@ -59,6 +59,7 @@
+     GXS_LITERAL = (1<<2),   /* result may be {N}literal */
+     GXS_NIL     = (1<<3),   /* result may be the special atom NIL */
+     GXS_BINARY  = (1<<4),   /* result may contain embedded NULs */
++    GXS_MUPDATE = (1<<5),   /* (non-IMAP) accept LITERAL+ as client */
+ 
+     IMAP_ASTRING = GXS_ATOM|GXS_QUOTED|GXS_LITERAL,
+     IMAP_BIN_ASTRING = IMAP_ASTRING|GXS_BINARY,
+@@ -70,6 +71,8 @@
+     /* note: there's some consistency issues here... the special
+      * value "NIL" must be quoted to get returned as a string */
+     IMAP_NASTRING = GXS_NIL|GXS_ATOM|GXS_QUOTED|GXS_LITERAL,
++
++    MUPDATE_STRING = IMAP_STRING|GXS_MUPDATE,
+ };
+ 
+ int getxstring(struct protstream *pin, struct protstream *pout,
+@@ -81,6 +84,7 @@
+ #define getqstring(pin, pout, buf) getxstring((pin), (pout), (buf), 
IMAP_QSTRING)
+ #define getstring(pin, pout, buf) getxstring((pin), (pout), (buf), 
IMAP_STRING)
+ #define getnastring(pin, pout, buf) getxstring((pin), (pout), (buf), 
IMAP_NASTRING)
++#define getmstring(pin, pout, buf) getxstring((pin), (pout), (buf), 
MUPDATE_STRING)
+ #define getcharset(pin, pout, buf) getxstring((pin), (pout), (buf), 
GXS_ATOM|GXS_QUOTED)
+ int getint32(struct protstream *pin, int *num);
+ int getint64(struct protstream *pin, int64_t *num);
+--- a/imap/mupdate-client.c
++++ b/imap/mupdate-client.c
+@@ -620,7 +620,7 @@
+         switch(handle->cmd.s[0]) {
+         case 'B':
+             if (!strncmp(handle->cmd.s, "BAD", 3)) {
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+                 CHECKNEWLINE(handle, ch);
+ 
+                 syslog(LOG_ERR, "mupdate BAD response: %s", handle->arg1.s);
+@@ -629,7 +629,7 @@
+                 }
+                 goto done;
+             } else if (!strncmp(handle->cmd.s, "BYE", 3)) {
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+                 CHECKNEWLINE(handle, ch);
+ 
+                 syslog(LOG_ERR, "mupdate BYE response: %s", handle->arg1.s);
+@@ -642,7 +642,7 @@
+ 
+         case 'D':
+             if (!strncmp(handle->cmd.s, "DELETE", 6)) {
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+                 CHECKNEWLINE(handle, ch);
+ 
+                 memset(&box, 0, sizeof(box));
+@@ -662,21 +662,21 @@
+         case 'M':
+             if (!strncmp(handle->cmd.s, "MAILBOX", 7)) {
+                 /* Mailbox Name */
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+                 if (ch != ' ') {
+                     r = MUPDATE_PROTOCOL_ERROR;
+                     goto done;
+                 }
+ 
+                 /* Server */
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg2));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg2));
+                 if (ch != ' ') {
+                     r = MUPDATE_PROTOCOL_ERROR;
+                     goto done;
+                 }
+ 
+                 /* ACL */
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg3));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg3));
+                 CHECKNEWLINE(handle, ch);
+ 
+                 /* Handle mailbox command */
+@@ -695,7 +695,7 @@
+             goto badcmd;
+         case 'N':
+             if (!strncmp(handle->cmd.s, "NO", 2)) {
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+                 CHECKNEWLINE(handle, ch);
+ 
+                 syslog(LOG_DEBUG, "mupdate NO response: %s", handle->arg1.s);
+@@ -709,7 +709,7 @@
+         case 'O':
+             if (!strncmp(handle->cmd.s, "OK", 2)) {
+                 /* It's all good, grab the attached string and move on */
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+ 
+                 CHECKNEWLINE(handle, ch);
+                 if (wait_for_ok) {
+@@ -722,14 +722,14 @@
+         case 'R':
+             if (!strncmp(handle->cmd.s, "RESERVE", 7)) {
+                 /* Mailbox Name */
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg1));
+                 if (ch != ' ') {
+                     r = MUPDATE_PROTOCOL_ERROR;
+                     goto done;
+                 }
+ 
+                 /* Server */
+-                ch = getstring(handle->conn->in, handle->conn->out, 
&(handle->arg2));
++                ch = getmstring(handle->conn->in, handle->conn->out, 
&(handle->arg2));
+                 CHECKNEWLINE(handle, ch);
+ 
+                 /* Handle reserve command */
diff --git a/debian/patches/CVE-2024-34055-regressions-3.patch 
b/debian/patches/CVE-2024-34055-regressions-3.patch
new file mode 100644
index 00000000..e2a6360e
--- /dev/null
+++ b/debian/patches/CVE-2024-34055-regressions-3.patch
@@ -0,0 +1,26 @@
+Description: sync_sieve_upload() always initialize buffer with script content
+Author: Ken Murchison <mu...@fastmail.com>
+Origin: upstream, https://github.com/cyrusimap/cyrus-imapd/commits/00d0646e
+Forwarded: not-needed
+Applied-Upstream: 3.6.6
+Reviewed-By: Yadd <y...@debian.org>
+Last-Update: 2024-07-29
+
+--- a/imap/sync_support.c
++++ b/imap/sync_support.c
+@@ -3438,7 +3438,6 @@
+     snprintf(name, sizeof(name), "%.*s", (int) (ext - fname), fname);
+     r = sievedb_lookup_name(db, name, &sdata, 0);
+     if (r == CYRUSDB_NOTFOUND) {
+-        buf_init_ro(&buf, content, len);
+         sdata->name = name;
+     }
+     else if (r) {
+@@ -3446,6 +3445,7 @@
+         goto done;
+     }
+ 
++    buf_init_ro(&buf, content, len);
+     r = sieve_script_store(mailbox, sdata, &buf);
+ 
+   done:
diff --git a/debian/patches/series b/debian/patches/series
index a2789c66..7cc24b60 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,6 @@
 0020_fix-cyr_cd-shebang.patch
 fix-upgrade-versions.patch
 CVE-2024-34055.patch
+CVE-2024-34055-regressions-1.patch
+CVE-2024-34055-regressions-2.patch
+CVE-2024-34055-regressions-3.patch

Reply via email to