Skip to content

Backport debian-security fixes from bookworm-security (2.3.19.1) to our unstable backport fork (2.3.21)#10

Open
j4n wants to merge 16 commits into
masterfrom
j4n/backport-security-patches
Open

Backport debian-security fixes from bookworm-security (2.3.19.1) to our unstable backport fork (2.3.21)#10
j4n wants to merge 16 commits into
masterfrom
j4n/backport-security-patches

Conversation

@j4n

@j4n j4n commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Backport 14 debian-security fixes from bookworm-security (2.3.19.1 base, deb12u1-u6, tip b0beae072) onto our 2.3.21 rebuild, which shared no history with the backport work and previously carried none of them.. All 26 patch files apply to 2.3.21 with offsets only, no fuzz and no rejects; grouped commits by CVE.
The first commit carries a change with the release builds: keep the debian/changelog at an UNRELEASED tip and do build-time 'stamping' of the release distro.

@j4n
j4n changed the base branch from master to j4n/unified-buildd July 21, 2026 15:06
@j4n
j4n force-pushed the j4n/backport-security-patches branch from ece6585 to 8aa5dbe Compare July 21, 2026 15:22
@j4n
j4n force-pushed the j4n/unified-buildd branch from 0ce9ea7 to 39943e9 Compare July 22, 2026 15:04
j4n added 16 commits July 22, 2026 17:50
We build the same source for two stable releases (bookworm/Debian 12 and
trixie/Debian 13), but both  derived the same package version string from
debian/changelog. Downstream that collision was worked around by separate
upload directories (download.delta.chat/dovecot/<distro>/) and a manual
`_${distro}` suffix rename for the GitHub release.

Fix it right: make each stable 'stamp' its own version.

- debian/changelog: make the current/next entry (1:2.3.21+dfsg1-3+chatmail2)
  UNRELEASED with a neutral base version only. This lets dch amend the entry in
  place at build time. Previously, we used 'unstable', which was never correct
  for our builds and inherited from the original sid backport.

- .github/workflows/pipeline.yml: after checkout, before the build, add a
  "finalize changelog" step that maps inputs.distro to a Debian-security-style
  suffix (bookworm -> +deb12u1, trixie -> +deb13u1) and runs `dch -v
  <base>+<suffix> --distribution <codename> --force-distribution` which
  rewrites the version in place. Explicity pull in 'devscripts' is added to the
  tools install.

- .github/workflows/pipeline.yml: delete _distro suffix rename hack and
  derive base version for combined GitHub release; upload both source
  variants (changelog differs per-distro).
Backport from Debian bookworm-security (deb12u1). Bounded recursion /
allocation in the RFC822 address and MIME header parsers
(lib-mail/message-address, message-header-parser, lib-imap/imap-envelope,
lib-storage index-search-mime) that a crafted message could drive into
excessive CPU/memory use. Squashed upstream series, applies clean onto
our 2.3.21 tree (byte-identical to upstream).
Backport from Debian bookworm-security (deb12u1). Limits on header count
and size in lib-mail/message-header-parser and message-parser to stop a
crafted message with a huge number of headers from exhausting CPU/memory.
Applies clean onto our 2.3.21 tree (byte-identical to upstream).
Backport from Debian bookworm-security (deb12u2). Upstream removed the
example FTS attachment-decoder script src/plugins/fts/decode2text.sh: it
shells out with insufficiently sanitized input and is not fit for
production, upstream recommends writing your own or using Apache Tika.
The patch (written against 2.3.21+dfsg1.orig, applies cleanly) drops the
script and its Makefile.am install lines.

Folded companion packaging edits so our build still works once the file is
gone (both would otherwise reference a missing path):
- debian/rules: drop the `rm .../usr/lib/dovecot/decode2text.sh` line in
  override_dh_auto_install (make install no longer ships it).
- debian/dovecot-core.examples: deleted (its sole entry was the script).

