Package: release.debian.org
Control: affects -1 + src:curl
X-Debbugs-Cc: [email protected]
User: [email protected]
Usertags: pu
Tags: bookworm
Severity: normal
[ Reason ]
This update fixes 7 CVEs in curl that were published upstream after the
last bookworm point release. All are upstream-derived patches; each one
needed adaptation against 7.88.1 because the affected code paths have
moved or been refactored in the years since. The unmodified upstream
patches were imported first and then a follow-up commit per CVE
backports them onto 7.88.1; the commit history reflects this with one
commit per CVE so each fix is reviewable in isolation.
CVEs fixed:
- CVE-2025-10148 ws: get a new mask for each new outgoing frame
- CVE-2025-14524 curl_sasl: if redirected, require permission to use bearer
- CVE-2025-14819 openssl: toggling CURLSSLOPT_NO_PARTIALCHAIN makes a
different CA cache
- CVE-2026-3783 http: only send bearer if auth is allowed
- CVE-2026-3784 proxy-auth: additional tests / proxy info match
- CVE-2026-5773 protocol: disable connection reuse for SMB(S)
- CVE-2026-7168 setopt: clear proxy auth properties when switching
A further set of CVEs (CVE-2025-13034, CVE-2026-3805, CVE-2026-1965,
CVE-2026-4873, CVE-2026-5545, CVE-2026-6253, CVE-2026-6276,
CVE-2026-6429) were considered but deliberately not backported to
bookworm; see the [Risks] section.
[ Impact ]
Without this update, bookworm users are exposed to the seven listed
CVEs in curl: a websocket masking weakness (mask reused across frames),
two bearer/credentials handling bugs on redirect, a TLS cache-key
collision when CURLSSLOPT_NO_PARTIALCHAIN toggles, a proxy-auth
identity mix-up across socks proxies, an SMB connection-reuse flaw,
and a digest proxy-auth replay across CURLOPT_PROXY changes.
[ Tests ]
The full upstream curl test suite is run as part of the package build.
With the updated patches, all three crypto-backend test passes (one per
backend variant the package builds) report 100% pass:
TESTDONE: 1403 tests out of 1403 reported OK: 100%
TESTDONE: 1401 tests out of 1401 reported OK: 100%
TESTDONE: 1397 tests out of 1397 reported OK: 100%
The added CVE patches do not include the upstream regression tests
themselves; see [Changes] / [Risks] for why.
[ Risks ]
The seven backported patches are upstream-authored, security-focused,
and all the modified files are well covered by curl's own test suite
(which still passes 100%). The adaptations to 7.88.1 are documented
per-patch with two Backported-by trailers (the trixie chain plus a
bookworm-specific one) and fall into a few categories:
- line-number / context refresh only (CVE-2025-14524, CVE-2026-3783,
CVE-2026-5773)
- apply the same logic in a slightly different surrounding shape
because upstream refactored helper functions or renamed structs
(CVE-2025-10148: bookworm's ws_packethead() vs upstream's
ws_enc_add_frame(); CVE-2025-14819: cached_x509_store_* /
multi_ssl_backend_data vs ossl_cached_x509_store_* /
ossl_x509_share, plus a (struct Curl_easy *)data cast in place
of CURL_UNCONST which does not exist here; CVE-2026-7168:
setproxy() added before Curl_vsetopt() since bookworm's setopt
is one big switch rather than a sub-switch, and the no-op
Curl_auth_digest_cleanup(x) macro added under
CURL_DISABLE_CRYPTO_AUTH which is the pre-split spelling)
- upstream switched to a newer alias (CVE-2026-3784:
strcasecompare() retained instead of upstream's curl_strequal())
- upstream's regression tests dropped because the necessary test
infrastructure does not exist in bookworm: CVE-2026-3783 needs
tests/data/test486 (which trixie's test2006 was copy-derived
from) -- bookworm has no test486; CVE-2026-3784 needs the
tests/http/ pytest framework which arrived in upstream after
7.88.1; CVE-2026-7168 needs the modern libtest harness
(test.h / CURLcode test(char *URL)) the trixie adaptation
rewrote against. In every case the security property is the
library code change itself, not the test.
CVEs deliberately skipped:
- CVE-2025-13034: not relevant to this branch (the affected gnutls
QUIC path in lib/vquic/vquic-tls.c does not exist in 7.88.1).
- CVE-2026-3805: SMB request struct fix; the bookworm SMB code
path differs enough that backporting is not worth the regression
risk for SMB users on stable.
- CVE-2026-1965, CVE-2026-4873, CVE-2026-5545: all three refactor
8.14.1's per-aspect url_match_* helper structure in lib/url.c.
None of those helpers exist in 7.88.1 -- it has one monolithic
ConnectionExists() function. Backporting would require writing
the equivalent of ~80 lines of Negotiate-aware /
starttls-aware / negotiate-state-aware matching logic inline
against a security-sensitive code path that gets exercised for
every reused connection. Considered too aggressive for a stable
point release.
- CVE-2026-6253, CVE-2026-6276, CVE-2026-6429: depend on helpers
or struct shapes that do not exist in 7.88.1
(Curl_reset_userpwd, Curl_reset_proxypwd, Curl_url_same_origin,
cookiehost-on-SingleRequest). Inlining the equivalent logic in
Curl_http_follow() would touch the redirect path
significantly; same regression-risk reasoning as above.
[ 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 ]
* For each of the seven CVEs, the upstream patch is imported as a
single commit (or, for the six already adapted on trixie,
cherry-picked from the trixie branch with `git cherry-pick -x`),
then re-exported via gbp pq with the bookworm-specific source
tweaks. Each patch carries the original upstream
From: / Date: / Subject: / commit body, the trixie Backported-by
trailer (where applicable), and a new bookworm-specific
Backported-by trailer that bullet-points the bookworm-only
changes (line offsets, function/struct renames, helper-macro
spellings, dropped test additions).
* d/patches/series: the seven new CVE-XXXX-YYYY.patch entries are
appended under a new "# Patches from 8.16.0." section heading,
keeping the existing per-curl-version comment grouping.
[ Other info ]
The build and the full test suite were run with sbuild on amd64. The
package builds clean and all three crypto-backend test passes report
100% (1403/1401/1397 tests).
I'm still yet to do another round of thorough review of all backporting
changes but I wanted to submit this request so that it can be viewed in time
for the next point release, as I understand the cutoff is this Saturday (May
9th). curl/libcurl is widely used and it's important to get these fixes out
on this one rather than in 2 months.
The backporting changes for bookworm are bigger than the p-u for trixie so I
want to pay extra attention to this one.
I will conclude the review before Sunday and reply to this bug if there are
any changes. Until then, the commits are in my fork at
https://salsa.debian.org/samueloph/curl.
Thank you!
--
Samuel Henrique <samueloph>
diff -Nru curl-7.88.1/debian/changelog curl-7.88.1/debian/changelog
--- curl-7.88.1/debian/changelog 2025-07-19 12:04:59.000000000 -0700
+++ curl-7.88.1/debian/changelog 2026-05-08 07:16:21.000000000 -0700
@@ -1,3 +1,16 @@
+curl (7.88.1-10+deb12u15) bookworm; urgency=medium
+
+ * Fix 7 CVEs:
+ - CVE-2025-10148
+ - CVE-2025-14524
+ - CVE-2025-14819
+ - CVE-2026-3783
+ - CVE-2026-3784
+ - CVE-2026-5773
+ - CVE-2026-7168
+
+ -- Samuel Henrique <[email protected]> Fri, 08 May 2026 07:16:21 -0700
+
curl (7.88.1-10+deb12u14) bookworm; urgency=medium
* d/p/0001-http_chunks-reset...: New patch to fix memory leak:
diff -Nru curl-7.88.1/debian/patches/CVE-2025-10148.patch
curl-7.88.1/debian/patches/CVE-2025-10148.patch
--- curl-7.88.1/debian/patches/CVE-2025-10148.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2025-10148.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,76 @@
+From 84db7a9eae8468c0445b15aa806fa7fa806fa0f2 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Mon, 8 Sep 2025 14:14:15 +0200
+Subject: [PATCH] ws: get a new mask for each new outgoing frame
+
+Reported-by: Calvin Ruocco
+Closes #18496
+
+Backported by: Samuel Henrique <[email protected]>
+
+Changes:
+* Apply the per-frame mask generation in ws_packethead() (bookworm
+ 7.88.1) rather than upstream's ws_enc_add_frame() (and trixie's
+ ws_enc_write_head()), since the bookworm code path that builds the
+ outgoing frame header is structurally different. On Curl_rand()
+ failure return 0 -- ws_packethead() already uses 0 as the
+ soft-error sentinel for buffer-too-small.
+* Preserve the DEBUGBUILD CURL_WS_FORCE_ZERO_MASK escape hatch
+ alongside the new per-frame mask generation, matching upstream.
+* Remove the corresponding one-time mask generation in
+ Curl_ws_accept(), and initialise `result` to CURLE_OK at
+ declaration since it is no longer unconditionally assigned by the
+ removed Curl_rand() call.
+---
+ lib/ws.c | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/lib/ws.c b/lib/ws.c
+index 0fc5e56..992357c 100644
+--- a/lib/ws.c
++++ b/lib/ws.c
+@@ -127,7 +127,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data,
+ struct connectdata *conn = data->conn;
+ struct websocket *wsp = &data->req.p.http->ws;
+ struct ws_conn *wsc = &conn->proto.ws;
+- CURLcode result;
++ CURLcode result = CURLE_OK;
+
+ /* Verify the Sec-WebSocket-Accept response.
+
+@@ -148,13 +148,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data,
+ subprotocol not requested by the client), the client MUST Fail
+ the WebSocket Connection. */
+
+- /* 4 bytes random */
+- result = Curl_rand(data, (unsigned char *)&ws->ws.mask,
sizeof(ws->ws.mask));
+- if(result)
+- return result;
+-
+- infof(data, "Received 101, switch to WebSocket; mask %02x%02x%02x%02x",
+- ws->ws.mask[0], ws->ws.mask[1], ws->ws.mask[2], ws->ws.mask[3]);
++ infof(data, "Received 101, switch to WebSocket");
+ Curl_dyn_init(&wsc->early, data->set.buffer_size);
+ if(nread) {
+ result = Curl_dyn_addn(&wsc->early, mem, nread);
+@@ -628,6 +622,20 @@ static size_t ws_packethead(struct Curl_easy *data,
+ firstbyte);
+ infof(data, "WS: send payload len %u", (int)len);
+
++ /* 4 bytes random */
++ {
++ CURLcode result = Curl_rand(data, (unsigned char *)&ws->ws.mask,
++ sizeof(ws->ws.mask));
++ if(result)
++ return 0;
++ }
++
++#ifdef DEBUGBUILD
++ if(getenv("CURL_WS_FORCE_ZERO_MASK"))
++ /* force the bit mask to 0x00000000, effectively disabling masking */
++ memset(&ws->ws.mask, 0, sizeof(ws->ws.mask));
++#endif
++
+ /* 4 bytes mask */
+ memcpy(&out[outi], &ws->ws.mask, 4);
+
diff -Nru curl-7.88.1/debian/patches/CVE-2025-14524.patch
curl-7.88.1/debian/patches/CVE-2025-14524.patch
--- curl-7.88.1/debian/patches/CVE-2025-14524.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2025-14524.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,49 @@
+From: Daniel Stenberg <[email protected]>
+Date: Wed, 10 Dec 2025 11:40:47 +0100
+Subject: [PATCH] curl_sasl: if redirected, require permission to use bearer
+
+Closes #19933
+
+Backported-by: Samuel Henrique <[email protected]>
+ * Refresh patch context for lib/curl_sasl.c: upstream gates the bearer
+ token in the sasl_choose_oauth() and sasl_choose_oauth2() helpers,
+ neither of which exists in 8.14.1. Apply the same
+ "!this_is_a_follow || allow_auth_to_other_hosts" guard inline at the
+ `oauth_bearer` initialisation in Curl_sasl_start() and
+ Curl_sasl_continue() instead.
+
+Backported by: Samuel Henrique <[email protected]>
+ * Refresh line numbers for bookworm 7.88.1: same functions
+ (Curl_sasl_start and Curl_sasl_continue), -7 line offset.
+---
+ lib/curl_sasl.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
+index 119fb9b..2dd6b00 100644
+--- a/lib/curl_sasl.c
++++ b/lib/curl_sasl.c
+@@ -349,7 +349,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct
Curl_easy *data,
+ data->set.str[STRING_SERVICE_NAME] :
+ sasl->params->service;
+ #endif
+- const char *oauth_bearer = data->set.str[STRING_BEARER];
++ const char *oauth_bearer =
++ (!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
++ data->set.str[STRING_BEARER] : NULL;
++
+ struct bufref nullmsg;
+
+ Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
+@@ -536,7 +539,10 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct
Curl_easy *data,
+ data->set.str[STRING_SERVICE_NAME] :
+ sasl->params->service;
+ #endif
+- const char *oauth_bearer = data->set.str[STRING_BEARER];
++ const char *oauth_bearer =
++ (!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
++ data->set.str[STRING_BEARER] : NULL;
++
+ struct bufref serverdata;
+
+ Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
diff -Nru curl-7.88.1/debian/patches/CVE-2025-14819.patch
curl-7.88.1/debian/patches/CVE-2025-14819.patch
--- curl-7.88.1/debian/patches/CVE-2025-14819.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2025-14819.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,80 @@
+From cd046f6c93b39d673a58c18648d8906e954c4f5d Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Wed, 17 Dec 2025 10:54:16 +0100
+Subject: [PATCH] openssl: toggling CURLSSLOPT_NO_PARTIALCHAIN makes a
+ different CA cache
+
+Reported-by: Stanislav Fort
+
+Closes #20009
+
+Backported-by: Samuel Henrique <[email protected]>
+ * Refresh patch context for lib/vtls/openssl.c: line numbers shift, and
+ one upstream context line ("BIT(store_is_empty);") does not exist in
+ 8.14.1's struct ossl_x509_share, so it is dropped from the hunk.
+ Functionally identical.
+
+Backported by: Samuel Henrique <[email protected]>
+ * Bookworm 7.88.1 names the cache struct `multi_ssl_backend_data`
+ (vs `ossl_x509_share` in 8.14.1+) and the helpers `cached_x509_store_*`
+ (without the `ossl_` prefix). Apply the same logic against those names.
+ Replace the upstream `CURL_UNCONST(data)` macro with a plain
+ `(struct Curl_easy *)data` cast since CURL_UNCONST does not exist in
+ bookworm.
+---
+ lib/vtls/openssl.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
+index 6557783..1f2579e 100644
+--- a/lib/vtls/openssl.c
++++ b/lib/vtls/openssl.c
+@@ -302,6 +302,7 @@ struct multi_ssl_backend_data {
+ char *CAfile; /* CAfile path used to generate X509 store */
+ X509_STORE *store; /* cached X509 store or NULL if none */
+ struct curltime time; /* when the cached store was created */
++ BIT(no_partialchain); /* keep partial chain state */
+ };
+ #endif /* HAVE_SSL_X509_STORE_SHARE */
+
+@@ -3339,9 +3340,14 @@ static bool cached_x509_store_expired(const struct
Curl_easy *data,
+
+ static bool cached_x509_store_different(
+ struct Curl_cfilter *cf,
++ const struct Curl_easy *data,
+ const struct multi_ssl_backend_data *mb)
+ {
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
++ struct ssl_config_data *ssl_config =
++ Curl_ssl_cf_get_config(cf, (struct Curl_easy *)data);
++ if(mb->no_partialchain != ssl_config->no_partialchain)
++ return true;
+ if(!mb->CAfile || !conn_config->CAfile)
+ return mb->CAfile != conn_config->CAfile;
+
+@@ -3358,7 +3364,7 @@ static X509_STORE *get_cached_x509_store(struct
Curl_cfilter *cf,
+ multi->ssl_backend_data &&
+ multi->ssl_backend_data->store &&
+ !cached_x509_store_expired(data, multi->ssl_backend_data) &&
+- !cached_x509_store_different(cf, multi->ssl_backend_data)) {
++ !cached_x509_store_different(cf, data, multi->ssl_backend_data)) {
+ store = multi->ssl_backend_data->store;
+ }
+
+@@ -3386,6 +3392,8 @@ static void set_cached_x509_store(struct Curl_cfilter
*cf,
+
+ if(X509_STORE_up_ref(store)) {
+ char *CAfile = NULL;
++ struct ssl_config_data *ssl_config =
++ Curl_ssl_cf_get_config(cf, (struct Curl_easy *)data);
+
+ if(conn_config->CAfile) {
+ CAfile = strdup(conn_config->CAfile);
+@@ -3403,6 +3411,7 @@ static void set_cached_x509_store(struct Curl_cfilter
*cf,
+ mbackend->time = Curl_now();
+ mbackend->store = store;
+ mbackend->CAfile = CAfile;
++ mbackend->no_partialchain = ssl_config->no_partialchain;
+ }
+ }
+
diff -Nru curl-7.88.1/debian/patches/CVE-2026-3783.patch
curl-7.88.1/debian/patches/CVE-2026-3783.patch
--- curl-7.88.1/debian/patches/CVE-2026-3783.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2026-3783.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,49 @@
+From e3d7401a32a46516c9e5ee877e613e62ed35bddc Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Fri, 6 Mar 2026 23:13:07 +0100
+Subject: [PATCH] http: only send bearer if auth is allowed
+
+Verify with test 2006
+
+Closes #20843
+
+Backported-by: Samuel Henrique <[email protected]>
+ * Refresh patch context for lib/http.c: upstream's one-line addition
+ in output_auth_headers() (a Curl_auth_allowed_to_host() check next
+ to the bearer block) sits in a slightly different surrounding
+ shape; rewrite the small if(...) with the same
+ Curl_auth_allowed_to_host() guard against the 8.14.1 layout.
+ * Adapt the new tests/data/test2006: reuse the existing test486 as
+ the base (similarity-copy in the diff), keep the test definition
+ structurally as upstream wants but also drop the two now-stale
+ "#" comment lines that already differ between upstream's and our
+ test486.
+
+Backported by: Samuel Henrique <[email protected]>
+ * Bookworm 7.88.1: same output_auth_headers() function, just at
+ line 793 (offset +97 vs trixie). Apply only the lib/http.c hunk.
+ * Drop the test additions: bookworm has neither tests/data/test486
+ (which trixie's test2006 was copy-derived from) nor a way to add
+ it without pulling in a non-trivial amount of unrelated test
+ infrastructure. The security property is the
+ Curl_auth_allowed_to_host() guard itself; tests are nice-to-have.
+---
+ lib/http.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/lib/http.c b/lib/http.c
+index 3829d72..cbed451 100644
+--- a/lib/http.c
++++ b/lib/http.c
+@@ -793,8 +793,9 @@ output_auth_headers(struct Curl_easy *data,
+ }
+ if(authstatus->picked == CURLAUTH_BEARER) {
+ /* Bearer */
+- if((!proxy && data->set.str[STRING_BEARER] &&
+- !Curl_checkheaders(data, STRCONST("Authorization")))) {
++ if(!proxy && data->set.str[STRING_BEARER] &&
++ Curl_auth_allowed_to_host(data) &&
++ !Curl_checkheaders(data, STRCONST("Authorization"))) {
+ auth = "Bearer";
+ result = http_output_bearer(data);
+ if(result)
diff -Nru curl-7.88.1/debian/patches/CVE-2026-3784.patch
curl-7.88.1/debian/patches/CVE-2026-3784.patch
--- curl-7.88.1/debian/patches/CVE-2026-3784.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2026-3784.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,69 @@
+From 5f13a7645e565c5c1a06f3ef86e97afb856fb364 Mon Sep 17 00:00:00 2001
+From: Stefan Eissing <[email protected]>
+Date: Fri, 6 Mar 2026 14:54:09 +0100
+Subject: [PATCH] proxy-auth: additional tests
+
+Also eliminate the special handling for socks proxy match.
+
+Closes #20837
+
+Backported-by: Samuel Henrique <[email protected]>
+ * Refresh patch context for lib/url.c: line numbers shift (590 ->
+ 640, 923 -> 986). Replace upstream's strcasecompare() call with
+ curl_strequal() to match what 8.14.1 already uses on this code
+ path. Keep the static socks_proxy_info_matches() helper in place
+ (upstream removes it as a tidy-up) and only switch the call site
+ to proxy_info_matches() so the new user/passwd check actually
+ runs; this minimises the diff and keeps the security fix focused.
+ * tests/http/test_13_proxy_auth.py and tests/http/testenv/curl.py:
+ applied verbatim; these are pytest-based HTTP tests that are not
+ currently exercised in the Debian build, but kept for parity with
+ upstream and future use.
+
+Backported by: Samuel Henrique <[email protected]>
+ * Bookworm 7.88.1: same proxy_info_matches and
+ socks_proxy_info_matches functions, just at line 863. Bookworm's
+ proxy_info_matches still uses strcasecompare() (upstream switched
+ to curl_strequal() at some point post-7.88.1), so leave that
+ call alone -- only add the new Curl_timestrcmp() user/passwd
+ check inside it. Keep socks_proxy_info_matches() in place and
+ switch the call site at line 1214 from socks_proxy_info_matches
+ to proxy_info_matches, matching the trixie minimal-diff approach.
+ * Drop the tests/http/test_13_proxy_auth.py and
+ tests/http/testenv/curl.py hunks: bookworm has no tests/http/
+ pytest infrastructure at all (those tests appeared in upstream
+ later than 7.88.1).
+---
+ lib/url.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/lib/url.c b/lib/url.c
+index cf0ad07..5243373 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -865,9 +865,13 @@ proxy_info_matches(const struct proxy_info *data,
+ {
+ if((data->proxytype == needle->proxytype) &&
+ (data->port == needle->port) &&
+- strcasecompare(data->host.name, needle->host.name))
+- return TRUE;
++ strcasecompare(data->host.name, needle->host.name)) {
+
++ if(Curl_timestrcmp(data->user, needle->user) ||
++ Curl_timestrcmp(data->passwd, needle->passwd))
++ return FALSE;
++ return TRUE;
++ }
+ return FALSE;
+ }
+
+@@ -1208,8 +1212,7 @@ ConnectionExists(struct Curl_easy *data,
+ continue;
+
+ if(needle->bits.socksproxy &&
+- !socks_proxy_info_matches(&needle->socks_proxy,
+- &check->socks_proxy))
++ !proxy_info_matches(&needle->socks_proxy, &check->socks_proxy))
+ continue;
+ #endif
+ if(needle->bits.conn_to_host != check->bits.conn_to_host)
diff -Nru curl-7.88.1/debian/patches/CVE-2026-5773.patch
curl-7.88.1/debian/patches/CVE-2026-5773.patch
--- curl-7.88.1/debian/patches/CVE-2026-5773.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2026-5773.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,52 @@
+From 74a169575d6412dc0ff532acdf94de35a6c2a571 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Sun, 5 Apr 2026 18:23:35 +0200
+Subject: [PATCH] protocol: disable connection reuse for SMB(S)
+
+Connections should only be reused when using the same "share" (and
+perhaps some additional conditions), but instead of fixing this flaw,
+this change completely disables connection reuse for SMB. This protocol
+is about to get dropped soon anyway.
+
+Reported-by: Osama Hamad
+Closes #21238
+
+Backported-by: Samuel Henrique <[email protected]>
+ * Upstream removes PROTOPT_CONN_REUSE from the SMB and SMBS scheme
+ registrations in lib/protocol.c. That flag (and the lib/protocol.c
+ scheme registry itself) only exists from upstream commit
+ feea96851230c7a5a11feaffa0a5e4a4d30e5e63 ("conncontrol: reuse
+ handling", Nov 2025) onward, so neither is present in 8.14.1.
+ * In 8.14.1 SMB connection reuse is instead controlled at runtime
+ via connkeep() / connclose(), and lib/smb.c explicitly calls
+ connkeep() in smb_connect() to mark SMB connections as eligible
+ for reuse. Replace that connkeep() with a connclose() so SMB
+ connections are marked as not-reusable, achieving the same effect
+ as the upstream change.
+
+Backported by: Samuel Henrique <[email protected]>
+ * Bookworm 7.88.1: same connkeep() call in smb_connect() at line
+ 271. Apply the same connkeep() -> connclose() swap; this version
+ also lacks PROTOPT_CONN_REUSE so the runtime approach is the
+ only way to express "do not reuse this connection".
+---
+ lib/smb.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/lib/smb.c b/lib/smb.c
+index 097874b..24c319c 100644
+--- a/lib/smb.c
++++ b/lib/smb.c
+@@ -267,8 +267,10 @@ static CURLcode smb_connect(struct Curl_easy *data, bool
*done)
+ if(!smbc->recv_buf)
+ return CURLE_OUT_OF_MEMORY;
+
+- /* Multiple requests are allowed with this connection */
+- connkeep(conn, "SMB default");
++ /* SMB does not allow connection reuse: connections should only be reused
++ when using the same "share" (and possibly other conditions), but rather
++ than implementing that, mark every SMB connection as not reusable. */
++ connclose(conn, "SMB does not allow connection reuse");
+
+ /* Parse the username, domain, and password */
+ slash = strchr(conn->user, '/');
diff -Nru curl-7.88.1/debian/patches/CVE-2026-7168.patch
curl-7.88.1/debian/patches/CVE-2026-7168.patch
--- curl-7.88.1/debian/patches/CVE-2026-7168.patch 1969-12-31
16:00:00.000000000 -0800
+++ curl-7.88.1/debian/patches/CVE-2026-7168.patch 2026-05-08
07:16:21.000000000 -0700
@@ -0,0 +1,116 @@
+From c1cfdf59acbaf9504c4578d4cf56cdd7c8594507 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Mon, 27 Apr 2026 09:14:51 +0200
+Subject: [PATCH] setopt: clear proxy auth properties when switching
+
+Verify with test 1588
+
+Closes #21453
+
+Backported-by: Samuel Henrique <[email protected]>
+ * lib/setopt.c: upstream's CURLOPT_PROXY case lives in a dedicated
+ setopt_cptr_proxy() function; in 8.14.1 it is still inline in the
+ setopt_cptr() switch. The setproxy() helper is added directly
+ above setopt_cptr() and the inline Curl_setstropt() call is
+ swapped for setproxy().
+ * lib/vauth/vauth.h: upstream's hunk also adds a no-op
+ Curl_auth_is_digest_supported() macro to the CURL_DISABLE_DIGEST_AUTH
+ branch, but our 8.14.1 vauth.h has no such #else branch (the file
+ ends the digest block with a bare #endif). Add only the
+ Curl_auth_digest_cleanup(x) no-op macro inside a new #else, which
+ is the part actually needed by setproxy() in disable-digest builds.
+ * tests/data/test1588: regression test from upstream with two changes:
+ crlf="headers" -> crlf="yes" so the 8.14.1 test runner correctly
+ applies CRLF to header lines on both the server-side data and the
+ expected protocol block; and the "digest" entry in <features> is
+ dropped because the 8.14.1 curlinfo emits the feature toggle as
+ "digest-auth" rather than "digest", so the unmodified feature gate
+ would always SKIP the test on this branch. Other digest-auth tests
+ (e.g. test1061) similarly do not list "digest" as a required
+ feature.
+ * tests/libtest/lib1588.c: rewritten to use the 8.14.1 libtest
+ harness (test.h / CURLcode test(char *URL) / easy_init / easy_setopt
+ with goto test_cleanup) instead of upstream's newer first.h-based
+ one. The init1588() helper also reuses the parent's test_cleanup
+ label rather than upstream's separate init_failed label, since
+ 8.14.1's easy_setopt jumps directly to test_cleanup.
+
+Backported by: Samuel Henrique <[email protected]>
+ * Bookworm 7.88.1: lib/setopt.c is a single Curl_vsetopt() function
+ with one big switch (no setopt_cptr() sub-switch like trixie).
+ Add the setproxy() helper just above Curl_vsetopt() instead, and
+ replace the inline Curl_setstropt() in the CURLOPT_PROXY case
+ with `result = setproxy(data, va_arg(param, char *));`.
+ * lib/vauth/vauth.h: bookworm uses CURL_DISABLE_CRYPTO_AUTH (the
+ pre-split spelling) instead of CURL_DISABLE_DIGEST_AUTH. Add the
+ no-op Curl_auth_digest_cleanup(x) macro under the matching
+ #else branch.
+ * Drop the test additions: bookworm has neither the test1588
+ xml-test infrastructure for CONNECT-based digest replay nor the
+ modern libtest harness (test.h / CURLcode test(char *URL)) the
+ trixie adaptation rewrote against -- backporting the test would
+ require touching the test runner setup more aggressively than is
+ appropriate for a stable update. The security property (proxy
+ auth state cleared on CURLOPT_PROXY change) is the setproxy()
+ helper itself.
+---
+ lib/setopt.c | 18 ++++++++++++++++--
+ lib/vauth/vauth.h | 2 ++
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/lib/setopt.c b/lib/setopt.c
+index 8862e0c..4a40a09 100644
+--- a/lib/setopt.c
++++ b/lib/setopt.c
+@@ -50,6 +50,7 @@
+ #include "multiif.h"
+ #include "altsvc.h"
+ #include "hsts.h"
++#include "vauth/vauth.h"
+
+ /* The last 3 #include files should be in this order */
+ #include "curl_printf.h"
+@@ -186,6 +187,20 @@ static CURLcode protocol2num(const char *str, curl_prot_t
*val)
+ return CURLE_OK;
+ }
+
++#ifndef CURL_DISABLE_PROXY
++static CURLcode setproxy(struct Curl_easy *data, const char *proxy)
++{
++ if((data->set.str[STRING_PROXY] && proxy) &&
++ /* there was one set, is this a new one? */
++ !strcmp(data->set.str[STRING_PROXY], proxy))
++ return CURLE_OK; /* same one as before */
++
++ Curl_auth_digest_cleanup(&data->state.proxydigest);
++ memset(&data->state.authproxy, 0, sizeof(data->state.authproxy));
++ return Curl_setstropt(&data->set.str[STRING_PROXY], proxy);
++}
++#endif
++
+ /*
+ * Do not make Curl_vsetopt() static: it is called from
+ * packages/OS400/ccsidcurl.c.
+@@ -1140,8 +1155,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption
option, va_list param)
+ * Setting it to NULL, means no proxy but allows the environment variables
+ * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
+ */
+- result = Curl_setstropt(&data->set.str[STRING_PROXY],
+- va_arg(param, char *));
++ result = setproxy(data, va_arg(param, char *));
+ break;
+
+ case CURLOPT_PRE_PROXY:
+diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h
+index e17d7aa..8c09764 100644
+--- a/lib/vauth/vauth.h
++++ b/lib/vauth/vauth.h
+@@ -119,6 +119,8 @@ CURLcode Curl_auth_create_digest_http_message(struct
Curl_easy *data,
+
+ /* This is used to clean up the digest specific data */
+ void Curl_auth_digest_cleanup(struct digestdata *digest);
++#else
++#define Curl_auth_digest_cleanup(x)
+ #endif /* !CURL_DISABLE_CRYPTO_AUTH */
+
+ #ifdef USE_GSASL
diff -Nru curl-7.88.1/debian/patches/series curl-7.88.1/debian/patches/series
--- curl-7.88.1/debian/patches/series 2025-07-19 12:04:59.000000000 -0700
+++ curl-7.88.1/debian/patches/series 2026-05-08 07:16:21.000000000 -0700
@@ -62,6 +62,15 @@
# Patches from 8.12.0.
CVE-2025-0167.patch
+# Patches from 8.16.0.
+CVE-2025-10148.patch
+CVE-2025-14524.patch
+CVE-2025-14819.patch
+CVE-2026-3783.patch
+CVE-2026-3784.patch
+CVE-2026-5773.patch
+CVE-2026-7168.patch
+
# Fix test issues with port clashes, now each build has a different random
seed.
runtests.pl-Increase-variance-of-random-seed-used-for-tes.patch