* [OE-core][wrynose][PATCH 0/8] curl: Security fixes
@ 2026-08-05 8:30 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-08-05 8:30 ` [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 UTC (permalink / raw)
To: openembedded-core
From: Deepak Rathore <deeratho@cisco.com>
This series addresses multiple curl security vulnerabilities affecting
the curl 8.19.0 version provided by the Wrynose branch.
Five changes backport upstream security fixes:
- CVE-2026-8286: Include TLS configuration when matching connections
that may be upgraded using STARTTLS.
- CVE-2026-8927: Clear Digest authentication state when an
environment-configured proxy changes.
- CVE-2026-8932: Include the complete mTLS client credential
configuration in connection reuse and TLS session-cache matching.
- CVE-2026-8458: Include the SASL service name in connection reuse
matching.
- CVE-2026-11856: Clear Digest authentication state when the origin,
proxy, or credentials change.
Three changes add CVE_STATUS annotations for vulnerabilities whose
applicability depends on the Wrynose curl configuration:
- CVE-2026-8924 is not applicable because the recipe explicitly builds
curl without Public Suffix List support using --without-libpsl.
- CVE-2026-9547 is not applicable because the vulnerable libssh backend
is not available in the recipe. The supported libssh2 backend is not
affected.
- CVE-2026-12064 is marked unpatched when the optional libssh2
PACKAGECONFIG is enabled and not-applicable-config otherwise, because
the affected SCP/SFTP support is provided through libssh2.
The manual adaptations required for curl 8.19.0 are documented in the
Backport Changes sections of the corresponding source patches.
Validation performed:
- All the curl patches are prepared on top of this upstream curl patch which is
under review: https://lists.openembedded.org/g/openembedded-core/topic/120530931
- All recipe changes apply using git am without three-way fallback.
- All existing Wrynose patches and the proposed source patches apply to
the checksum-verified curl 8.19.0 source with no fuzz.
- A host build using the GnuTLS backend completed successfully.
- Regression tests 1686, 3303, and 3304 passed.
Deepak Rathore (8):
curl: fix CVE-2026-8286
curl: set CVE_STATUS for CVE-2026-8924
curl: fix CVE-2026-8927
curl: fix CVE-2026-8932
curl: fix CVE-2026-8458
curl: fix CVE-2026-11856
curl: set CVE_STATUS for CVE-2026-9547
curl: set CVE_STATUS for CVE-2026-12064
.../curl/curl/CVE-2026-11856_p1.patch | 372 ++++++
.../curl/curl/CVE-2026-11856_p2.patch | 72 ++
.../curl/curl/CVE-2026-8286.patch | 81 ++
.../curl/curl/CVE-2026-8458.patch | 202 +++
.../curl/curl/CVE-2026-8927.patch | 349 +++++
.../curl/curl/CVE-2026-8932-dependent.patch | 71 +
.../curl/curl/CVE-2026-8932.patch | 1148 +++++++++++++++++
meta/recipes-support/curl/curl_8.19.0.bb | 11 +
8 files changed, 2306 insertions(+)
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8286.patch
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8458.patch
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8927.patch
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8932-dependent.patch
create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8932.patch
--
2.35.6
^ permalink raw reply [flat|nested] 16+ messages in thread* [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-25 15:04 ` Yoann Congal 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 2/8] curl: set CVE_STATUS for CVE-2026-8924 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (6 subsequent siblings) 7 siblings, 1 reply; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> This patch applies the upstream curl security fix backport for CVE-2026-8286. The upstream fix commit is referenced in [1], and the public curl advisory is referenced in [2]. The backported commit link is also recorded in the embedded patch header. [1] https://github.com/curl/curl/commit/a86efdd7ca5433de9231e650f18247de8319ad16 [2] https://curl.se/docs/CVE-2026-8286.html Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- .../curl/curl/CVE-2026-8286.patch | 81 +++++++++++++++++++ meta/recipes-support/curl/curl_8.19.0.bb | 1 + 2 files changed, 82 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8286.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-8286.patch b/meta/recipes-support/curl/curl/CVE-2026-8286.patch new file mode 100644 index 0000000000..6fa42887a1 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-8286.patch @@ -0,0 +1,81 @@ +From 90ff17f6bfe1d358c26fa25ab457bc420a9847b2 Mon Sep 17 00:00:00 2001 +From: Stefan Eissing <stefan@eissing.org> +Date: Thu, 7 May 2026 10:30:07 +0200 +Subject: [PATCH] url: fix connection reuse for starttls protocols + +When a connection is tested for reuse in a transfer that *may* upgrade +to TLS (commonly via STARTTLS), the SSL configuration must match the +existing connection. + +Reported-by: Andrew Nesbit +Closes #21522 + +CVE: CVE-2026-8286 +Upstream-Status: Backport [https://github.com/curl/curl/commit/a86efdd7ca5433de9231e650f18247de8319ad16] + +Backport Changes: +- Wrynose applies upstream commit [1] before this patch. That commit + adds req_tls to struct url_conn_match and initializes it in + url_attach_existing(). +- This backport replaces that local req_tls state with the upstream + may_tls/require_tls split and updates url_match_ssl_use(), + url_match_ssl_config(), and url_attach_existing() to preserve the + upstream STARTTLS reuse behavior on the Wrynose 8.19.0 codebase. + +[1] https://github.com/curl/curl/commit/507e7be573b0a76fca597b75ff7cb27a66e7d865 + +(cherry picked from commit a86efdd7ca5433de9231e650f18247de8319ad16) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/url.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 4ebff50ef1..6c1375f8e3 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -745,7 +745,11 @@ struct url_conn_match { + BIT(want_proxy_ntlm_http); + BIT(want_nego_http); + BIT(want_proxy_nego_http); +- BIT(req_tls); /* require TLS use from a clear-text start */ ++ BIT(may_tls); /* May upgrade clear-text connection to TLS, can only reuse ++ * connections that have matching TLS configuration. ++ * Always TRUE if `req_tls` is TRUE. */ ++ BIT(require_tls); /* Requires TLS use from a clear-text start, can only ++ * reuse connections that have TLS. */ + BIT(wait_pipe); + BIT(force_reuse); + BIT(seen_pending_conn); +@@ -897,7 +901,7 @@ static bool url_match_ssl_use(struct connectdata *conn, + (get_protocol_family(conn->scheme) != m->needle->scheme->protocol)) + return FALSE; + } +- else if(m->req_tls) ++ else if(m->require_tls) + /* a clear-text STARTTLS protocol with required TLS */ + return FALSE; + return TRUE; +@@ -1090,8 +1094,8 @@ static bool url_match_destination(struct connectdata *conn, + static bool url_match_ssl_config(struct connectdata *conn, + struct url_conn_match *m) + { +- /* If talking TLS, conn needs to use the same SSL options. */ +- if((m->needle->scheme->flags & PROTOPT_SSL) && ++ /* If talking/upgrading to TLS, conn needs to use the same SSL options. */ ++ if(((m->needle->scheme->flags & PROTOPT_SSL) || m->may_tls) && + !Curl_ssl_conn_config_match(m->data, conn, FALSE)) { + DEBUGF(infof(m->data, "Connection #%" FMT_OFF_T + " has different SSL parameters, cannot reuse", +@@ -1364,7 +1368,8 @@ static bool url_attach_existing(struct Curl_easy *data, + (needle->scheme->protocol & PROTO_FAMILY_HTTP); + #endif + #endif +- match.req_tls = data->set.use_ssl >= CURLUSESSL_CONTROL; ++ match.require_tls = data->set.use_ssl >= CURLUSESSL_CONTROL; ++ match.may_tls = data->set.use_ssl > CURLUSESSL_NONE; + + /* Find a connection in the pool that matches what "data + needle" + * requires. If a suitable candidate is found, it is attached to "data". */ +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index 5ba881bd76..ae57776eab 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -23,6 +23,7 @@ SRC_URI = " \ file://CVE-2026-6429.patch \ file://CVE-2026-7168.patch \ file://CVE-2026-4873.patch \ + file://CVE-2026-8286.patch \ " SRC_URI:append:class-nativesdk = " \ -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-25 15:04 ` Yoann Congal 2026-08-26 8:47 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 0 siblings, 1 reply; 16+ messages in thread From: Yoann Congal @ 2026-08-25 15:04 UTC (permalink / raw) To: deeratho, openembedded-core On Wed Aug 5, 2026 at 10:30 AM CEST, Deepak Rathore via lists.openembedded.org wrote: > From: Deepak Rathore <deeratho@cisco.com> > > This patch applies the upstream curl security fix backport for > CVE-2026-8286. The upstream fix commit is referenced in [1], > and the public curl advisory is referenced in [2]. The backported > commit link is also recorded in the embedded patch header. > > [1] https://github.com/curl/curl/commit/a86efdd7ca5433de9231e650f18247de8319ad16 > [2] https://curl.se/docs/CVE-2026-8286.html > > Signed-off-by: Deepak Rathore <deeratho@cisco.com> > --- > .../curl/curl/CVE-2026-8286.patch | 81 +++++++++++++++++++ > meta/recipes-support/curl/curl_8.19.0.bb | 1 + > 2 files changed, 82 insertions(+) > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8286.patch Hello, This series does not apply on top of the review branch anymore: https://git.openembedded.org/openembedded-core-contrib/log/?h=stable/wrynose-review |ERROR: curl-8.19.0-r0 do_patch: Applying patch '.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl/CVE-2026-8927.patch' on target directory '.../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/sources/curl-8.19.0' |CmdError('quilt --quiltrc .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/recipe-sysroot-native/etc/quiltrc push', 0, 'stdout: Applying patch CVE-2026-8927.patch |patching file lib/url.c |patching file lib/urldata.h |patching file tests/data/Makefile.am |Hunk #1 FAILED at 218. |1 out of 1 hunk FAILED -- rejects in file tests/data/Makefile.am |patching file tests/data/test1647 |patching file tests/libtest/Makefile.inc |Hunk #1 FAILED at 100. |1 out of 1 hunk FAILED -- rejects in file tests/libtest/Makefile.inc |patching file tests/libtest/lib1647.c |Patch CVE-2026-8927.patch does not apply (enforce with -f) | |stderr: ') |ERROR: Logfile of failure stored in: .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/temp/log.do_patch.468848 |ERROR: Task (.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl_8.19.0.bb:do_patch) failed with exit code '1' Can you please rebase and send a v2? Please note that there are other pending curl CVE patches, I'd recommand reviewing/testing patches to identify conflict at the earliest. Thanks! -- Yoann Congal Smile ECS ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 2026-08-25 15:04 ` Yoann Congal @ 2026-08-26 8:47 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-27 6:53 ` Yoann Congal 0 siblings, 1 reply; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-26 8:47 UTC (permalink / raw) To: Yoann Congal, openembedded-core@lists.openembedded.org [-- Attachment #1: Type: text/plain, Size: 3938 bytes --] Hi Yoann, Thank you for your review and feedback. These patches were originally prepared on top of the curl CVE fix series that is currently under review and already present in the wrynose/wrynose-nut review branches: * curl: fix CVE-2026-4873 - openembedded-core-contrib - OpenEmbedded Core user contribution trees<https://git.openembedded.org/openembedded-core-contrib/commit/?h=stable/wrynose-nut&id=7e44b94a57a1b7d9ec043554fb7f1f4c3fbfbbaf> * [wrynose,v4] curl: fix CVE-2026-4873 - Patchwork<https://patchwork.yoctoproject.org/project/oe-core/patch/20260731061427.14543-1-deeratho@cisco.com/> Because the remaining curl CVE patches in this series were developed on top of that patch, rebasing everything on the current wrynose review branch would require additional rebasing work once CVE-2026-4873 is merged. If you apply current curl patches on top of this CVE-2026-4873 fix, then there will be no build failure. Could you please advise on the preferred approach in this situation? I appreciate your guidance. Regards, Deepak Rathore ________________________________ From: Yoann Congal <yoann.congal@smile.fr> Sent: Tuesday, August 25, 2026 8:34 PM To: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) <deeratho@cisco.com>; openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> Subject: Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 On Wed Aug 5, 2026 at 10:30 AM CEST, Deepak Rathore via lists.openembedded.org wrote: > From: Deepak Rathore <deeratho@cisco.com> > > This patch applies the upstream curl security fix backport for > CVE-2026-8286. The upstream fix commit is referenced in [1], > and the public curl advisory is referenced in [2]. The backported > commit link is also recorded in the embedded patch header. > > [1] https://github.com/curl/curl/commit/a86efdd7ca5433de9231e650f18247de8319ad16 > [2] https://curl.se/docs/CVE-2026-8286.html > > Signed-off-by: Deepak Rathore <deeratho@cisco.com> > --- > .../curl/curl/CVE-2026-8286.patch | 81 +++++++++++++++++++ > meta/recipes-support/curl/curl_8.19.0.bb | 1 + > 2 files changed, 82 insertions(+) > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8286.patch Hello, This series does not apply on top of the review branch anymore: https://git.openembedded.org/openembedded-core-contrib/log/?h=stable/wrynose-review |ERROR: curl-8.19.0-r0 do_patch: Applying patch '.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl/CVE-2026-8927.patch' on target directory '.../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/sources/curl-8.19.0' |CmdError('quilt --quiltrc .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/recipe-sysroot-native/etc/quiltrc push', 0, 'stdout: Applying patch CVE-2026-8927.patch |patching file lib/url.c |patching file lib/urldata.h |patching file tests/data/Makefile.am |Hunk #1 FAILED at 218. |1 out of 1 hunk FAILED -- rejects in file tests/data/Makefile.am |patching file tests/data/test1647 |patching file tests/libtest/Makefile.inc |Hunk #1 FAILED at 100. |1 out of 1 hunk FAILED -- rejects in file tests/libtest/Makefile.inc |patching file tests/libtest/lib1647.c |Patch CVE-2026-8927.patch does not apply (enforce with -f) | |stderr: ') |ERROR: Logfile of failure stored in: .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/temp/log.do_patch.468848 |ERROR: Task (.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl_8.19.0.bb:do_patch) failed with exit code '1' Can you please rebase and send a v2? Please note that there are other pending curl CVE patches, I'd recommand reviewing/testing patches to identify conflict at the earliest. Thanks! -- Yoann Congal Smile ECS [-- Attachment #2: Type: text/html, Size: 7261 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 2026-08-26 8:47 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-27 6:53 ` Yoann Congal 2026-08-27 10:51 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 0 siblings, 1 reply; 16+ messages in thread From: Yoann Congal @ 2026-08-27 6:53 UTC (permalink / raw) To: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco), openembedded-core@lists.openembedded.org On Wed Aug 26, 2026 at 10:47 AM CEST, Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) wrote: > Hi Yoann, > Thank you for your review and feedback. > These patches were originally prepared on top of the curl CVE fix > series that is currently under review and already present in the > wrynose/wrynose-nut review branches: > > * > curl: fix CVE-2026-4873 - openembedded-core-contrib - OpenEmbedded Core user contribution trees<https://git.openembedded.org/openembedded-core-contrib/commit/?h=stable/wrynose-nut&id=7e44b94a57a1b7d9ec043554fb7f1f4c3fbfbbaf> > * > [wrynose,v4] curl: fix CVE-2026-4873 - Patchwork<https://patchwork.yoctoproject.org/project/oe-core/patch/20260731061427.14543-1-deeratho@cisco.com/> > > Because the remaining curl CVE patches in this series were developed > on top of that patch, rebasing everything on the current wrynose > review branch would require additional rebasing work once > CVE-2026-4873 is merged. If you apply current curl patches on top of > this CVE-2026-4873 fix, then there will be no build failure. Could you > please advise on the preferred approach in this situation? > I appreciate your guidance. > Regards, > Deepak Rathore Ok, there was a bad interaction with other curl patches in my series but those are gone now. So, this series does apply cleanly and I've added it to my review branch. Thanks! > ________________________________ > From: Yoann Congal <yoann.congal@smile.fr> > Sent: Tuesday, August 25, 2026 8:34 PM > To: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) <deeratho@cisco.com>; openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> > Subject: Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 > > On Wed Aug 5, 2026 at 10:30 AM CEST, Deepak Rathore via lists.openembedded.org wrote: >> From: Deepak Rathore <deeratho@cisco.com> >> >> This patch applies the upstream curl security fix backport for >> CVE-2026-8286. The upstream fix commit is referenced in [1], >> and the public curl advisory is referenced in [2]. The backported >> commit link is also recorded in the embedded patch header. >> >> [1] https://github.com/curl/curl/commit/a86efdd7ca5433de9231e650f18247de8319ad16 >> [2] https://curl.se/docs/CVE-2026-8286.html >> >> Signed-off-by: Deepak Rathore <deeratho@cisco.com> >> --- >> .../curl/curl/CVE-2026-8286.patch | 81 +++++++++++++++++++ >> meta/recipes-support/curl/curl_8.19.0.bb | 1 + >> 2 files changed, 82 insertions(+) >> create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8286.patch > > Hello, > > This series does not apply on top of the review branch anymore: > https://git.openembedded.org/openembedded-core-contrib/log/?h=stable/wrynose-review > |ERROR: curl-8.19.0-r0 do_patch: Applying patch '.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl/CVE-2026-8927.patch' on target directory '.../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/sources/curl-8.19.0' > |CmdError('quilt --quiltrc .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/recipe-sysroot-native/etc/quiltrc push', 0, 'stdout: Applying patch CVE-2026-8927.patch > |patching file lib/url.c > |patching file lib/urldata.h > |patching file tests/data/Makefile.am > |Hunk #1 FAILED at 218. > |1 out of 1 hunk FAILED -- rejects in file tests/data/Makefile.am > |patching file tests/data/test1647 > |patching file tests/libtest/Makefile.inc > |Hunk #1 FAILED at 100. > |1 out of 1 hunk FAILED -- rejects in file tests/libtest/Makefile.inc > |patching file tests/libtest/lib1647.c > |Patch CVE-2026-8927.patch does not apply (enforce with -f) > | > |stderr: ') > |ERROR: Logfile of failure stored in: .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/temp/log.do_patch.468848 > |ERROR: Task (.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl_8.19.0.bb:do_patch) failed with exit code '1' > > Can you please rebase and send a v2? > > Please note that there are other pending curl CVE patches, I'd recommand > reviewing/testing patches to identify conflict at the earliest. > > Thanks! > -- > Yoann Congal > Smile ECS -- Yoann Congal Smile ECS ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 2026-08-27 6:53 ` Yoann Congal @ 2026-08-27 10:51 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 0 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-27 10:51 UTC (permalink / raw) To: Yoann Congal, openembedded-core@lists.openembedded.org [-- Attachment #1: Type: text/plain, Size: 4826 bytes --] Thanks, Yoann, for the update!! Regards, Deepak ________________________________ From: Yoann Congal <yoann.congal@smile.fr> Sent: Thursday, August 27, 2026 12:23 PM To: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) <deeratho@cisco.com>; openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> Subject: Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 On Wed Aug 26, 2026 at 10:47 AM CEST, Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) wrote: > Hi Yoann, > Thank you for your review and feedback. > These patches were originally prepared on top of the curl CVE fix > series that is currently under review and already present in the > wrynose/wrynose-nut review branches: > > * > curl: fix CVE-2026-4873 - openembedded-core-contrib - OpenEmbedded Core user contribution trees<https://git.openembedded.org/openembedded-core-contrib/commit/?h=stable/wrynose-nut&id=7e44b94a57a1b7d9ec043554fb7f1f4c3fbfbbaf> > * > [wrynose,v4] curl: fix CVE-2026-4873 - Patchwork<https://patchwork.yoctoproject.org/project/oe-core/patch/20260731061427.14543-1-deeratho@cisco.com/> > > Because the remaining curl CVE patches in this series were developed > on top of that patch, rebasing everything on the current wrynose > review branch would require additional rebasing work once > CVE-2026-4873 is merged. If you apply current curl patches on top of > this CVE-2026-4873 fix, then there will be no build failure. Could you > please advise on the preferred approach in this situation? > I appreciate your guidance. > Regards, > Deepak Rathore Ok, there was a bad interaction with other curl patches in my series but those are gone now. So, this series does apply cleanly and I've added it to my review branch. Thanks! > ________________________________ > From: Yoann Congal <yoann.congal@smile.fr> > Sent: Tuesday, August 25, 2026 8:34 PM > To: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) <deeratho@cisco.com>; openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> > Subject: Re: [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 > > On Wed Aug 5, 2026 at 10:30 AM CEST, Deepak Rathore via lists.openembedded.org wrote: >> From: Deepak Rathore <deeratho@cisco.com> >> >> This patch applies the upstream curl security fix backport for >> CVE-2026-8286. The upstream fix commit is referenced in [1], >> and the public curl advisory is referenced in [2]. The backported >> commit link is also recorded in the embedded patch header. >> >> [1] https://github.com/curl/curl/commit/a86efdd7ca5433de9231e650f18247de8319ad16 >> [2] https://curl.se/docs/CVE-2026-8286.html >> >> Signed-off-by: Deepak Rathore <deeratho@cisco.com> >> --- >> .../curl/curl/CVE-2026-8286.patch | 81 +++++++++++++++++++ >> meta/recipes-support/curl/curl_8.19.0.bb | 1 + >> 2 files changed, 82 insertions(+) >> create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8286.patch > > Hello, > > This series does not apply on top of the review branch anymore: > https://git.openembedded.org/openembedded-core-contrib/log/?h=stable/wrynose-review > |ERROR: curl-8.19.0-r0 do_patch: Applying patch '.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl/CVE-2026-8927.patch' on target directory '.../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/sources/curl-8.19.0' > |CmdError('quilt --quiltrc .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/recipe-sysroot-native/etc/quiltrc push', 0, 'stdout: Applying patch CVE-2026-8927.patch > |patching file lib/url.c > |patching file lib/urldata.h > |patching file tests/data/Makefile.am > |Hunk #1 FAILED at 218. > |1 out of 1 hunk FAILED -- rejects in file tests/data/Makefile.am > |patching file tests/data/test1647 > |patching file tests/libtest/Makefile.inc > |Hunk #1 FAILED at 100. > |1 out of 1 hunk FAILED -- rejects in file tests/libtest/Makefile.inc > |patching file tests/libtest/lib1647.c > |Patch CVE-2026-8927.patch does not apply (enforce with -f) > | > |stderr: ') > |ERROR: Logfile of failure stored in: .../wrynose/bitbake-builds/poky-wrynose/build/tmp/work/x86-64-v3-poky-linux/curl/8.19.0/temp/log.do_patch.468848 > |ERROR: Task (.../wrynose/bitbake-builds/poky-wrynose/layers/openembedded-core/meta/recipes-support/curl/curl_8.19.0.bb:do_patch) failed with exit code '1' > > Can you please rebase and send a v2? > > Please note that there are other pending curl CVE patches, I'd recommand > reviewing/testing patches to identify conflict at the earliest. > > Thanks! > -- > Yoann Congal > Smile ECS -- Yoann Congal Smile ECS [-- Attachment #2: Type: text/html, Size: 7450 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 2/8] curl: set CVE_STATUS for CVE-2026-8924 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 3/8] curl: fix CVE-2026-8927 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (5 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> Analysis: - CVE-2026-8924 protects cookie domain handling when public suffix list support is enabled in curl. [1] - Wrynose curl 8.19.0 is configured with --without-libpsl, so the PSL check path is not built by the default recipe. [2] - Hence mark this CVE as not-applicable-config for the default Wrynose recipe configuration. Reference: [1] https://curl.se/docs/CVE-2026-8924.html [2] https://git.openembedded.org/openembedded-core/tree/meta/recipes-support/curl/curl_8.19.0.bb?h=wrynose Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- meta/recipes-support/curl/curl_8.19.0.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index ae57776eab..5bec405eb7 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -35,6 +35,7 @@ SRC_URI[sha256sum] = "4eb41489790d19e190d7ac7e18e82857cdd68af8f4e66b292ced562d33 # Curl has used many names over the years... CVE_PRODUCT = "haxx:curl haxx:libcurl curl:curl curl:libcurl libcurl:libcurl daniel_stenberg:curl" CVE_STATUS[CVE-2024-32928] = "ignored: CURLOPT_SSL_VERIFYPEER was disabled on google cloud services causing a potential man in the middle attack" +CVE_STATUS[CVE-2026-8924] = "not-applicable-config: public suffix list support is disabled by the recipe with --without-libpsl" CVE_STATUS[CVE-2026-10536] = "${@bb.utils.contains('PACKAGECONFIG', 'nghttp2', 'unpatched', 'not-applicable-config: applicable only with HTTP/2', d)}" inherit autotools pkgconfig binconfig multilib_header ptest -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 3/8] curl: fix CVE-2026-8927 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 2/8] curl: set CVE_STATUS for CVE-2026-8924 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 4/8] curl: fix CVE-2026-8932 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (4 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> This patch applies the upstream curl security fix backport for CVE-2026-8927. The upstream fix commit is referenced in [1], and the public curl advisory is referenced in [2]. The backported commit link is also recorded in the embedded patch header. [1] https://github.com/curl/curl/commit/5c225384b8d52c67ce8259c6e4203bc57aacb567 [2] https://curl.se/docs/CVE-2026-8927.html Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- .../curl/curl/CVE-2026-8927.patch | 349 ++++++++++++++++++ meta/recipes-support/curl/curl_8.19.0.bb | 1 + 2 files changed, 350 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8927.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-8927.patch b/meta/recipes-support/curl/curl/CVE-2026-8927.patch new file mode 100644 index 0000000000..653d908eb5 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-8927.patch @@ -0,0 +1,349 @@ +From c3e9c57b5cd128f33250caf86184e23dc1e8c4e5 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Thu, 30 Jul 2026 04:29:18 -0700 +Subject: [PATCH] url: detect proxy changes read from environment + +When a proxy is set from an environment variable, detect if that proxy +is not the same as previously and flush state. + +Verified by test1647: verify changing proxy with env variables and make +sure Digest state is flushed in the second use + +Closes #21666 + +CVE: CVE-2026-8927 +Upstream-Status: Backport [https://github.com/curl/curl/commit/5c225384b8d52c67ce8259c6e4203bc57aacb567] + +Backport Changes: +- Kept Wrynose test registry ordering and added only the new upstream + test1647/lib1647 regression test entries. +- Added the explicit vauth/vauth.h include because Wrynose's url.c did + not already include the Digest cleanup prototype used by this fix. +- Placed the env proxy comparison before parse_proxy() because Wrynose + frees the temporary proxy string immediately after parse_proxy() copies + it. + +(cherry picked from commit 5c225384b8d52c67ce8259c6e4203bc57aacb567) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/url.c | 12 ++++ + lib/urldata.h | 1 + + tests/data/Makefile.am | 2 +- + tests/data/test1647 | 103 +++++++++++++++++++++++++++++++ + tests/libtest/Makefile.inc | 1 + + tests/libtest/lib1647.c | 120 +++++++++++++++++++++++++++++++++++++ + 6 files changed, 238 insertions(+), 1 deletion(-) + create mode 100644 tests/data/test1647 + create mode 100644 tests/libtest/lib1647.c + +diff --git a/lib/url.c b/lib/url.c +index 6c1375f8e3..1cd3955e64 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -99,6 +99,7 @@ + #include "headers.h" + #include "curlx/strerr.h" + #include "curlx/strparse.h" ++#include "vauth/vauth.h" + + /* And now for the protocols */ + #include "ftp.h" +@@ -326,6 +327,9 @@ CURLcode Curl_close(struct Curl_easy **datap) + Curl_freeset(data); + Curl_headers_cleanup(data); + Curl_netrc_cleanup(&data->state.netrc); ++#ifndef CURL_DISABLE_DIGEST_AUTH ++ curlx_free(data->state.envproxy); ++#endif + curlx_free(data); + return CURLE_OK; + } +@@ -2354,6 +2358,14 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, + if(proxy || socksproxy) { + long ptype = conn->http_proxy.proxytype; + if(proxy) { ++#ifndef CURL_DISABLE_DIGEST_AUTH ++ if(!Curl_safecmp(data->state.envproxy, proxy)) { ++ /* proxy changed */ ++ Curl_auth_digest_cleanup(&data->state.proxydigest); ++ curlx_free(data->state.envproxy); ++ data->state.envproxy = curlx_strdup(proxy); ++ } ++#endif + result = parse_proxy(data, conn, proxy, ptype); + Curl_safefree(proxy); /* parse_proxy copies the proxy string */ + if(result) +diff --git a/lib/urldata.h b/lib/urldata.h +index d71337c8f6..65005c4b34 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -959,6 +959,7 @@ struct UrlState { + void (*prev_signal)(int sig); + #endif + #ifndef CURL_DISABLE_DIGEST_AUTH ++ char *envproxy; /* last proxy string used for proxy-related state */ + struct digestdata digest; /* state data for host Digest auth */ + struct digestdata proxydigest; /* state data for proxy Digest auth */ + #endif +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 1e84b26820..bcee03b938 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -218,7 +218,7 @@ test1620 test1621 test1622 test1623 test1624 \ + \ + test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 \ + \ +-test1640 test1641 test1642 test1643 \ ++test1640 test1641 test1642 test1643 test1647 \ + \ + test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \ + test1658 \ +diff --git a/tests/data/test1647 b/tests/data/test1647 +new file mode 100644 +index 0000000000..a87487fa9f +--- /dev/null ++++ b/tests/data/test1647 +@@ -0,0 +1,103 @@ ++<?xml version="1.0" encoding="US-ASCII"?> ++<testcase> ++<info> ++<keywords> ++HTTP ++HTTP GET ++HTTP proxy ++HTTP proxy Digest auth ++multi ++</keywords> ++</info> ++ ++# Server-side ++<reply> ++ ++# this is returned first since we get no proxy-auth ++<data crlf="headers" nocheck="yes"> ++HTTP/1.1 407 Authorization Required to proxy me my dear ++Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345" ++Content-Length: 33 ++ ++And you should ignore this data. ++</data> ++ ++# then this is returned when we get proxy-auth ++<data1000 crlf="headers"> ++HTTP/1.1 200 OK ++Content-Length: 21 ++Server: no ++ ++Nice proxy auth sir! ++</data1000> ++ ++<connect crlf="headers"> ++HTTP/1.1 401 OK ++Content-Length: 21 ++Server: no ++ ++Denied access. Leave ++</connect> ++ ++</reply> ++ ++# Client-side ++<client> ++<server> ++http ++https-proxy ++https ++</server> ++# tool is what to use instead of 'curl' ++<tool> ++lib%TESTNUMBER ++</tool> ++<features> ++!SSPI ++crypto ++proxy ++digest ++Debug ++</features> ++<setenv> ++http_proxy=%HOSTIP:%HTTPPORT ++https_proxy=https://%HOSTIP:%HTTPSPROXYPORT ++CURL_ENTROPY=99376 ++</setenv> ++<name> ++HTTP proxy auth Digest, then change proxy with env var and do it again ++</name> ++<command> ++http://test.remote.example.com/path/%TESTNUMBER https://another.example.com:%HTTPSPORT/ daniel:monkey123 another:bump456 ++</command> ++</client> ++ ++# Verify data after the test has been "shot" ++<verify> ++<protocol crlf="headers"> ++GET http://test.remote.example.com/path/%TESTNUMBER HTTP/1.1 ++Host: test.remote.example.com ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++GET http://test.remote.example.com/path/%TESTNUMBER HTTP/1.1 ++Host: test.remote.example.com ++Proxy-Authorization: Digest username="daniel", realm="weirdorealm", nonce="12345", uri="/path/%TESTNUMBER", response="7a1672891aff03248887b1a6674b8096" ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++</protocol> ++ ++<proxy crlf="headers"> ++CONNECT another.example.com:%HTTPSPORT HTTP/1.1 ++Host: another.example.com:%HTTPSPORT ++Proxy-Connection: Keep-Alive ++ ++</proxy> ++ ++# CONNECT fails ++<errorcode> ++7 ++</errorcode> ++</verify> ++</testcase> +diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc +index 96b82bc059..e938b87bc5 100644 +--- a/tests/libtest/Makefile.inc ++++ b/tests/libtest/Makefile.inc +@@ -100,6 +100,7 @@ TESTS_C = \ + lib1582.c lib1588.c \ + lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c \ + lib1598.c lib1599.c \ ++ lib1647.c \ + lib1662.c \ + lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c \ + lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c \ +diff --git a/tests/libtest/lib1647.c b/tests/libtest/lib1647.c +new file mode 100644 +index 0000000000..8060e1bfe9 +--- /dev/null ++++ b/tests/libtest/lib1647.c +@@ -0,0 +1,120 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at https://curl.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ * SPDX-License-Identifier: curl ++ * ++ ***************************************************************************/ ++/* ++ * argv1 = the first URL ++ * argv2 = URL2 ++ * argv3 = credentials 1 ++ * argv4 = credentials 2 ++ */ ++ ++#include "first.h" ++ ++/* this is meant to pick up the proxy from the environment variable */ ++static CURLcode init1647(CURL *curl, const char *url, const char *userpwd) ++{ ++ CURLcode result = CURLE_OK; ++ ++ res_easy_setopt(curl, CURLOPT_URL, url); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_VERBOSE, 1L); ++ if(result) ++ goto init_failed; ++ ++ return CURLE_OK; /* success */ ++ ++init_failed: ++ return result; /* failure */ ++} ++ ++static CURLcode run1647(CURL *curl, const char *url, const char *userpwd) ++{ ++ CURLcode result = CURLE_OK; ++ ++ result = init1647(curl, url, userpwd); ++ if(result) ++ return result; ++ ++ return curl_easy_perform(curl); ++} ++ ++static CURLcode test_lib1647(const char *URL) ++{ ++ CURLcode result = CURLE_OK; ++ CURL *curl = NULL; ++ ++ res_global_init(CURL_GLOBAL_ALL); ++ if(result) ++ return result; ++ ++ curl = curl_easy_init(); ++ if(!curl) { ++ curl_mfprintf(stderr, "curl_easy_init() failed\n"); ++ curl_global_cleanup(); ++ return TEST_ERR_MAJOR_BAD; ++ } ++ ++ start_test_timing(); ++ ++ curl_mprintf("--- First get '%s'\n", URL); ++ result = run1647(curl, URL, libtest_arg3); ++ if(result) ++ goto test_cleanup; ++ ++ curl_mprintf("--- Then get '%s'\n", libtest_arg2); ++ result = run1647(curl, libtest_arg2, libtest_arg4); ++ ++test_cleanup: ++ ++ /* proper cleanup sequence - type PB */ ++ ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ return result; ++} +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index 5bec405eb7..193366f657 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -24,6 +24,7 @@ SRC_URI = " \ file://CVE-2026-7168.patch \ file://CVE-2026-4873.patch \ file://CVE-2026-8286.patch \ + file://CVE-2026-8927.patch \ " SRC_URI:append:class-nativesdk = " \ -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 4/8] curl: fix CVE-2026-8932 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (2 preceding siblings ...) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 3/8] curl: fix CVE-2026-8927 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 5/8] curl: fix CVE-2026-8458 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (3 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:30 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> This patch applies the upstream curl security fix backport for CVE-2026-8932. The upstream dependency commit is referenced in [1], the upstream fix commit is referenced in [2], and the public curl advisory is referenced in [3]. The individual backported commit links are recorded in the embedded patch headers. [1] https://github.com/curl/curl/commit/67bf021e97bbebadade7e40217a4967042ac6a07 [2] https://github.com/curl/curl/commit/7541ae569d82fb308a5e2d94916027da4fa3ba3e [3] https://curl.se/docs/CVE-2026-8932.html Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- .../curl/curl/CVE-2026-8932-dependent.patch | 71 + .../curl/curl/CVE-2026-8932.patch | 1148 +++++++++++++++++ meta/recipes-support/curl/curl_8.19.0.bb | 2 + 3 files changed, 1221 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8932-dependent.patch create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8932.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-8932-dependent.patch b/meta/recipes-support/curl/curl/CVE-2026-8932-dependent.patch new file mode 100644 index 0000000000..c64ced329a --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-8932-dependent.patch @@ -0,0 +1,71 @@ +From a79f8dae1aa632155be430143b4685f0b91d1694 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Wed, 6 May 2026 23:59:22 +0200 +Subject: [PATCH] mbedtls: null terminate the private key blob + +Unfortunately, mbedtls_pk_parse_key() requires the data to be +null-terminated if the data is PEM encoded (even when provided the exact +length), so this function needs to make a copy that has one. + +Reported-by: Elise Vance +Closes #21515 + +CVE: CVE-2026-8932 +Upstream-Status: Backport [https://github.com/curl/curl/commit/67bf021e97bbebadade7e40217a4967042ac6a07] + +Backport Changes: +- Added as a prerequisite for upstream commit [1] because Wrynose curl + 8.19.0 did not already contain this mbedTLS private-key blob fix. + +[1] https://github.com/curl/curl/commit/7541ae569d82fb308a5e2d94916027da4fa3ba3e + +(cherry picked from commit 67bf021e97bbebadade7e40217a4967042ac6a07) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/vtls/mbedtls.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c +index 2bac406c35..54f0ac9fd4 100644 +--- a/lib/vtls/mbedtls.c ++++ b/lib/vtls/mbedtls.c +@@ -697,11 +697,17 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + } + else { + const struct curl_blob *ssl_key_blob = ssl_config->key_blob; +- const unsigned char *key_data = +- (const unsigned char *)ssl_key_blob->data; + const char *passwd = ssl_config->key_passwd; ++ /* Unfortunately, mbedtls_pk_parse_key() requires the data to be ++ null-terminated if the data is PEM encoded (even when provided the ++ exact length). */ ++ unsigned char *newblob = curlx_memdup0(ssl_key_blob->data, ++ ssl_key_blob->len); ++ if(!newblob) ++ return CURLE_OUT_OF_MEMORY; ++ + #if MBEDTLS_VERSION_NUMBER >= 0x04000000 +- ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, ++ ret = mbedtls_pk_parse_key(&backend->pk, newblob, ssl_key_blob->len, + (const unsigned char *)passwd, + passwd ? strlen(passwd) : 0); + if(ret == 0 && +@@ -713,7 +719,7 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + PSA_KEY_USAGE_SIGN_HASH))) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + #else +- ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, ++ ret = mbedtls_pk_parse_key(&backend->pk, newblob, ssl_key_blob->len, + (const unsigned char *)passwd, + passwd ? strlen(passwd) : 0, + mbedtls_ctr_drbg_random, +@@ -722,6 +728,7 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + #endif ++ curlx_free(newblob); + + if(ret) { + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl/CVE-2026-8932.patch b/meta/recipes-support/curl/curl/CVE-2026-8932.patch new file mode 100644 index 0000000000..8fec1a5adb --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-8932.patch @@ -0,0 +1,1148 @@ +From c1cf1ddf723cdfcbd071394a6b4e73ea995e100a Mon Sep 17 00:00:00 2001 +From: Joshua Rogers <MegaManSec@users.noreply.github.com> +Date: Tue, 14 Jul 2026 04:38:15 -0700 +Subject: [PATCH] tls: fix incomplete mTLS config in conn reuse and session + cache + +cert_type, key, key_type, key_passwd and key_blob lived in +ssl_config_data but not in ssl_primary_config, so they were invisible to +match_ssl_primary_config() and to the TLS session cache peer key. + +Two easy handles sharing a connection pool could reuse each other's +authenticated connections when they differed only on SSLKEY, SSLKEYTYPE, +KEYPASSWD, SSLCERTTYPE or SSLKEYBLOB. The second handle would silently +inherit the first handle's authenticated identity. + +Promote all five fields into ssl_primary_config so the conn-reuse +predicate and session cache key cover the complete client credential +set. Also replace the fixed ":CCERT" session cache marker with the +actual clientcert path so sessions are not shared across different +client certificates. + +Verified by test 3303 and 3304 + +Reported-By: Joshua Rogers (AISLE Research) +Closes #21667 + +CVE: CVE-2026-8932 +Upstream-Status: Backport [https://github.com/curl/curl/commit/7541ae569d82fb308a5e2d94916027da4fa3ba3e] + +Backport Changes: +- Split prerequisite upstream commit [1] before this patch. This patch + now applies on top of that dependency and does not fold in the + mbedTLS private-key blob null-termination change. +- Kept Wrynose Curl_safefree() helper usage and local result-variable + style while preserving the upstream mTLS credential matching and + session-cache key behavior. +- Wrynose curl 8.19.0 does not have upstream Curl_peer. The + Curl_ssl_peer_key_build() helper keeps Wrynose connectdata and + conn_to_host/conn_to_port keying while adding the mTLS key fields. +- Kept Wrynose test registry ordering and added only the new upstream + test3303/test3304 and unit3303/unit3304 regression test entries. + +[1] https://github.com/curl/curl/commit/67bf021e97bbebadade7e40217a4967042ac6a07 + +(cherry picked from commit 7541ae569d82fb308a5e2d94916027da4fa3ba3e) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/ldap.c | 4 +- + lib/urldata.h | 10 +-- + lib/vssh/libssh.c | 6 +- + lib/vssh/libssh2.c | 2 +- + lib/vtls/gtls.c | 14 ++-- + lib/vtls/mbedtls.c | 24 +++--- + lib/vtls/openssl.c | 7 +- + lib/vtls/rustls.c | 13 ++-- + lib/vtls/schannel.c | 10 +-- + lib/vtls/vtls.c | 37 ++++++--- + lib/vtls/vtls_scache.c | 105 +++++++++++++++++++++----- + lib/vtls/vtls_scache.h | 16 ++++ + lib/vtls/wolfssl.c | 14 ++-- + tests/data/Makefile.am | 3 + + tests/data/test3303 | 20 +++++ + tests/data/test3304 | 20 +++++ + tests/unit/Makefile.inc | 3 +- + tests/unit/unit3303.c | 127 +++++++++++++++++++++++++++++++ + tests/unit/unit3304.c | 163 ++++++++++++++++++++++++++++++++++++++++ + 19 files changed, 517 insertions(+), 81 deletions(-) + create mode 100644 tests/data/test3303 + create mode 100644 tests/data/test3304 + create mode 100644 tests/unit/unit3303.c + create mode 100644 tests/unit/unit3304.c + +diff --git a/lib/ldap.c b/lib/ldap.c +index e223078b03..5bf76572c8 100644 +--- a/lib/ldap.c ++++ b/lib/ldap.c +@@ -329,8 +329,8 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) + #ifdef LDAP_OPT_X_TLS + if(conn->ssl_config.verifypeer) { + /* OpenLDAP SDK supports BASE64 files. */ +- if(data->set.ssl.cert_type && +- !curl_strequal(data->set.ssl.cert_type, "PEM")) { ++ if(data->set.ssl.primary.cert_type && ++ !curl_strequal(data->set.ssl.primary.cert_type, "PEM")) { + failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type"); + result = CURLE_SSL_CERTPROBLEM; + goto quit; +diff --git a/lib/urldata.h b/lib/urldata.h +index 65005c4b34..dce181d99d 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -230,9 +230,14 @@ struct ssl_primary_config { + char *signature_algorithms; /* list of signature algorithms to use */ + char *pinned_key; + char *CRLfile; /* CRL to check certificate revocation */ ++ char *cert_type; /* format for certificate (default: PEM) */ ++ char *key; /* private key filename */ ++ char *key_type; /* format for private key (default: PEM) */ ++ char *key_passwd; /* plain text private key password */ + struct curl_blob *cert_blob; + struct curl_blob *ca_info_blob; + struct curl_blob *issuercert_blob; ++ struct curl_blob *key_blob; + #ifdef USE_TLS_SRP + char *username; /* TLS username (for, e.g., SRP) */ + char *password; /* TLS password (for, e.g., SRP) */ +@@ -252,11 +257,6 @@ struct ssl_config_data { + long certverifyresult; /* result from the certificate verification */ + curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ + void *fsslctxp; /* parameter for call back */ +- char *cert_type; /* format for certificate (default: PEM) */ +- char *key; /* private key filename */ +- struct curl_blob *key_blob; +- char *key_type; /* format for private key (default: PEM) */ +- char *key_passwd; /* plain text private key password */ + BIT(certinfo); /* gather lots of certificate info */ + BIT(earlydata); /* use TLS 1.3 early data */ + BIT(enable_beast); /* allow this flaw for interoperability's sake */ +diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c +index 3a2a52e1f8..db767f7d00 100644 +--- a/lib/vssh/libssh.c ++++ b/lib/vssh/libssh.c +@@ -791,7 +791,7 @@ static int myssh_in_AUTH_PKEY_INIT(struct Curl_easy *data, + /* Two choices, (1) private key was given on CMD, + * (2) use the "default" keys. */ + if(data->set.str[STRING_SSH_PRIVATE_KEY]) { +- if(sshc->pubkey && !data->set.ssl.key_passwd) { ++ if(sshc->pubkey && !data->set.ssl.primary.key_passwd) { + rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, sshc->pubkey); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; +@@ -804,7 +804,7 @@ static int myssh_in_AUTH_PKEY_INIT(struct Curl_easy *data, + + rc = ssh_pki_import_privkey_file(data-> + set.str[STRING_SSH_PRIVATE_KEY], +- data->set.ssl.key_passwd, NULL, ++ data->set.ssl.primary.key_passwd, NULL, + NULL, &sshc->privkey); + if(rc != SSH_OK) { + failf(data, "Could not load private key file %s", +@@ -817,7 +817,7 @@ static int myssh_in_AUTH_PKEY_INIT(struct Curl_easy *data, + } + else { + rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, +- data->set.ssl.key_passwd); ++ data->set.ssl.primary.key_passwd); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + +diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c +index 63f5735b83..3c25fe7448 100644 +--- a/lib/vssh/libssh2.c ++++ b/lib/vssh/libssh2.c +@@ -1144,7 +1144,7 @@ static CURLcode ssh_state_pkey_init(struct Curl_easy *data, + return CURLE_OUT_OF_MEMORY; + } + +- sshc->passphrase = data->set.ssl.key_passwd; ++ sshc->passphrase = data->set.ssl.primary.key_passwd; + if(!sshc->passphrase) + sshc->passphrase = ""; + +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index a0a465c360..bfeb948542 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -988,10 +988,11 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, + if(result) + return result; + } +- if(ssl_config->cert_type && curl_strequal(ssl_config->cert_type, "P12")) { ++ if(ssl_config->primary.cert_type && ++ curl_strequal(ssl_config->primary.cert_type, "P12")) { + rc = gnutls_certificate_set_x509_simple_pkcs12_file( + gtls->shared_creds->creds, config->clientcert, GNUTLS_X509_FMT_DER, +- ssl_config->key_passwd ? ssl_config->key_passwd : ""); ++ ssl_config->primary.key_passwd ? ssl_config->primary.key_passwd : ""); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, + "error reading X.509 potentially-encrypted key or certificate " +@@ -1009,14 +1010,15 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, + rc = gnutls_certificate_set_x509_key_file2( + gtls->shared_creds->creds, + config->clientcert, +- ssl_config->key ? ssl_config->key : config->clientcert, +- gnutls_do_file_type(ssl_config->cert_type), +- ssl_config->key_passwd, ++ ssl_config->primary.key ? ssl_config->primary.key : ++ config->clientcert, ++ gnutls_do_file_type(ssl_config->primary.cert_type), ++ ssl_config->primary.key_passwd, + supported_key_encryption_algorithms); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, + "error reading X.509 %skey file: %s", +- ssl_config->key_passwd ? "potentially-encrypted " : "", ++ ssl_config->primary.key_passwd ? "potentially-encrypted " : "", + gnutls_strerror(rc)); + return CURLE_SSL_CONNECT_ERROR; + } +diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c +index 54f0ac9fd4..d2199df884 100644 +--- a/lib/vtls/mbedtls.c ++++ b/lib/vtls/mbedtls.c +@@ -484,7 +484,7 @@ static CURLcode mbed_load_cacert(struct Curl_cfilter *cf, + const char * const ssl_capath = conn_config->CApath; + #ifdef MBEDTLS_PEM_PARSE_C + struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); +- const char * const ssl_cert_type = ssl_config->cert_type; ++ const char * const ssl_cert_type = ssl_config->primary.cert_type; + #endif + int ret = -1; + char errorbuf[128]; +@@ -579,7 +579,7 @@ static CURLcode mbed_load_clicert(struct Curl_cfilter *cf, + char * const ssl_cert = ssl_config->primary.clientcert; + const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; + #ifdef MBEDTLS_PEM_PARSE_C +- const char * const ssl_cert_type = ssl_config->cert_type; ++ const char * const ssl_cert_type = ssl_config->primary.cert_type; + #endif + int ret = -1; + char errorbuf[128]; +@@ -660,12 +660,12 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + + mbedtls_pk_init(&backend->pk); + +- if(ssl_config->key || ssl_config->key_blob) { +- if(ssl_config->key) { ++ if(ssl_config->primary.key || ssl_config->primary.key_blob) { ++ if(ssl_config->primary.key) { + #ifdef MBEDTLS_FS_IO + #if MBEDTLS_VERSION_NUMBER >= 0x04000000 +- ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key, +- ssl_config->key_passwd); ++ ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->primary.key, ++ ssl_config->primary.key_passwd); + if(ret == 0 && + !(mbedtls_pk_can_do_psa(&backend->pk, + PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH), +@@ -675,8 +675,8 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + PSA_KEY_USAGE_SIGN_HASH))) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + #else +- ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key, +- ssl_config->key_passwd, ++ ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->primary.key, ++ ssl_config->primary.key_passwd, + mbedtls_ctr_drbg_random, + &rng.drbg); + if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || +@@ -687,7 +687,7 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + if(ret) { + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "mbedTLS: error reading private key %s: (-0x%04X) %s", +- ssl_config->key, -ret, errorbuf); ++ ssl_config->primary.key, -ret, errorbuf); + return CURLE_SSL_CERTPROBLEM; + } + #else +@@ -696,8 +696,8 @@ static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, + #endif + } + else { +- const struct curl_blob *ssl_key_blob = ssl_config->key_blob; +- const char *passwd = ssl_config->key_passwd; ++ const struct curl_blob *ssl_key_blob = ssl_config->primary.key_blob; ++ const char *passwd = ssl_config->primary.key_passwd; + /* Unfortunately, mbedtls_pk_parse_key() requires the data to be + null-terminated if the data is PEM encoded (even when provided the + exact length). */ +@@ -931,7 +931,7 @@ static CURLcode mbed_configure_ssl(struct Curl_cfilter *cf, + #endif + ); + +- if(ssl_config->key || ssl_config->key_blob) { ++ if(ssl_config->primary.key || ssl_config->primary.key_blob) { + mbedtls_ssl_conf_own_cert(&backend->config, &backend->clicert, + &backend->pk); + } +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 50bf1e0476..9cbab14b41 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3724,7 +3724,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, + struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); + char * const ssl_cert = ssl_config->primary.clientcert; + const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; +- const char * const ssl_cert_type = ssl_config->cert_type; ++ const char * const ssl_cert_type = ssl_config->primary.cert_type; + unsigned int ssl_version_min; + char error_buffer[256]; + +@@ -3888,8 +3888,9 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, + if(ssl_cert || ssl_cert_blob || ssl_cert_type) { + result = client_cert(data, octx->ssl_ctx, + ssl_cert, ssl_cert_blob, ssl_cert_type, +- ssl_config->key, ssl_config->key_blob, +- ssl_config->key_type, ssl_config->key_passwd); ++ ssl_config->primary.key, ssl_config->primary.key_blob, ++ ssl_config->primary.key_type, ++ ssl_config->primary.key_passwd); + if(result) + /* failf() is already done in client_cert() */ + return result; +diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c +index 061b444bce..564b10aa47 100644 +--- a/lib/vtls/rustls.c ++++ b/lib/vtls/rustls.c +@@ -841,14 +841,14 @@ init_config_builder_client_auth(struct Curl_easy *data, + const struct rustls_certified_key *certified_key = NULL; + CURLcode result = CURLE_OK; + +- if(conn_config->clientcert && !ssl_config->key) { ++ if(conn_config->clientcert && !ssl_config->primary.key) { + failf(data, "rustls: must provide key with certificate '%s'", + conn_config->clientcert); + return CURLE_SSL_CERTPROBLEM; + } +- else if(!conn_config->clientcert && ssl_config->key) { ++ else if(!conn_config->clientcert && ssl_config->primary.key) { + failf(data, "rustls: must provide certificate with key '%s'", +- ssl_config->key); ++ ssl_config->primary.key); + return CURLE_SSL_CERTPROBLEM; + } + +@@ -862,8 +862,9 @@ init_config_builder_client_auth(struct Curl_easy *data, + goto cleanup; + } + +- if(!read_file_into(ssl_config->key, &key_contents)) { +- failf(data, "rustls: failed to read key file: '%s'", ssl_config->key); ++ if(!read_file_into(ssl_config->primary.key, &key_contents)) { ++ failf(data, "rustls: failed to read key file: '%s'", ++ ssl_config->primary.key); + result = CURLE_SSL_CERTPROBLEM; + goto cleanup; + } +@@ -1053,7 +1054,7 @@ static CURLcode cr_init_backend(struct Curl_cfilter *cf, + } + } + +- if(conn_config->clientcert || ssl_config->key) { ++ if(conn_config->clientcert || ssl_config->primary.key) { + result = init_config_builder_client_auth(data, + conn_config, + ssl_config, +diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c +index 650a0e38ca..a4f57c7c0a 100644 +--- a/lib/vtls/schannel.c ++++ b/lib/vtls/schannel.c +@@ -414,8 +414,8 @@ static CURLcode get_client_cert(struct Curl_easy *data, + } + } + +- if((fInCert || blob) && data->set.ssl.cert_type && +- !curl_strequal(data->set.ssl.cert_type, "P12")) { ++ if((fInCert || blob) && data->set.ssl.primary.cert_type && ++ !curl_strequal(data->set.ssl.primary.cert_type, "P12")) { + failf(data, "schannel: certificate format compatibility error " + "for %s", + blob ? "(memory blob)" : data->set.ssl.primary.clientcert); +@@ -465,15 +465,15 @@ static CURLcode get_client_cert(struct Curl_easy *data, + datablob.pbData = (BYTE *)certdata; + datablob.cbData = (DWORD)certsize; + +- if(data->set.ssl.key_passwd) +- pwd_len = strlen(data->set.ssl.key_passwd); ++ if(data->set.ssl.primary.key_passwd) ++ pwd_len = strlen(data->set.ssl.primary.key_passwd); + pszPassword = (WCHAR *)curlx_malloc(sizeof(WCHAR) * (pwd_len + 1)); + if(pszPassword) { + int str_w_len = 0; + if(pwd_len > 0) + str_w_len = MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, +- data->set.ssl.key_passwd, ++ data->set.ssl.primary.key_passwd, + (int)pwd_len, + pszPassword, (int)(pwd_len + 1)); + +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index f7201d18d6..6dcc67dccd 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -204,6 +204,7 @@ static bool match_ssl_primary_config(struct Curl_easy *data, + blobcmp(c1->cert_blob, c2->cert_blob) && + blobcmp(c1->ca_info_blob, c2->ca_info_blob) && + blobcmp(c1->issuercert_blob, c2->issuercert_blob) && ++ blobcmp(c1->key_blob, c2->key_blob) && + Curl_safecmp(c1->CApath, c2->CApath) && + Curl_safecmp(c1->CAfile, c2->CAfile) && + Curl_safecmp(c1->issuercert, c2->issuercert) && +@@ -217,7 +218,11 @@ static bool match_ssl_primary_config(struct Curl_easy *data, + curl_strequal(c1->curves, c2->curves) && + curl_strequal(c1->signature_algorithms, c2->signature_algorithms) && + curl_strequal(c1->CRLfile, c2->CRLfile) && +- curl_strequal(c1->pinned_key, c2->pinned_key)) ++ curl_strequal(c1->pinned_key, c2->pinned_key) && ++ curl_strequal(c1->cert_type, c2->cert_type) && ++ Curl_safecmp(c1->key, c2->key) && ++ curl_strequal(c1->key_type, c2->key_type) && ++ !Curl_timestrcmp(c1->key_passwd, c2->key_passwd)) + return TRUE; + + return FALSE; +@@ -252,6 +257,7 @@ static bool clone_ssl_primary_config(struct ssl_primary_config *source, + CLONE_BLOB(cert_blob); + CLONE_BLOB(ca_info_blob); + CLONE_BLOB(issuercert_blob); ++ CLONE_BLOB(key_blob); + CLONE_STRING(CApath); + CLONE_STRING(CAfile); + CLONE_STRING(issuercert); +@@ -262,6 +268,10 @@ static bool clone_ssl_primary_config(struct ssl_primary_config *source, + CLONE_STRING(curves); + CLONE_STRING(signature_algorithms); + CLONE_STRING(CRLfile); ++ CLONE_STRING(cert_type); ++ CLONE_STRING(key); ++ CLONE_STRING(key_type); ++ CLONE_STRING(key_passwd); + #ifdef USE_TLS_SRP + CLONE_STRING(username); + CLONE_STRING(password); +@@ -282,9 +292,14 @@ static void free_primary_ssl_config(struct ssl_primary_config *sslc) + Curl_safefree(sslc->cert_blob); + Curl_safefree(sslc->ca_info_blob); + Curl_safefree(sslc->issuercert_blob); ++ Curl_safefree(sslc->key_blob); + Curl_safefree(sslc->curves); + Curl_safefree(sslc->signature_algorithms); + Curl_safefree(sslc->CRLfile); ++ Curl_safefree(sslc->cert_type); ++ Curl_safefree(sslc->key); ++ Curl_safefree(sslc->key_type); ++ Curl_safefree(sslc->key_passwd); + #ifdef USE_TLS_SRP + Curl_safefree(sslc->username); + Curl_safefree(sslc->password); +@@ -336,12 +351,12 @@ CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data) + sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; + sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; + #endif +- sslc->cert_type = data->set.str[STRING_CERT_TYPE]; +- sslc->key = data->set.str[STRING_KEY]; +- sslc->key_type = data->set.str[STRING_KEY_TYPE]; +- sslc->key_passwd = data->set.str[STRING_KEY_PASSWD]; ++ sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE]; ++ sslc->primary.key = data->set.str[STRING_KEY]; ++ sslc->primary.key_type = data->set.str[STRING_KEY_TYPE]; ++ sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD]; + sslc->primary.clientcert = data->set.str[STRING_CERT]; +- sslc->key_blob = data->set.blobs[BLOB_KEY]; ++ sslc->primary.key_blob = data->set.blobs[BLOB_KEY]; + + #ifndef CURL_DISABLE_PROXY + sslc = &data->set.proxy_ssl; +@@ -377,12 +392,12 @@ CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data) + sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; + sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; +- sslc->cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; +- sslc->key = data->set.str[STRING_KEY_PROXY]; +- sslc->key_type = data->set.str[STRING_KEY_TYPE_PROXY]; +- sslc->key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; ++ sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; ++ sslc->primary.key = data->set.str[STRING_KEY_PROXY]; ++ sslc->primary.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; ++ sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; + sslc->primary.clientcert = data->set.str[STRING_CERT_PROXY]; +- sslc->key_blob = data->set.blobs[BLOB_KEY_PROXY]; ++ sslc->primary.key_blob = data->set.blobs[BLOB_KEY_PROXY]; + #ifdef USE_TLS_SRP + sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; + sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; +diff --git a/lib/vtls/vtls_scache.c b/lib/vtls/vtls_scache.c +index 673abcfe0d..75e5b89553 100644 +--- a/lib/vtls/vtls_scache.c ++++ b/lib/vtls/vtls_scache.c +@@ -50,6 +50,7 @@ + struct Curl_ssl_scache_peer { + char *ssl_peer_key; /* id for peer + relevant TLS configuration */ + char *clientcert; ++ char *key_passwd; + char *srp_username; + char *srp_password; + struct Curl_llist sessions; +@@ -123,6 +124,48 @@ out: + return r; + } + ++static CURLcode cf_ssl_peer_key_add_mtls(struct dynbuf *buf, ++ struct ssl_primary_config *ssl, ++ bool *is_local) ++{ ++ CURLcode result = CURLE_OK; ++ if(ssl->clientcert && ssl->clientcert[0]) { ++ result = cf_ssl_peer_key_add_path(buf, "CCERT", ssl->clientcert, is_local); ++ if(result) ++ goto out; ++ } ++ if(ssl->key && ssl->key[0]) { ++ result = cf_ssl_peer_key_add_path(buf, "KEY", ssl->key, is_local); ++ if(result) ++ goto out; ++ } ++ if(ssl->key_blob) { ++ result = cf_ssl_peer_key_add_hash(buf, "KEYBlob", ssl->key_blob); ++ if(result) ++ goto out; ++ } ++ if(ssl->cert_type && ssl->cert_type[0]) { ++ size_t i; ++ result = curlx_dyn_add(buf, ":CT-"); ++ for(i = 0; !result && ssl->cert_type[i]; i++) { ++ char c = Curl_raw_toupper(ssl->cert_type[i]); ++ result = curlx_dyn_addn(buf, &c, 1); ++ } ++ if(result) ++ goto out; ++ } ++ if(ssl->key_type && ssl->key_type[0]) { ++ size_t i; ++ result = curlx_dyn_add(buf, ":KT-"); ++ for(i = 0; !result && ssl->key_type[i]; i++) { ++ char c = Curl_raw_toupper(ssl->key_type[i]); ++ result = curlx_dyn_addn(buf, &c, 1); ++ } ++ } ++out: ++ return result; ++} ++ + #define CURL_SSLS_LOCAL_SUFFIX ":L" + #define CURL_SSLS_GLOBAL_SUFFIX ":G" + +@@ -134,12 +177,12 @@ static bool cf_ssl_peer_key_is_global(const char *peer_key) + (peer_key[len - 2] == ':'); + } + +-CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, +- const struct ssl_peer *peer, +- const char *tls_id, +- char **ppeer_key) ++CURLcode Curl_ssl_peer_key_build(struct ssl_primary_config *ssl, ++ const struct ssl_peer *peer, ++ const struct connectdata *conn, ++ const char *tls_id, ++ char **ppeer_key) + { +- struct ssl_primary_config *ssl = Curl_ssl_cf_get_primary_config(cf); + struct dynbuf buf; + size_t key_len; + bool is_local = FALSE; +@@ -187,13 +230,13 @@ CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, + goto out; + } + if(!ssl->verifypeer || !ssl->verifyhost) { +- if(cf->conn->bits.conn_to_host) { +- r = curlx_dyn_addf(&buf, ":CHOST-%s", cf->conn->conn_to_host.name); ++ if(conn && conn->bits.conn_to_host) { ++ r = curlx_dyn_addf(&buf, ":CHOST-%s", conn->conn_to_host.name); + if(r) + goto out; + } +- if(cf->conn->bits.conn_to_port) { +- r = curlx_dyn_addf(&buf, ":CPORT-%d", cf->conn->conn_to_port); ++ if(conn && conn->bits.conn_to_port) { ++ r = curlx_dyn_addf(&buf, ":CPORT-%d", conn->conn_to_port); + if(r) + goto out; + } +@@ -260,11 +303,9 @@ CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, + goto out; + } + +- if(ssl->clientcert && ssl->clientcert[0]) { +- r = curlx_dyn_add(&buf, ":CCERT"); +- if(r) +- goto out; +- } ++ r = cf_ssl_peer_key_add_mtls(&buf, ssl, &is_local); ++ if(r) ++ goto out; + #ifdef USE_TLS_SRP + if(ssl->username || ssl->password) { + r = curlx_dyn_add(&buf, ":SRP-AUTH"); +@@ -295,6 +336,15 @@ out: + return r; + } + ++CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, ++ const struct ssl_peer *peer, ++ const char *tls_id, ++ char **ppeer_key) ++{ ++ struct ssl_primary_config *ssl = Curl_ssl_cf_get_primary_config(cf); ++ return Curl_ssl_peer_key_build(ssl, peer, cf->conn, tls_id, ppeer_key); ++} ++ + struct Curl_ssl_scache { + unsigned int magic; + struct Curl_ssl_scache_peer *peers; +@@ -402,6 +452,7 @@ static void cf_ssl_scache_clear_peer(struct Curl_ssl_scache_peer *peer) + } + peer->sobj_free = NULL; + Curl_safefree(peer->clientcert); ++ Curl_safefree(peer->key_passwd); + #ifdef USE_TLS_SRP + Curl_safefree(peer->srp_username); + Curl_safefree(peer->srp_password); +@@ -430,8 +481,8 @@ static void cf_ssl_cache_peer_update(struct Curl_ssl_scache_peer *peer) + * - its peer key is not yet known, because sessions were + * imported using only the salt+hmac + * - the peer key is global, e.g. carrying no relative paths */ +- peer->exportable = (!peer->clientcert && !peer->srp_username && +- !peer->srp_password && ++ peer->exportable = (!peer->clientcert && !peer->key_passwd && ++ !peer->srp_username && !peer->srp_password && + (!peer->ssl_peer_key || + cf_ssl_peer_key_is_global(peer->ssl_peer_key))); + } +@@ -440,6 +491,7 @@ static CURLcode + cf_ssl_scache_peer_init(struct Curl_ssl_scache_peer *peer, + const char *ssl_peer_key, + const char *clientcert, ++ const char *key_passwd, + const char *srp_username, + const char *srp_password, + const unsigned char *salt, +@@ -468,6 +520,11 @@ cf_ssl_scache_peer_init(struct Curl_ssl_scache_peer *peer, + if(!peer->clientcert) + goto out; + } ++ if(key_passwd) { ++ peer->key_passwd = curlx_strdup(key_passwd); ++ if(!peer->key_passwd) ++ goto out; ++ } + if(srp_username) { + peer->srp_username = curlx_strdup(srp_username); + if(!peer->srp_username) +@@ -598,7 +655,7 @@ static bool cf_ssl_scache_match_auth(struct Curl_ssl_scache_peer *peer, + struct ssl_primary_config *conn_config) + { + if(!conn_config) { +- if(peer->clientcert) ++ if(peer->clientcert || peer->key_passwd) + return FALSE; + #ifdef USE_TLS_SRP + if(peer->srp_username || peer->srp_password) +@@ -608,6 +665,8 @@ static bool cf_ssl_scache_match_auth(struct Curl_ssl_scache_peer *peer, + } + else if(!Curl_safecmp(peer->clientcert, conn_config->clientcert)) + return FALSE; ++ if(Curl_timestrcmp(peer->key_passwd, conn_config->key_passwd)) ++ return FALSE; + #ifdef USE_TLS_SRP + if(Curl_timestrcmp(peer->srp_username, conn_config->username) || + Curl_timestrcmp(peer->srp_password, conn_config->password)) +@@ -734,13 +793,21 @@ static CURLcode cf_ssl_add_peer(struct Curl_easy *data, + + peer = cf_ssl_get_free_peer(scache); + if(peer) { ++ char buffer[64]; + const char *ccert = conn_config ? conn_config->clientcert : NULL; ++ const char *kpasswd = conn_config ? conn_config->key_passwd : NULL; + const char *username = NULL, *password = NULL; + #ifdef USE_TLS_SRP + username = conn_config ? conn_config->username : NULL; + password = conn_config ? conn_config->password : NULL; + #endif +- result = cf_ssl_scache_peer_init(peer, ssl_peer_key, ccert, ++ if(!ccert && conn_config && conn_config->cert_blob) { ++ /* when using a client cert blob, create a name for it */ ++ curl_msnprintf(buffer, sizeof(buffer), ++ "cert-%p", conn_config->cert_blob->data); ++ ccert = buffer; /* data is strduped by cf_ssl_scache_peer_init */ ++ } ++ result = cf_ssl_scache_peer_init(peer, ssl_peer_key, ccert, kpasswd, + username, password, NULL, NULL); + if(result) + goto out; +@@ -1115,7 +1182,7 @@ CURLcode Curl_ssl_session_import(struct Curl_easy *data, + if(!peer) { + peer = cf_ssl_get_free_peer(scache); + if(peer) { +- r = cf_ssl_scache_peer_init(peer, ssl_peer_key, NULL, ++ r = cf_ssl_scache_peer_init(peer, ssl_peer_key, NULL, NULL, + NULL, NULL, salt, hmac); + if(r) + goto out; +diff --git a/lib/vtls/vtls_scache.h b/lib/vtls/vtls_scache.h +index b9db0f19b3..d33f2bb1a7 100644 +--- a/lib/vtls/vtls_scache.h ++++ b/lib/vtls/vtls_scache.h +@@ -66,6 +66,22 @@ CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, + const char *tls_id, + char **ppeer_key); + ++/** ++ * Like Curl_ssl_peer_key_make() but takes the primary config and peer ++ * descriptors directly, without requiring a Curl_cfilter. Exposed for ++ * unit testing. ++ * @param ssl the primary SSL config to key on ++ * @param peer the peer the filter wants to talk to ++ * @param conn connection data for connect-to keying, or NULL ++ * @param tls_id identifier of TLS implementation for sessions ++ * @param ppeer_key on successful return, the key generated ++ */ ++CURLcode Curl_ssl_peer_key_build(struct ssl_primary_config *ssl, ++ const struct ssl_peer *peer, ++ const struct connectdata *conn, ++ const char *tls_id, ++ char **ppeer_key); ++ + /* Return if there is a session cache shall be used. + * An ssl session might not be configured or not available for + * "connect-only" transfers. +diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c +index aa841a754a..74bd247e68 100644 +--- a/lib/vtls/wolfssl.c ++++ b/lib/vtls/wolfssl.c +@@ -919,10 +919,10 @@ static CURLcode client_certificate(struct Curl_easy *data, + #ifndef NO_FILESYSTEM + if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) { + const char *cert_file = ssl_config->primary.clientcert; +- const char *key_file = ssl_config->key; ++ const char *key_file = ssl_config->primary.key; + const struct curl_blob *cert_blob = ssl_config->primary.cert_blob; +- const struct curl_blob *key_blob = ssl_config->key_blob; +- int file_type = wssl_do_file_type(ssl_config->cert_type); ++ const struct curl_blob *key_blob = ssl_config->primary.key_blob; ++ int file_type = wssl_do_file_type(ssl_config->primary.cert_type); + int rc; + + switch(file_type) { +@@ -953,7 +953,7 @@ static CURLcode client_certificate(struct Curl_easy *data, + key_file = cert_file; + } + else +- file_type = wssl_do_file_type(ssl_config->key_type); ++ file_type = wssl_do_file_type(ssl_config->primary.key_type); + + rc = key_blob ? + wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data, +@@ -967,8 +967,8 @@ static CURLcode client_certificate(struct Curl_easy *data, + #else /* NO_FILESYSTEM */ + if(ssl_config->primary.cert_blob) { + const struct curl_blob *cert_blob = ssl_config->primary.cert_blob; +- const struct curl_blob *key_blob = ssl_config->key_blob; +- int file_type = wssl_do_file_type(ssl_config->cert_type); ++ const struct curl_blob *key_blob = ssl_config->primary.key_blob; ++ int file_type = wssl_do_file_type(ssl_config->primary.cert_type); + int rc; + + switch(file_type) { +@@ -993,7 +993,7 @@ static CURLcode client_certificate(struct Curl_easy *data, + if(!key_blob) + key_blob = cert_blob; + else +- file_type = wssl_do_file_type(ssl_config->key_type); ++ file_type = wssl_do_file_type(ssl_config->primary.key_type); + + if(wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data, + (long)key_blob->len, +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 4fd7dfe912..2217666382 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -282,6 +282,9 @@ test3100 test3101 test3102 test3103 test3104 test3105 \ + \ + test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 \ + test3209 test3210 test3211 test3212 test3213 test3214 test3215 test3216 \ ++\ ++test3303 test3304 \ ++\ + test4000 test4001 + + EXTRA_DIST = $(TESTCASES) DISABLED data-xml1 data320.html \ +diff --git a/tests/data/test3303 b/tests/data/test3303 +new file mode 100644 +index 0000000000..697049f013 +--- /dev/null ++++ b/tests/data/test3303 +@@ -0,0 +1,20 @@ ++<?xml version="1.0" encoding="US-ASCII"?> ++<testcase> ++<info> ++<keywords> ++unittest ++TLS ++mTLS ++</keywords> ++</info> ++ ++# Client-side ++<client> ++<features> ++unittest ++</features> ++<name> ++conn-reuse match distinguishes mTLS key, cert_type, key_type and key_passwd fields ++</name> ++</client> ++</testcase> +diff --git a/tests/data/test3304 b/tests/data/test3304 +new file mode 100644 +index 0000000000..4380c0819f +--- /dev/null ++++ b/tests/data/test3304 +@@ -0,0 +1,20 @@ ++<?xml version="1.0" encoding="US-ASCII"?> ++<testcase> ++<info> ++<keywords> ++unittest ++TLS ++mTLS ++</keywords> ++</info> ++ ++# Client-side ++<client> ++<features> ++unittest ++</features> ++<name> ++TLS session cache peer key discriminates on mTLS key, key_type and cert_type fields ++</name> ++</client> ++</testcase> +diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc +index 149636cbcc..bba30f6706 100644 +--- a/tests/unit/Makefile.inc ++++ b/tests/unit/Makefile.inc +@@ -43,4 +43,5 @@ TESTS_C = \ + unit1979.c unit1980.c \ + unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c \ + unit3200.c unit3205.c \ +- unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c ++ unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c \ ++ unit3303.c unit3304.c +diff --git a/tests/unit/unit3303.c b/tests/unit/unit3303.c +new file mode 100644 +index 0000000000..41bced542d +--- /dev/null ++++ b/tests/unit/unit3303.c +@@ -0,0 +1,127 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at https://curl.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ * SPDX-License-Identifier: curl ++ * ++ ***************************************************************************/ ++#include "unitcheck.h" ++#include "urldata.h" ++ ++#ifdef USE_SSL ++#include "vtls/vtls.h" ++#endif ++ ++static CURLcode test_unit3303(const char *arg) ++{ ++ UNITTEST_BEGIN_SIMPLE ++ ++#ifdef USE_SSL ++ { ++ CURL *curl; ++ struct connectdata *conn; ++ struct ssl_primary_config *primary; ++ char *saved; ++ static char alt_passwd[] = "wrong"; ++ static char alt_key[] = "other.key"; ++ static char alt_ktype[] = "DER"; ++ static char alt_ctype[] = "P12"; ++ ++ curl_global_init(CURL_GLOBAL_ALL); ++ curl = curl_easy_init(); ++ if(!curl) { ++ curl_global_cleanup(); ++ goto unit_test_abort; ++ } ++ ++ curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); ++ curl_easy_setopt(curl, CURLOPT_SSLKEY, "client.key"); ++ curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "secret"); ++ curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); ++ curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); ++ ++ if(Curl_ssl_easy_config_complete((struct Curl_easy *)curl)) { ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ goto unit_test_abort; ++ } ++ ++ conn = curlx_calloc(1, sizeof(*conn)); ++ if(!conn || Curl_ssl_conn_config_init((struct Curl_easy *)curl, conn)) { ++ if(conn) ++ Curl_ssl_conn_config_cleanup(conn); ++ curlx_free(conn); ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ goto unit_test_abort; ++ } ++ ++ /* Baseline: identical config must match. */ ++ fail_unless(Curl_ssl_conn_config_match((struct Curl_easy *)curl, conn, ++ FALSE), ++ "identical mTLS config should match"); ++ ++ primary = &((struct Curl_easy *)curl)->set.ssl.primary; ++ ++ /* Different key_passwd must not match. */ ++ saved = primary->key_passwd; ++ primary->key_passwd = alt_passwd; ++ fail_unless(!Curl_ssl_conn_config_match((struct Curl_easy *)curl, conn, ++ FALSE), ++ "different key_passwd must not reuse conn"); ++ primary->key_passwd = saved; ++ ++ /* Different key path must not match. */ ++ saved = primary->key; ++ primary->key = alt_key; ++ fail_unless(!Curl_ssl_conn_config_match((struct Curl_easy *)curl, conn, ++ FALSE), ++ "different key must not reuse conn"); ++ primary->key = saved; ++ ++ /* Different key type must not match. */ ++ saved = primary->key_type; ++ primary->key_type = alt_ktype; ++ fail_unless(!Curl_ssl_conn_config_match((struct Curl_easy *)curl, conn, ++ FALSE), ++ "different key_type must not reuse conn"); ++ primary->key_type = saved; ++ ++ /* Different cert type must not match. */ ++ saved = primary->cert_type; ++ primary->cert_type = alt_ctype; ++ fail_unless(!Curl_ssl_conn_config_match((struct Curl_easy *)curl, conn, ++ FALSE), ++ "different cert_type must not reuse conn"); ++ primary->cert_type = saved; ++ ++ /* All fields restored: must match again. */ ++ fail_unless(Curl_ssl_conn_config_match((struct Curl_easy *)curl, conn, ++ FALSE), ++ "restored mTLS config should match"); ++ ++ Curl_ssl_conn_config_cleanup(conn); ++ curlx_free(conn); ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ } ++#endif /* USE_SSL */ ++ ++ UNITTEST_END_SIMPLE ++} +diff --git a/tests/unit/unit3304.c b/tests/unit/unit3304.c +new file mode 100644 +index 0000000000..4defa1e426 +--- /dev/null ++++ b/tests/unit/unit3304.c +@@ -0,0 +1,163 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at https://curl.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ * SPDX-License-Identifier: curl ++ * ++ ***************************************************************************/ ++ ++/* Unit tests for TLS session cache peer key discrimination on mTLS fields. ++ * Verifies that Curl_ssl_peer_key_build() produces distinct keys when two ++ * handles differ only on key, key_type or cert_type. key_passwd is NOT ++ * embedded in the peer key; it is compared separately at session lookup via ++ * cf_ssl_scache_match_auth(), following the same pattern as SRP ++ * credentials. */ ++ ++#include "unitcheck.h" ++#include "urldata.h" ++ ++#ifdef USE_SSL ++#include "vtls/vtls.h" ++#include "vtls/vtls_scache.h" ++#endif ++ ++static CURLcode test_unit3304(const char *arg) ++{ ++ UNITTEST_BEGIN_SIMPLE ++ ++#ifdef USE_SSL ++ { ++ struct ssl_peer peer; ++ struct ssl_primary_config ssl; ++ char *key1 = NULL; ++ char *key2 = NULL; ++ static char base_hostname[] = "example.com"; ++ static char base_cert[] = "client.pem"; ++ static char base_key[] = "client.key"; ++ static char base_passwd[] = "secret"; ++ static char base_ctype[] = "PEM"; ++ static char base_ktype[] = "PEM"; ++ static char alt_key[] = "other.key"; ++ static char alt_ktype[] = "DER"; ++ static char alt_ctype[] = "P12"; ++ static char lc_ctype[] = "pem"; ++ static char lc_ktype[] = "pem"; ++ ++ memset(&peer, 0, sizeof(peer)); ++ peer.hostname = base_hostname; ++ peer.port = 443; ++ peer.transport = TRNSPRT_TCP; ++ ++ memset(&ssl, 0, sizeof(ssl)); ++ ssl.verifypeer = TRUE; ++ ssl.verifyhost = TRUE; ++ ssl.clientcert = base_cert; ++ ssl.key = base_key; ++ ssl.key_passwd = base_passwd; ++ ssl.cert_type = base_ctype; ++ ssl.key_type = base_ktype; ++ ++ /* Baseline: same config produces same key. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && !strcmp(key1, key2), ++ "identical config should produce identical peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ ++ /* key_passwd is NOT in the peer key: lookup uses timing-safe comparison ++ * via cf_ssl_scache_match_auth(), same as SRP credentials. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ ssl.key_passwd = NULL; ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && !strcmp(key1, key2), ++ "key_passwd must not affect the peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ ssl.key_passwd = base_passwd; ++ ++ /* Different key path must produce a different peer key. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ ssl.key = alt_key; ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && strcmp(key1, key2), ++ "different key must produce different peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ ssl.key = base_key; ++ ++ /* Different key_type must produce a different peer key. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ ssl.key_type = alt_ktype; ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && strcmp(key1, key2), ++ "different key_type must produce different peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ ssl.key_type = base_ktype; ++ ++ /* Different cert_type must produce a different peer key. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ ssl.cert_type = alt_ctype; ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && strcmp(key1, key2), ++ "different cert_type must produce different peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ ssl.cert_type = base_ctype; ++ ++ /* cert_type is case-insensitive: "PEM" and "pem" must produce the ++ * same peer key, consistent with the conn-reuse comparison. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ ssl.cert_type = lc_ctype; ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && !strcmp(key1, key2), ++ "cert_type case must not affect peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ ssl.cert_type = base_ctype; ++ ++ /* key_type is case-insensitive: "PEM" and "pem" must produce the ++ * same peer key. */ ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key1), ++ "peer key build failed"); ++ ssl.key_type = lc_ktype; ++ fail_unless(!Curl_ssl_peer_key_build(&ssl, &peer, NULL, "test", &key2), ++ "peer key build failed"); ++ fail_unless(key1 && key2 && !strcmp(key1, key2), ++ "key_type case must not affect peer key"); ++ curlx_free(key1); key1 = NULL; ++ curlx_free(key2); key2 = NULL; ++ } ++#endif /* USE_SSL */ ++ ++ UNITTEST_END_SIMPLE ++} +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index 193366f657..994b1cff28 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -25,6 +25,8 @@ SRC_URI = " \ file://CVE-2026-4873.patch \ file://CVE-2026-8286.patch \ file://CVE-2026-8927.patch \ + file://CVE-2026-8932-dependent.patch \ + file://CVE-2026-8932.patch \ " SRC_URI:append:class-nativesdk = " \ -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 5/8] curl: fix CVE-2026-8458 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (3 preceding siblings ...) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 4/8] curl: fix CVE-2026-8932 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-28 15:07 ` Yoann Congal 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (2 subsequent siblings) 7 siblings, 1 reply; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> This patch applies the upstream curl security fix backport for CVE-2026-8458. The upstream fix commit is referenced in [1], and the public curl advisory is referenced in [2]. The backported commit link is also recorded in the embedded patch header. [1] https://github.com/curl/curl/commit/5e99b73cf441d9c369768b9cd48b5389b9a2503d [2] https://curl.se/docs/CVE-2026-8458.html Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- .../curl/curl/CVE-2026-8458.patch | 202 ++++++++++++++++++ meta/recipes-support/curl/curl_8.19.0.bb | 1 + 2 files changed, 203 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8458.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-8458.patch b/meta/recipes-support/curl/curl/CVE-2026-8458.patch new file mode 100644 index 0000000000..6340f5305f --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-8458.patch @@ -0,0 +1,202 @@ +From 01ce94b67888e6efa4196247302e59cf68e77b2d Mon Sep 17 00:00:00 2001 +From: Stefan Eissing <stefan@eissing.org> +Date: Mon, 13 Jul 2026 23:13:37 -0700 +Subject: [PATCH] creds: add sasl service name + +The SASL service name, used in authentication, is part of curl's credentials +when authenticating to a server/proxy. Make it part of `struct Curl_creds`. + +Change code to use `creds` to obtain a service name. By tying creds used +to the connection, connection reuse is also only allowed when the service +name matches. + +Closes #21585 + +CVE: CVE-2026-8458 +Upstream-Status: Backport [https://github.com/curl/curl/commit/5e99b73cf441d9c369768b9cd48b5389b9a2503d] + +Backport Changes: +- Wrynose curl 8.19.0 does not have upstream struct Curl_creds. + This backport stores the optional SASL service name on the existing + connectdata/proxy_info structures and compares it during connection + reuse for the same security behavior. +- Omitted the upstream unit1304 Curl_creds_create() signature + adjustment because Wrynose 8.19.0 does not contain Curl_creds. + +(cherry picked from commit 5e99b73cf441d9c369768b9cd48b5389b9a2503d) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/url.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++----- + lib/urldata.h | 2 ++ + 2 files changed, 58 insertions(+), 5 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 6c1375f8e3..35f467daf2 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -535,12 +535,15 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn) + Curl_safefree(conn->socks_proxy.user); + Curl_safefree(conn->http_proxy.passwd); + Curl_safefree(conn->socks_proxy.passwd); ++ Curl_safefree(conn->http_proxy.sasl_service_name); ++ Curl_safefree(conn->socks_proxy.sasl_service_name); + Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ + Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ + #endif + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + Curl_safefree(conn->sasl_authzid); ++ Curl_safefree(conn->sasl_service_name); + Curl_safefree(conn->options); + Curl_safefree(conn->oauth_bearer); + Curl_safefree(conn->host.rawalloc); /* hostname buffer */ +@@ -593,7 +596,9 @@ static bool proxy_info_matches(const struct proxy_info *data, + curl_strequal(data->host.name, needle->host.name)) { + + if(Curl_timestrcmp(data->user, needle->user) || +- Curl_timestrcmp(data->passwd, needle->passwd)) ++ Curl_timestrcmp(data->passwd, needle->passwd) || ++ Curl_timestrcmp(data->sasl_service_name, ++ needle->sasl_service_name)) + return FALSE; + return TRUE; + } +@@ -1035,6 +1040,8 @@ static bool url_match_auth(struct connectdata *conn, + if(Curl_timestrcmp(m->needle->user, conn->user) || + Curl_timestrcmp(m->needle->passwd, conn->passwd) || + Curl_timestrcmp(m->needle->sasl_authzid, conn->sasl_authzid) || ++ Curl_timestrcmp(m->needle->sasl_service_name, ++ conn->sasl_service_name) || + Curl_timestrcmp(m->needle->oauth_bearer, conn->oauth_bearer)) { + /* one of them was different */ + return FALSE; +@@ -1116,7 +1123,9 @@ static bool url_match_auth_ntlm(struct connectdata *conn, + partway through a handshake!) */ + if(m->want_ntlm_http) { + if(Curl_timestrcmp(m->needle->user, conn->user) || +- Curl_timestrcmp(m->needle->passwd, conn->passwd)) { ++ Curl_timestrcmp(m->needle->passwd, conn->passwd) || ++ Curl_timestrcmp(m->needle->sasl_service_name, ++ conn->sasl_service_name)) { + /* we prefer a credential match, but this is at least a connection + that can be reused and "upgraded" to NTLM if it does + not have any auth ongoing. */ +@@ -1147,7 +1156,9 @@ static bool url_match_auth_ntlm(struct connectdata *conn, + if(Curl_timestrcmp(m->needle->http_proxy.user, + conn->http_proxy.user) || + Curl_timestrcmp(m->needle->http_proxy.passwd, +- conn->http_proxy.passwd)) ++ conn->http_proxy.passwd) || ++ Curl_timestrcmp(m->needle->http_proxy.sasl_service_name, ++ conn->http_proxy.sasl_service_name)) + return FALSE; + } + else if(conn->proxy_ntlm_state != NTLMSTATE_NONE) { +@@ -1188,7 +1199,9 @@ static bool url_match_auth_nego(struct connectdata *conn, + so that we can reuse Negotiate connections if possible. */ + if(m->want_nego_http) { + if(Curl_timestrcmp(m->needle->user, conn->user) || +- Curl_timestrcmp(m->needle->passwd, conn->passwd)) ++ Curl_timestrcmp(m->needle->passwd, conn->passwd) || ++ Curl_timestrcmp(m->needle->sasl_service_name, ++ conn->sasl_service_name)) + return FALSE; + } + else if(conn->http_negotiate_state != GSS_AUTHNONE) { +@@ -1207,7 +1220,9 @@ static bool url_match_auth_nego(struct connectdata *conn, + if(Curl_timestrcmp(m->needle->http_proxy.user, + conn->http_proxy.user) || + Curl_timestrcmp(m->needle->http_proxy.passwd, +- conn->http_proxy.passwd)) ++ conn->http_proxy.passwd) || ++ Curl_timestrcmp(m->needle->http_proxy.sasl_service_name, ++ conn->http_proxy.sasl_service_name)) + return FALSE; + } + else if(conn->proxy_negotiate_state != GSS_AUTHNONE) { +@@ -3196,6 +3211,11 @@ static void url_conn_reuse_adjust(struct Curl_easy *data, + needle->user = NULL; + needle->passwd = NULL; + } ++ if(needle->sasl_service_name) { ++ curlx_free(conn->sasl_service_name); ++ conn->sasl_service_name = needle->sasl_service_name; ++ needle->sasl_service_name = NULL; ++ } + + #ifndef CURL_DISABLE_PROXY + conn->bits.proxy_user_passwd = needle->bits.proxy_user_passwd; +@@ -3214,6 +3234,17 @@ static void url_conn_reuse_adjust(struct Curl_easy *data, + needle->http_proxy.passwd = NULL; + needle->socks_proxy.passwd = NULL; + } ++ if(needle->http_proxy.sasl_service_name || ++ needle->socks_proxy.sasl_service_name) { ++ curlx_free(conn->http_proxy.sasl_service_name); ++ curlx_free(conn->socks_proxy.sasl_service_name); ++ conn->http_proxy.sasl_service_name = ++ needle->http_proxy.sasl_service_name; ++ conn->socks_proxy.sasl_service_name = ++ needle->socks_proxy.sasl_service_name; ++ needle->http_proxy.sasl_service_name = NULL; ++ needle->socks_proxy.sasl_service_name = NULL; ++ } + #endif + + /* Finding a connection for reuse in the cpool matches, among other +@@ -3283,6 +3314,15 @@ static CURLcode url_create_needle(struct Curl_easy *data, + } + } + ++ if(data->set.str[STRING_SERVICE_NAME]) { ++ needle->sasl_service_name = ++ curlx_strdup(data->set.str[STRING_SERVICE_NAME]); ++ if(!needle->sasl_service_name) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } ++ } ++ + if(data->set.str[STRING_BEARER]) { + needle->oauth_bearer = curlx_strdup(data->set.str[STRING_BEARER]); + if(!needle->oauth_bearer) { +@@ -3310,6 +3350,17 @@ static CURLcode url_create_needle(struct Curl_easy *data, + if(result) + goto out; + ++ if(data->set.str[STRING_PROXY_SERVICE_NAME]) { ++ result = Curl_setstropt(&needle->http_proxy.sasl_service_name, ++ data->set.str[STRING_PROXY_SERVICE_NAME]); ++ if(result) ++ goto out; ++ result = Curl_setstropt(&needle->socks_proxy.sasl_service_name, ++ data->set.str[STRING_PROXY_SERVICE_NAME]); ++ if(result) ++ goto out; ++ } ++ + /************************************************************* + * If the protocol is using SSL and HTTP proxy is used, we set + * the tunnel_proxy bit. +diff --git a/lib/urldata.h b/lib/urldata.h +index 6c6c83969c..1c369a54f2 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -586,6 +586,7 @@ struct proxy_info { + uint8_t proxytype; /* what kind of proxy that is in use */ + char *user; /* proxy username string, allocated */ + char *passwd; /* proxy password string, allocated */ ++ char *sasl_service_name; /* SASL service name, allocated */ + }; + + /* +@@ -628,6 +629,7 @@ struct connectdata { + char *passwd; /* password string, allocated */ + char *options; /* options string, allocated */ + char *sasl_authzid; /* authorization identity string, allocated */ ++ char *sasl_service_name; /* SASL service name, allocated */ + char *oauth_bearer; /* OAUTH2 bearer, allocated */ + struct curltime created; /* creation time */ + struct curltime lastused; /* when returned to the connection poolas idle */ +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index 994b1cff28..33ccb73eb3 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -27,6 +27,7 @@ SRC_URI = " \ file://CVE-2026-8927.patch \ file://CVE-2026-8932-dependent.patch \ file://CVE-2026-8932.patch \ + file://CVE-2026-8458.patch \ " SRC_URI:append:class-nativesdk = " \ -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 5/8] curl: fix CVE-2026-8458 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 5/8] curl: fix CVE-2026-8458 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-28 15:07 ` Yoann Congal 0 siblings, 0 replies; 16+ messages in thread From: Yoann Congal @ 2026-08-28 15:07 UTC (permalink / raw) To: deeratho, openembedded-core On Wed Aug 5, 2026 at 10:31 AM CEST, Deepak Rathore via lists.openembedded.org wrote: > From: Deepak Rathore <deeratho@cisco.com> > > This patch applies the upstream curl security fix backport for > CVE-2026-8458. The upstream fix commit is referenced in [1], > and the public curl advisory is referenced in [2]. The backported > commit link is also recorded in the embedded patch header. > > [1] https://github.com/curl/curl/commit/5e99b73cf441d9c369768b9cd48b5389b9a2503d > [2] https://curl.se/docs/CVE-2026-8458.html > > Signed-off-by: Deepak Rathore <deeratho@cisco.com> > --- > .../curl/curl/CVE-2026-8458.patch | 202 ++++++++++++++++++ > meta/recipes-support/curl/curl_8.19.0.bb | 1 + > 2 files changed, 203 insertions(+) > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-8458.patch > > diff --git a/meta/recipes-support/curl/curl/CVE-2026-8458.patch b/meta/recipes-support/curl/curl/CVE-2026-8458.patch > new file mode 100644 > index 0000000000..6340f5305f > --- /dev/null > +++ b/meta/recipes-support/curl/curl/CVE-2026-8458.patch > @@ -0,0 +1,202 @@ > +From 01ce94b67888e6efa4196247302e59cf68e77b2d Mon Sep 17 00:00:00 2001 > +From: Stefan Eissing <stefan@eissing.org> > +Date: Mon, 13 Jul 2026 23:13:37 -0700 > +Subject: [PATCH] creds: add sasl service name > + > +The SASL service name, used in authentication, is part of curl's credentials > +when authenticating to a server/proxy. Make it part of `struct Curl_creds`. > + > +Change code to use `creds` to obtain a service name. By tying creds used > +to the connection, connection reuse is also only allowed when the service > +name matches. > + > +Closes #21585 > + > +CVE: CVE-2026-8458 > +Upstream-Status: Backport [https://github.com/curl/curl/commit/5e99b73cf441d9c369768b9cd48b5389b9a2503d] > + > +Backport Changes: > +- Wrynose curl 8.19.0 does not have upstream struct Curl_creds. > + This backport stores the optional SASL service name on the existing > + connectdata/proxy_info structures and compares it during connection > + reuse for the same security behavior. > +- Omitted the upstream unit1304 Curl_creds_create() signature > + adjustment because Wrynose 8.19.0 does not contain Curl_creds. > + > +(cherry picked from commit 5e99b73cf441d9c369768b9cd48b5389b9a2503d) > +Signed-off-by: Deepak Rathore <deeratho@cisco.com> > +--- > + lib/url.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++----- > + lib/urldata.h | 2 ++ > + 2 files changed, 58 insertions(+), 5 deletions(-) This patch looks nothing like the upstream patch and is basically new code. I'm not confortable merging this. I'll hold this one for now and continue with the rest of the series. Regards, -- Yoann Congal Smile ECS ^ permalink raw reply [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (4 preceding siblings ...) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 5/8] curl: fix CVE-2026-8458 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-28 15:24 ` Yoann Congal 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 7/8] curl: set CVE_STATUS for CVE-2026-9547 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 8/8] curl: set CVE_STATUS for CVE-2026-12064 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 7 siblings, 1 reply; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> This patch applies the upstream curl security backports for CVE-2026-11856. The main fix commit is referenced in [1], the Digest proxy-state follow-up is referenced in [2], and the public curl advisory is referenced in [3]. The individual backported commit links are recorded in the embedded patch headers. [1] https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535 [2] https://github.com/curl/curl/commit/7ec25148c06b049d3252172ff17fae85b19c54c9 [3] https://curl.se/docs/CVE-2026-11856.html Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- .../curl/curl/CVE-2026-11856_p1.patch | 372 ++++++++++++++++++ .../curl/curl/CVE-2026-11856_p2.patch | 72 ++++ meta/recipes-support/curl/curl_8.19.0.bb | 2 + 3 files changed, 446 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch b/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch new file mode 100644 index 0000000000..80fb18a7c1 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch @@ -0,0 +1,372 @@ +From 3349fbcb7876456cadc3cc3a8d3e8aff29406906 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Mon, 13 Jul 2026 23:17:23 -0700 +Subject: [PATCH] digest: flush state on origin or credential change + +Verified by test 1686 + +Closes #21944 + +CVE: CVE-2026-11856 +Upstream-Status: Backport [https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535] + +Backport Changes: +- Wrynose curl 8.19.0 does not have upstream Curl_peer or + struct Curl_creds. This backport stores the host Digest origin + and user/password on digestdata, then flushes stale host Digest + state before reuse when either value changes. +- Kept Wrynose test-list ordering and added only the upstream + test1686/lib1686 regression coverage. + +(cherry picked from commit 5c6b4880357ab3e72967c1c45cae0f96ffabc535) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/http_digest.c | 50 ++++++++++++++++++++ + lib/urldata.h | 3 ++ + lib/vauth/digest.c | 3 ++ + lib/vauth/digest_sspi.c | 4 ++ + tests/data/Makefile.am | 2 +- + tests/data/test1686 | 84 +++++++++++++++++++++++++++++++++ + tests/libtest/Makefile.inc | 1 + + tests/libtest/lib1686.c | 96 ++++++++++++++++++++++++++++++++++++++ + 8 files changed, 242 insertions(+), 1 deletion(-) + create mode 100644 tests/data/test1686 + create mode 100644 tests/libtest/lib1686.c + +diff --git a/lib/http_digest.c b/lib/http_digest.c +index f5b20c5e9d..29bfa3b0b3 100644 +--- a/lib/http_digest.c ++++ b/lib/http_digest.c +@@ -29,6 +29,7 @@ + #include "strcase.h" + #include "vauth/vauth.h" + #include "http_digest.h" ++#include "curlx/strdup.h" + #include "curlx/strparse.h" + + /* Test example headers: +@@ -38,6 +39,49 @@ Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" + + */ + ++static CURLcode digest_update_origin(struct Curl_easy *data, ++ struct digestdata *digest, ++ const char *userp, ++ const char *passwdp) ++{ ++ char *origin; ++ char *authuser; ++ char *authpasswd; ++ bool flush = FALSE; ++ ++ origin = curl_maprintf("%s:%d:%s", data->conn->scheme->name, ++ data->conn->remote_port, data->conn->host.name); ++ if(!origin) ++ return CURLE_OUT_OF_MEMORY; ++ ++ authuser = curlx_strdup(userp); ++ authpasswd = curlx_strdup(passwdp); ++ if(!authuser || !authpasswd) { ++ curlx_free(origin); ++ curlx_free(authuser); ++ curlx_free(authpasswd); ++ return CURLE_OUT_OF_MEMORY; ++ } ++ ++ if(digest->authorigin && Curl_timestrcmp(digest->authorigin, origin)) ++ flush = TRUE; ++ else if(digest->authuser && Curl_timestrcmp(digest->authuser, userp)) ++ flush = TRUE; ++ else if(digest->authpasswd && Curl_timestrcmp(digest->authpasswd, passwdp)) ++ flush = TRUE; ++ ++ if(flush) ++ Curl_auth_digest_cleanup(digest); ++ ++ Curl_safefree(digest->authorigin); ++ Curl_safefree(digest->authuser); ++ Curl_safefree(digest->authpasswd); ++ digest->authorigin = origin; ++ digest->authuser = authuser; ++ digest->authpasswd = authpasswd; ++ return CURLE_OK; ++} ++ + CURLcode Curl_input_digest(struct Curl_easy *data, + bool proxy, + const char *header) /* rest of the *-authenticate: +@@ -114,6 +158,12 @@ CURLcode Curl_output_digest(struct Curl_easy *data, + if(!passwdp) + passwdp = ""; + ++ if(!proxy) { ++ result = digest_update_origin(data, digest, userp, passwdp); ++ if(result) ++ return result; ++ } ++ + #ifdef USE_WINDOWS_SSPI + have_chlg = !!digest->input_token; + #else +diff --git a/lib/urldata.h b/lib/urldata.h +index 455ed7f996..113f6e7102 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -283,6 +283,9 @@ struct ssl_general_config { + #ifndef CURL_DISABLE_DIGEST_AUTH + /* Struct used for Digest challenge-response authentication */ + struct digestdata { ++ char *authorigin; /* origin used for the host Digest state */ ++ char *authuser; /* user used for the host Digest state */ ++ char *authpasswd; /* password used for the host Digest state */ + #ifdef USE_WINDOWS_SSPI + BYTE *input_token; + size_t input_token_len; +diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c +index 9609390387..1feee07764 100644 +--- a/lib/vauth/digest.c ++++ b/lib/vauth/digest.c +@@ -1028,6 +1028,9 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, + */ + void Curl_auth_digest_cleanup(struct digestdata *digest) + { ++ Curl_safefree(digest->authorigin); ++ Curl_safefree(digest->authuser); ++ Curl_safefree(digest->authpasswd); + Curl_safefree(digest->nonce); + Curl_safefree(digest->cnonce); + Curl_safefree(digest->realm); +diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c +index f29e569cd1..4688a7b5c5 100644 +--- a/lib/vauth/digest_sspi.c ++++ b/lib/vauth/digest_sspi.c +@@ -636,6 +636,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, + */ + void Curl_auth_digest_cleanup(struct digestdata *digest) + { ++ Curl_safefree(digest->authorigin); ++ Curl_safefree(digest->authuser); ++ Curl_safefree(digest->authpasswd); ++ + /* Free the input token */ + Curl_safefree(digest->input_token); + +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index f9d20a9cc8..89eae33ca0 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -226,7 +226,7 @@ test1660 test1661 test1662 test1663 test1664 test1665 \ + \ + test1670 test1671 \ + \ +-test1680 test1681 test1682 test1683 \ ++test1680 test1681 test1682 test1683 test1686 \ + \ + test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \ + test1708 test1709 test1710 test1711 test1712 \ +diff --git a/tests/data/test1686 b/tests/data/test1686 +new file mode 100644 +index 0000000000..2d419ad608 +--- /dev/null ++++ b/tests/data/test1686 +@@ -0,0 +1,84 @@ ++<?xml version="1.0" encoding="US-ASCII"?> ++<testcase> ++<info> ++<keywords> ++HTTP ++Digest ++</keywords> ++</info> ++ ++<reply> ++<data crlf="headers" nocheck="yes"> ++HTTP/1.1 401 Authorization Required ++Server: Apache/1.3.27 (Darwin) PHP/4.1.2 ++WWW-Authenticate: Digest realm="my-backyard", nonce="314156295" ++Content-Length: 26 ++ ++This is not the real page ++</data> ++ ++# This is supposed to be returned when the server gets a ++# Authorization: Digest line passed-in from the client ++<data1000 crlf="headers"> ++HTTP/1.1 200 OK ++Server: Apache/1.3.27 (Darwin) PHP/4.1.2 ++Content-Type: text/html; charset=iso-8859-1 ++Content-Length: 23 ++ ++This IS the real page! ++</data1000> ++ ++</reply> ++ ++<client> ++<features> ++!SSPI ++crypto ++digest ++</features> ++<server> ++http ++</server> ++<name> ++HTTP Digest to different origins and switching credentials ++</name> ++<tool> ++lib%TESTNUMBER ++</tool> ++<command> ++%HOSTIP %HTTPPORT ++</command> ++</client> ++ ++<verify> ++<protocol crlf="headers"> ++GET /api HTTP/1.1 ++Host: first.test:%HTTPPORT ++Accept: */* ++ ++GET /api HTTP/1.1 ++Host: first.test:%HTTPPORT ++Authorization: Digest username="alice", realm="my-backyard", nonce="314156295", uri="/api", response="4ecc00e567c37a9d537727890c2e5b32" ++Accept: */* ++ ++GET /hook HTTP/1.1 ++Host: second.test:%HTTPPORT ++Accept: */* ++ ++GET /hook HTTP/1.1 ++Host: second.test:%HTTPPORT ++Authorization: Digest username="alice", realm="my-backyard", nonce="314156295", uri="/hook", response="d3a7738fb6a23f5543fb8dacc0f0f253" ++Accept: */* ++ ++GET /hook HTTP/1.1 ++Host: second.test:%HTTPPORT ++Accept: */* ++ ++GET /hook HTTP/1.1 ++Host: second.test:%HTTPPORT ++Authorization: Digest username="bob", realm="my-backyard", nonce="314156295", uri="/hook", response="777e68eddb77294d9cbd6134973cbbab" ++Accept: */* ++ ++</protocol> ++</verify> ++</testcase> +diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc +index e938b87bc5..ef23ca4e28 100644 +--- a/tests/libtest/Makefile.inc ++++ b/tests/libtest/Makefile.inc +@@ -102,6 +102,7 @@ TESTS_C = \ + lib1598.c lib1599.c \ + lib1647.c \ + lib1662.c \ ++ lib1686.c \ + lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c \ + lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c \ + lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c \ +diff --git a/tests/libtest/lib1686.c b/tests/libtest/lib1686.c +new file mode 100644 +index 0000000000..e457012bb9 +--- /dev/null ++++ b/tests/libtest/lib1686.c +@@ -0,0 +1,96 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at https://curl.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ * SPDX-License-Identifier: curl ++ * ++ ***************************************************************************/ ++#include "first.h" ++ ++static size_t devnull_1686(char *p, size_t s, size_t n, void *u) ++{ ++ (void)p; ++ (void)u; ++ return s * n; ++} ++ ++#define FIRSTHOST "first.test" ++#define SECONDHOST "second.test" ++ ++static CURLcode test_lib1686(const char *hostip) ++{ ++ CURL *curl = NULL; ++ CURLcode result = CURLE_OK; ++ const char *httpport = libtest_arg2; ++ char firsturl[100]; ++ char secondurl[100]; ++ char firstres[100]; ++ char secondres[100]; ++ struct curl_slist *host = NULL; ++ struct curl_slist *host2 = NULL; ++ ++ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { ++ curl_mfprintf(stderr, "curl_global_init() failed\n"); ++ return TEST_ERR_MAJOR_BAD; ++ } ++ ++ /* create strings for CURLOPT_RESOLVE */ ++ curl_msnprintf(firstres, sizeof(firstres), "%s:%s:%s", ++ FIRSTHOST, httpport, hostip); ++ curl_msnprintf(secondres, sizeof(secondres), "%s:%s:%s", ++ SECONDHOST, httpport, hostip); ++ ++ /* create URLs */ ++ curl_msnprintf(firsturl, sizeof(firsturl), "http://%s:%s/api", ++ FIRSTHOST, httpport); ++ curl_msnprintf(secondurl, sizeof(secondurl), "http://%s:%s/hook", ++ SECONDHOST, httpport); ++ ++ host = curl_slist_append(NULL, firstres); ++ if(!host) ++ goto test_cleanup; ++ host2 = curl_slist_append(host, secondres); ++ if(!host2) ++ goto test_cleanup; ++ host = host2; ++ ++ curl = curl_easy_init(); ++ if(curl) { ++ easy_setopt(curl, CURLOPT_RESOLVE, host); ++ easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); ++ easy_setopt(curl, CURLOPT_USERPWD, "alice:bond"); ++ easy_setopt(curl, CURLOPT_WRITEFUNCTION, devnull_1686); ++ ++ easy_setopt(curl, CURLOPT_URL, firsturl); ++ result = curl_easy_perform(curl); ++ ++ easy_setopt(curl, CURLOPT_URL, secondurl); ++ result = curl_easy_perform(curl); ++ ++ easy_setopt(curl, CURLOPT_USERPWD, "bob:secret"); ++ easy_setopt(curl, CURLOPT_URL, secondurl); ++ result = curl_easy_perform(curl); ++ } ++ ++test_cleanup: ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ curl_slist_free_all(host); ++ return result; ++} +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch b/meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch new file mode 100644 index 0000000000..4e3dc45186 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch @@ -0,0 +1,72 @@ +From 0d7f5b5037e2878ee68ca8317445df1240d117bf Mon Sep 17 00:00:00 2001 +From: alhudz <al.hudz.k@gmail.com> +Date: Thu, 30 Jul 2026 22:18:13 -0700 +Subject: [PATCH] digest: flush proxy state on proxy or credential change + +Closes #21951 + +CVE: CVE-2026-11856 +Upstream-Status: Backport [https://github.com/curl/curl/commit/7ec25148c06b049d3252172ff17fae85b19c54c9] + +Backport Changes: +- Wrynose curl 8.19.0 does not have upstream Curl_peer or Curl_creds. + This backport extends the string-based Digest origin and credential + tracking introduced by upstream commit [1] to the proxy path, so + proxy Digest state is flushed when the proxy destination or proxy + credentials change. + +[1] https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535 + +(cherry picked from commit 7ec25148c06b049d3252172ff17fae85b19c54c9) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + lib/http_digest.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/lib/http_digest.c b/lib/http_digest.c +index 29bfa3b0b3..06e4028f02 100644 +--- a/lib/http_digest.c ++++ b/lib/http_digest.c +@@ -41,6 +41,7 @@ Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" + + static CURLcode digest_update_origin(struct Curl_easy *data, + struct digestdata *digest, ++ bool proxy, + const char *userp, + const char *passwdp) + { +@@ -49,8 +50,15 @@ static CURLcode digest_update_origin(struct Curl_easy *data, + char *authpasswd; + bool flush = FALSE; + +- origin = curl_maprintf("%s:%d:%s", data->conn->scheme->name, +- data->conn->remote_port, data->conn->host.name); ++#ifndef CURL_DISABLE_PROXY ++ if(proxy) ++ origin = curl_maprintf("%d:%d:%s", data->conn->http_proxy.proxytype, ++ data->conn->http_proxy.port, ++ data->conn->http_proxy.host.name); ++ else ++#endif ++ origin = curl_maprintf("%s:%d:%s", data->conn->scheme->name, ++ data->conn->remote_port, data->conn->host.name); + if(!origin) + return CURLE_OUT_OF_MEMORY; + +@@ -158,11 +166,9 @@ CURLcode Curl_output_digest(struct Curl_easy *data, + if(!passwdp) + passwdp = ""; + +- if(!proxy) { +- result = digest_update_origin(data, digest, userp, passwdp); +- if(result) +- return result; +- } ++ result = digest_update_origin(data, digest, proxy, userp, passwdp); ++ if(result) ++ return result; + + #ifdef USE_WINDOWS_SSPI + have_chlg = !!digest->input_token; +-- +2.35.6 diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index 33ccb73eb3..b0edc5b960 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -28,6 +28,8 @@ SRC_URI = " \ file://CVE-2026-8932-dependent.patch \ file://CVE-2026-8932.patch \ file://CVE-2026-8458.patch \ + file://CVE-2026-11856_p1.patch \ + file://CVE-2026-11856_p2.patch \ " SRC_URI:append:class-nativesdk = " \ -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-28 15:24 ` Yoann Congal 2026-08-31 9:49 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 0 siblings, 1 reply; 16+ messages in thread From: Yoann Congal @ 2026-08-28 15:24 UTC (permalink / raw) To: deeratho, openembedded-core On Wed Aug 5, 2026 at 10:31 AM CEST, Deepak Rathore via lists.openembedded.org wrote: > From: Deepak Rathore <deeratho@cisco.com> > > This patch applies the upstream curl security backports for > CVE-2026-11856. The main fix commit is referenced in [1], the > Digest proxy-state follow-up is referenced in [2], and the public > curl advisory is referenced in [3]. The individual backported commit > links are recorded in the embedded patch headers. > > [1] https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535 > [2] https://github.com/curl/curl/commit/7ec25148c06b049d3252172ff17fae85b19c54c9 > [3] https://curl.se/docs/CVE-2026-11856.html > > Signed-off-by: Deepak Rathore <deeratho@cisco.com> > --- > .../curl/curl/CVE-2026-11856_p1.patch | 372 ++++++++++++++++++ > .../curl/curl/CVE-2026-11856_p2.patch | 72 ++++ > meta/recipes-support/curl/curl_8.19.0.bb | 2 + > 3 files changed, 446 insertions(+) > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch > > diff --git a/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch b/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch > new file mode 100644 > index 0000000000..80fb18a7c1 > --- /dev/null > +++ b/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch > @@ -0,0 +1,372 @@ > +From 3349fbcb7876456cadc3cc3a8d3e8aff29406906 Mon Sep 17 00:00:00 2001 > +From: Daniel Stenberg <daniel@haxx.se> > +Date: Mon, 13 Jul 2026 23:17:23 -0700 > +Subject: [PATCH] digest: flush state on origin or credential change > + > +Verified by test 1686 > + > +Closes #21944 > + > +CVE: CVE-2026-11856 > +Upstream-Status: Backport [https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535] > + > +Backport Changes: > +- Wrynose curl 8.19.0 does not have upstream Curl_peer or > + struct Curl_creds. This backport stores the host Digest origin > + and user/password on digestdata, then flushes stale host Digest > + state before reuse when either value changes. > +- Kept Wrynose test-list ordering and added only the upstream > + test1686/lib1686 regression coverage. Same as previous patch of the series, this is new code that does not look like the fix from upstream (I can't accept/understand backporting adaptation but here, I feel like this is too much) I'll hold this one as well. Regards, -- Yoann Congal Smile ECS ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 2026-08-28 15:24 ` Yoann Congal @ 2026-08-31 9:49 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 0 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-31 9:49 UTC (permalink / raw) To: Yoann Congal, openembedded-core@lists.openembedded.org [-- Attachment #1: Type: text/plain, Size: 2985 bytes --] Thanks, Yoann, for your review. Let me review your suggestion and comments in both patches. Regards, Deepak ________________________________ From: Yoann Congal <yoann.congal@smile.fr> Sent: Friday, August 28, 2026 8:54 PM To: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) <deeratho@cisco.com>; openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> Subject: Re: [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 On Wed Aug 5, 2026 at 10:31 AM CEST, Deepak Rathore via lists.openembedded.org wrote: > From: Deepak Rathore <deeratho@cisco.com> > > This patch applies the upstream curl security backports for > CVE-2026-11856. The main fix commit is referenced in [1], the > Digest proxy-state follow-up is referenced in [2], and the public > curl advisory is referenced in [3]. The individual backported commit > links are recorded in the embedded patch headers. > > [1] https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535 > [2] https://github.com/curl/curl/commit/7ec25148c06b049d3252172ff17fae85b19c54c9 > [3] https://curl.se/docs/CVE-2026-11856.html > > Signed-off-by: Deepak Rathore <deeratho@cisco.com> > --- > .../curl/curl/CVE-2026-11856_p1.patch | 372 ++++++++++++++++++ > .../curl/curl/CVE-2026-11856_p2.patch | 72 ++++ > meta/recipes-support/curl/curl_8.19.0.bb | 2 + > 3 files changed, 446 insertions(+) > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch > create mode 100644 meta/recipes-support/curl/curl/CVE-2026-11856_p2.patch > > diff --git a/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch b/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch > new file mode 100644 > index 0000000000..80fb18a7c1 > --- /dev/null > +++ b/meta/recipes-support/curl/curl/CVE-2026-11856_p1.patch > @@ -0,0 +1,372 @@ > +From 3349fbcb7876456cadc3cc3a8d3e8aff29406906 Mon Sep 17 00:00:00 2001 > +From: Daniel Stenberg <daniel@haxx.se> > +Date: Mon, 13 Jul 2026 23:17:23 -0700 > +Subject: [PATCH] digest: flush state on origin or credential change > + > +Verified by test 1686 > + > +Closes #21944 > + > +CVE: CVE-2026-11856 > +Upstream-Status: Backport [https://github.com/curl/curl/commit/5c6b4880357ab3e72967c1c45cae0f96ffabc535] > + > +Backport Changes: > +- Wrynose curl 8.19.0 does not have upstream Curl_peer or > + struct Curl_creds. This backport stores the host Digest origin > + and user/password on digestdata, then flushes stale host Digest > + state before reuse when either value changes. > +- Kept Wrynose test-list ordering and added only the upstream > + test1686/lib1686 regression coverage. Same as previous patch of the series, this is new code that does not look like the fix from upstream (I can't accept/understand backporting adaptation but here, I feel like this is too much) I'll hold this one as well. Regards, -- Yoann Congal Smile ECS [-- Attachment #2: Type: text/html, Size: 5543 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 7/8] curl: set CVE_STATUS for CVE-2026-9547 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (5 preceding siblings ...) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 8/8] curl: set CVE_STATUS for CVE-2026-12064 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 7 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> Analysis: - CVE-2026-9547 is tied to the libssh backend. [1] - Wrynose curl 8.19.0 does not enable or expose the libssh backend in the recipe. [2] - Hence mark this CVE as not-applicable-config for the default Wrynose recipe configuration. Reference: [1] https://curl.se/docs/CVE-2026-9547.html [2] https://git.openembedded.org/openembedded-core/tree/meta/recipes-support/curl/curl_8.19.0.bb?h=wrynose Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- meta/recipes-support/curl/curl_8.19.0.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index b0edc5b960..4c3e31d438 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -43,6 +43,7 @@ CVE_PRODUCT = "haxx:curl haxx:libcurl curl:curl curl:libcurl libcurl:libcurl dan CVE_STATUS[CVE-2024-32928] = "ignored: CURLOPT_SSL_VERIFYPEER was disabled on google cloud services causing a potential man in the middle attack" CVE_STATUS[CVE-2026-8924] = "not-applicable-config: public suffix list support is disabled by the recipe with --without-libpsl" CVE_STATUS[CVE-2026-10536] = "${@bb.utils.contains('PACKAGECONFIG', 'nghttp2', 'unpatched', 'not-applicable-config: applicable only with HTTP/2', d)}" +CVE_STATUS[CVE-2026-9547] = "not-applicable-config: vulnerable libssh backend is not enabled by the recipe" inherit autotools pkgconfig binconfig multilib_header ptest -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [OE-core][wrynose][PATCH 8/8] curl: set CVE_STATUS for CVE-2026-12064 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) ` (6 preceding siblings ...) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 7/8] curl: set CVE_STATUS for CVE-2026-9547 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 7 siblings, 0 replies; 16+ messages in thread From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-05 8:31 UTC (permalink / raw) To: openembedded-core From: Deepak Rathore <deeratho@cisco.com> Analysis: - CVE-2026-12064 affects the curl command-line tool when SCP/SFTP protocol support is available. [1] - Wrynose exposes SCP/SFTP only through the optional libssh2 PACKAGECONFIG, which is disabled by default. [2] - Hence mark this CVE as not-applicable-config for the default Wrynose recipe configuration, while reporting unpatched if libssh2 is explicitly enabled. Reference: [1] https://curl.se/docs/CVE-2026-12064.html [2] https://git.openembedded.org/openembedded-core/tree/meta/recipes-support/curl/curl_8.19.0.bb?h=wrynose Signed-off-by: Deepak Rathore <deeratho@cisco.com> --- meta/recipes-support/curl/curl_8.19.0.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta/recipes-support/curl/curl_8.19.0.bb b/meta/recipes-support/curl/curl_8.19.0.bb index 4c3e31d438..1bf32ffc53 100644 --- a/meta/recipes-support/curl/curl_8.19.0.bb +++ b/meta/recipes-support/curl/curl_8.19.0.bb @@ -44,6 +44,7 @@ CVE_STATUS[CVE-2024-32928] = "ignored: CURLOPT_SSL_VERIFYPEER was disabled on go CVE_STATUS[CVE-2026-8924] = "not-applicable-config: public suffix list support is disabled by the recipe with --without-libpsl" CVE_STATUS[CVE-2026-10536] = "${@bb.utils.contains('PACKAGECONFIG', 'nghttp2', 'unpatched', 'not-applicable-config: applicable only with HTTP/2', d)}" CVE_STATUS[CVE-2026-9547] = "not-applicable-config: vulnerable libssh backend is not enabled by the recipe" +CVE_STATUS[CVE-2026-12064] = "${@bb.utils.contains('PACKAGECONFIG', 'libssh2', 'unpatched', 'not-applicable-config: SCP/SFTP support is not enabled in PACKAGECONFIG', d)}" inherit autotools pkgconfig binconfig multilib_header ptest -- 2.35.6 ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-08-31 9:49 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-05 8:30 [OE-core][wrynose][PATCH 0/8] curl: Security fixes Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 1/8] curl: fix CVE-2026-8286 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-25 15:04 ` Yoann Congal 2026-08-26 8:47 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-27 6:53 ` Yoann Congal 2026-08-27 10:51 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 2/8] curl: set CVE_STATUS for CVE-2026-8924 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 3/8] curl: fix CVE-2026-8927 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:30 ` [OE-core][wrynose][PATCH 4/8] curl: fix CVE-2026-8932 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 5/8] curl: fix CVE-2026-8458 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-28 15:07 ` Yoann Congal 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 6/8] curl: fix CVE-2026-11856 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-28 15:24 ` Yoann Congal 2026-08-31 9:49 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 7/8] curl: set CVE_STATUS for CVE-2026-9547 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) 2026-08-05 8:31 ` [OE-core][wrynose][PATCH 8/8] curl: set CVE_STATUS for CVE-2026-12064 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.