The script was only shipped as doc example, never under /usr/lib/dovecot, we
mirror Debian's full removal.
Backport from Debian bookworm-security (deb12u2). A crash in
pigeonhole managesieve-login when a command did not finish on the initial
line (NULL-deref / assert reachable pre-auth). Applies cleanly onto 2.3.21.
Backport from Debian bookworm-security (deb12u2, with the deb12u4
regression correction folded in). auth db-passwd-file could be tricked via
unnormalized %-variable paths; -1 adds db_passwd_fix_path(), -2 normalizes
the path with it (the -2 commit is Debian's passwd-file regression fix from
u4, so copying the deb12u6 versions carries the corrected behavior). Both
apply cleanly onto 2.3.21.
Backport from Debian bookworm-security (deb12u2). The doveadm HTTP/TCP
client-connection compared the API key / credentials with a non-constant
-time compare, leaking key material via a timing side channel; -1 switches
to a timing-safe compare, -2 moves the temporary base64 value to the
datastack, -3 fetches the API key from the correct source. Apply cleanly
onto 2.3.21.
…sponse

Backport from Debian bookworm-security (deb12u2). pigeonhole
managesieve-login did not properly verify the AUTHENTICATE initial
response, allowing a malformed pre-auth SASL initial response to be
mishandled. Applies cleanly onto 2.3.21.
Backport from Debian bookworm-security (deb12u2). lib-mail rfc2231-parser
did not bound the number of RFC2231 continuation parameters, letting a
crafted MIME header drive excessive work (DoS). Adds a parameter-count
limit. Applies cleanly onto 2.3.21.
Backport from Debian bookworm-security (deb12u6). pigeonhole lib-sieve did
not enforce the CPU time limit inside the :contains and :matches match
types, so a crafted Sieve script / message could burn unbounded CPU (DoS).
Applies cleanly onto 2.3.21.
Backport from Debian bookworm-security (deb12u6). imap-acl / acl plugins
did not validate ACL identifiers: -1 adds acl_id_is_valid(), -2 makes
imap-acl fail on an invalid identifier, -3 asserts before writing an
invalid identifier to the vfile backend (prevents ACL corruption /
mis-scoped rights). Apply cleanly onto 2.3.21.
Backport Debian's four-part fix for CVE-2026-27855 from
upstream/stable/bookworm-security (deb12u2 base, deb12u5-corrected,
copied from the deb12u6 tip). Applies to our 2.3.21 tree with line
offsets only.

The security-relevant defect (patch -1) is that auth_cache_remove() expanded
the passdb cache key from the raw, untranslated request->fields.user instead of
the post-userdb-translation request->fields.translated_username. Every other
cache-key expansion in auth-cache.c (lookup, insert) already uses
translated_username, so a credentials update could compute a key that does not
match the entry that lookups use. The stale/mismatched entry is left behind,
letting a subsequent auth reuse cached data keyed under the wrong
(pre-translation) identity. Aligning the removal path with the lookup/insert
paths closes that inconsistency.

The remaining three parts are the supporting refactor and hardening
Debian shipped in the same CVE set:
  -2 extracts auth_request_passdb_event_(begin|end) out of
     auth_request_passdb_lookup_(begin|end) so the passdb event/settings
     lifecycle can be driven around any passdb call, not just lookups
     (src/auth/auth-request.c, .h).
  -3 wraps the credentials-update path with that begin/end pair, in both
     auth_request_set_credentials() and the auth worker's setcred handler,
     so update_query runs with the correct per-passdb event + settings
     context (src/auth/auth-request.c, src/auth/auth-worker-client.c).
     Note Debian's diffstat names auth-worker-server.c but the hunk
     targets auth-worker-client.c; both files exist in 2.3.21 and the
     hunk lands on the correct one.
  -4 rejects an empty update_query with an explicit error instead of
     issuing a malformed SQL credentials update (src/auth/passdb-sql.c).
Backport Debian's CVE-2026-33603 fix (deb12u6) from bookworm-security. Applies
to our 2.3.21 tree with a line offset only.

Defect: client_auth_respond() forwarded the client's SASL continuation
response verbatim to auth_client_request_continue(), which hands it to
the auth server over the tab-delimited auth protocol. The response is
attacker-controlled and arrives pre-authentication. A response
containing a TAB (or other non-base64 byte) is not valid SASL base64 but
was passed through unchecked, letting the client inject extra fields into
the auth-protocol request line. The fix validates every byte against
base64_is_valid_char() (plus '=') before forwarding and fails the auth
attempt on the first invalid character, so only well-formed base64 ever
reaches the auth server.
Backport Debian's five-part CVE-2026-27857 fix (deb12u2 base,
deb12u5-corrected, copied from the deb12u6 tip) from bookworm-security. Applies
to our 2.3.21 tree with no fuzz and no rejects; our imap_parser_create()
call-site set is identical to Debian's.

