--- Begin Message ---
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
--- End Message ---