Defect: the pre-authentication IMAP parser imposed no limit on the depth of
parenthesised lists. Each '(' opens a new list arg allocated from the
parser pool, so a client could send a command with a huge run of '('
and drive the imap-login process's memory usage up without ever
completing a line, a pre-auth memory-exhaustion DoS.

The fix threads an optional parameters struct into the parser and lets a
caller cap the open-list count:
  -1 adjusts the pigeonhole imap-filter-sieve call site for the new
     imap_parser_create() arity (pass NULL)
  -2 adds the trailing `const struct imap_parser_params *params`
     argument to imap_parser_create() and passes NULL at every existing
     call site. params is unused in this step.
  -3 gives imap_parser_params a list_count_limit field and enforces it
     in the parser: exceeding the limit fails the line with an error,
     adds a unit test.
  -4 sets list_count_limit = IMAP_LOGIN_LIST_COUNT_LIMIT (1) for the two
     imap-login parsers and the pre-login ID-command parser, since
     pre-login only ever uses a list in the ID command.
  -5 makes the on-stack params const (u5 correction).

The list-limit test relies on test_assert_strcmp_idx / test_assert_cmp
(src/lib-test/test-common.h) and istream-chain (src/lib/istream-chain.h),
both present in 2.3.21, so it builds. Note CVE-2026-42006 (next commit)
corrects a counting bug in the -3 enforcement.
Backport Debian's CVE-2026-42006 fix (deb12u6) from bookworm-security. Applies
to our 2.3.21 tree with no fuzz and no rejects. Must layer on top of
CVE-2026-27857 (previous commit), which introduced the code this corrects.

Defect: the nesting limit added in CVE-2026-27857-3 was placed in
imap_parser_close_list(), i.e. it counted and capped the ')' that close
lists rather than the '(' that open (and allocate) them. Because the
allocation happens on open, an attacker could still send an unbounded
run of '(' without any ')' and exhaust imap-login memory pre-auth; the
original limit never engaged on the byte that actually grows the pool.

The fix moves the counter+limit check into imap_parser_open_list(),
makes that function return bool, and fails the parse at the offending
'(' from imap_parser_read_arg(). The unit test is extended to assert the exact
error string across the missing-')', unexpected-')', too-many-'(' and
pending-literal cases.
Bring debian/tests up to the version Debian ships alongside the security
fixes. Our tests were an older fork of Debian's own (the run-parts
debian/tests/usage layout came from Debian via merge 7c68cb0), so this
is convergence, not divergence, and it lands the regression coverage the
CVE work added.

Changes:
  * debian/changelog: add lists of patches
  * debian/tests/control: now byte-identical to bookworm-security. The
    usage (run-parts) stanza gains dovecot-managesieved and sieve-connect
    in Depends (both satisfiable: we build dovecot-managesieved per
    debian/control, and sieve-connect is in bookworm and trixie main). A
    new debian_bug_1134464 stanza is added (Depends: dovecot-imapd;
    Restrictions: needs-root, breaks-testbed, allow-stderr).
  * debian/tests/usage/00_setup: enable cram-md5 alongside plain in
    auth_mechanisms. The static passdb already stores the password as
    plaintext (password=test), which CRAM-MD5 can use, so the new
    imap-cram-md5 test authenticates without further setup.
  * debian/tests/usage/imap-cram-md5 (new): STARTTLS + CRAM-MD5 login,
    then fetch and verify the seeded DEP-8 message.
  * debian/tests/usage/sieve (new): authenticate to managesieved on 4190
    via sieve-connect and LIST scripts.
  * debian/tests/debian_bug_1134464 (new): self-contained passwd-file +
    LDA delivery test that guards the CVE-2026-0394 passwd-file path
    regression (Debian bug 1134464). Writes its own local.conf, so it
    does not depend on the usage/ setup.
@j4n
j4n force-pushed the j4n/backport-security-patches branch from 8aa5dbe to 333a985 Compare July 22, 2026 15:50
@j4n
j4n changed the base branch from j4n/unified-buildd to master July 22, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant