From patchwork Fri Nov 6 14:41:28 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103274 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.7293.1793976108530186685 for ; Fri, 06 Nov 2026 06:41:48 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=vixx7CDv; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id C65E84E4145C for ; Fri, 6 Nov 2026 14:41:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 96C875FFBC; Fri, 6 Nov 2026 14:41:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 76D06103292BC; Fri, 6 Nov 2026 15:41:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976105; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=eNa4x2GHDQB6a2LJil2C+3+O+y0dOB8Zn3yIj/pN4ZE=; b=vixx7CDviPE8g3RUGuIDF3K310AVTfAJLrwKcZtKv4fgWx7hCSJcd/myD+JSxSavRpYUzR 5+g3nBIcn6ykLawBPWMLUgOXPaksd/P2B3ymdSlmGyauaKRY2Z4BxHAZw5qgfr9OHEDuMJ v02veepVSSPuKPP0x003kdp5C3HKC55VYFmV7F8JFZ8NFymP92eOaoppCDEQ7V20cT/R/E 9sF0vYzcy/izninuYbHCQzpkVMVJhlwZCFTCTqJF+lFBvxNfUrJBCubm16JB3N5HGJjE2f XHfKDL1SgMtflpzOMPIY2tz0BoflkpNXajkxwFMC2cX8FKpE0L2PMxCFkMzKpg== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 1/7] curl: fix CVE-2026-86409 Date: Fri, 6 Nov 2026 15:41:28 +0100 Message-ID: <20261106144134.1370928-2-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:58 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249656 This vulnerability, marked as High [1], was fixed upstream [2] since v8.22.0. Backport the fix to curl v8.7.1. The only changes not included in the backport are the ones related to test1978, which is not available in v8.7.1. [1] https://nvd.nist.gov/vuln/detail/cve-2026-86409 [2] https://curl.se/docs/CVE-2026-86409.html Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-86409.patch | 36 +++++++++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 1 + 2 files changed, 37 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-86409.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-86409.patch b/meta/recipes-support/curl/curl/CVE-2026-86409.patch new file mode 100644 index 0000000000..55a4def13b --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-86409.patch @@ -0,0 +1,36 @@ +From 0d375942119d6a8fe6a4c6874a2f1f05d3312ad0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jo=C3=A3o=20Marcos=20Costa?= +Date: Thu, 5 Nov 2026 17:55:56 +0100 +Subject: [PATCH] setopt: make NULL CURLOPT_AWS_SIGV4 disable aws-sigv4 auth +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Disable `CURLAUTH_AWS_SIGV4` when `CURLOPT_AWS_SIGV4` is set to NULL. +Syncing behavior with `CURLAUTH_HTTPSIG`. + +Reported-by: Stanislav Fort + +Closes #22681 + +CVE: CVE-2026-86409 +Upstream-Status: Backport [https://github.com/curl/curl/commit/c3c70440e8d9938c0bb732595751e8aebc614f24] + +Signed-off-by: João Marcos Costa +--- + lib/setopt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/setopt.c b/lib/setopt.c +index 8a5a5d7c33..bcf41807e7 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -693,6 +693,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) + */ + if(data->set.str[STRING_AWS_SIGV4]) + data->set.httpauth = CURLAUTH_AWS_SIGV4; ++ else ++ data->set.httpauth &= ~(uint32_t)CURLAUTH_AWS_SIGV4; + break; + #endif + diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index ab33d4aa77..18123ece3c 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -43,6 +43,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-13608.patch \ file://CVE-2026-8286.patch \ file://CVE-2026-80230.patch \ + file://CVE-2026-86409.patch \ " SRC_URI:append:class-nativesdk = " \ From patchwork Fri Nov 6 14:41:29 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103275 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.7466.1793976110152604853 for ; Fri, 06 Nov 2026 06:41:50 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=XFYvWXB0; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 35D5A4E4145B for ; Fri, 6 Nov 2026 14:41:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0C0635FFBC; Fri, 6 Nov 2026 14:41:48 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EDAAC103288D3; Fri, 6 Nov 2026 15:41:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976107; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=NOjiPoXQ9xpq12AtAKluSyqQcRi7cAy52Ihgn1hq9Mk=; b=XFYvWXB0RcOzSh7iBJ2WTgfeU3ew3aAiQcwZ0vDKxRBOTFue7LCHFNSPlRuvKb2U9uvtBY UfAcVoEQup6FTrb0WCsRFEqFaIuuqtSKzLZ5v/8hAKeZsyP+gpsUK8wZzGnlg0Qa1jmvaZ Jid+5Khe3/Cx+ujSc8j0jzhnOk7ejg9tG/eeMVfDdA8Y0lQo+2N6sOHxLypgSB1rG5GDWc DK9HrOOzxJSUw2BPnedkJT94VWheKaDq+MbDvElNwULWoHVyAdh+YVMoA9Ri4hIhqjracS UWFr5nivPKPztZt7xm3haDLlioRQIODHkCL/IosdQPKSvMOJGMIAro9iOPhpYA== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 2/7] curl: fix CVE-2026-87864 Date: Fri, 6 Nov 2026 15:41:29 +0100 Message-ID: <20261106144134.1370928-3-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249657 This vulnerability, marked as High [1], was fixed upstream [2] since v8.22.0. Backport the fix to curl v8.7.1. [1] https://nvd.nist.gov/vuln/detail/cve-2026-87864 [2] https://curl.se/docs/CVE-2026-87864.html Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-87864.patch | 55 +++++++++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 1 + 2 files changed, 56 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-87864.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-87864.patch b/meta/recipes-support/curl/curl/CVE-2026-87864.patch new file mode 100644 index 0000000000..a8b7e887e8 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-87864.patch @@ -0,0 +1,55 @@ +From af73dab33be1161ed09aa20247e26d344a12f4d8 Mon Sep 17 00:00:00 2001 +From: Stefan Eissing +Date: Thu, 27 Aug 2026 09:47:53 +0200 +Subject: [PATCH] imap: APPEND CRLF fix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Deny an APPEND operation with CRLF conversion requested as we are unable +to predict the final upload size and APPEND requires us to announce it +before starting the upload. + +The check for unknown sizes had already been there, but the crlf +conversion that renders a known size unknown was not accounted for. + +Closes #22702 + +CVE: CVE-2026-87864 +Upstream-Status: Backport [https://github.com/curl/curl/commit/3b547de301342b347fb3c6ea6ae7979070793a66] + +Signed-off-by: João Marcos Costa +--- + lib/imap.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/lib/imap.c b/lib/imap.c +index 0e013e740a..6e4194b0cf 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -790,7 +790,6 @@ static CURLcode imap_perform_append(struct Curl_easy *data) + result = Curl_creader_set_mime(data, &data->set.mimepost); + if(result) + return result; +- data->state.infilesize = Curl_creader_client_length(data); + } + else + #endif +@@ -800,9 +799,15 @@ static CURLcode imap_perform_append(struct Curl_easy *data) + return result; + } + +- /* Check we know the size of the upload */ ++ /* Check we know the size of the upload. This takes all readers ++ * into account. Especially crlf conversions which make the size ++ * unpredictable, e.g. -1. */ ++ data->state.infilesize = Curl_creader_total_length(data); + if(data->state.infilesize < 0) { +- failf(data, "Cannot APPEND with unknown input file size"); ++ if(data->set.crlf) ++ failf(data, "Cannot APPEND with CRLF conversion making size unknown"); ++ else ++ failf(data, "Cannot APPEND with unknown input file size"); + return CURLE_UPLOAD_FAILED; + } + diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index 18123ece3c..9ca79a14fc 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -44,6 +44,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-8286.patch \ file://CVE-2026-80230.patch \ file://CVE-2026-86409.patch \ + file://CVE-2026-87864.patch \ " SRC_URI:append:class-nativesdk = " \ From patchwork Fri Nov 6 14:41:30 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103273 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.7295.1793976111115014209 for ; Fri, 06 Nov 2026 06:41:51 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=c0CAUXBM; spf=pass (domain: bootlin.com, ip: 185.246.84.56, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 3F93B1A14E1 for ; Fri, 6 Nov 2026 14:41:49 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0B22B5FFBC; Fri, 6 Nov 2026 14:41:49 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D9444103293BA; Fri, 6 Nov 2026 15:41:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976108; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=x8UoHukdQHxe1BPuYJ11wdpyExz7uLphMxvEyLZAiUc=; b=c0CAUXBM6ZgK7Te0Ue1+1k/FVtQIGKGaANs1XSwb9N7GkKHujW/uf9o09rvhvqUXPgIqm4 awNyTLCAMIY2YtKrZ1QJrY6Krjt1TZZdbX3+H26+VlZ76+0CY/WI2Li2TcP3Tpl5sUh67E 4HiUCZq259I1HUhntEU8y6F2mRTEbo10WHaAw1DNMzd9iigZscOh7Xq1kQC8ONBmGTkfKv yf4D+ih2IPLbWSiRo58rPEqSLXTd84eBUhrNYOSEAcFWbU//vjaim0wpn+HgHfVRQI5LTM XsCSQEqqN81Psk36X3kWYECcROyXCOdc1Rg4PLX8wT0OnziW9nzVVU8HHTAVvg== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 3/7] curl: fix CVE-2026-87865 Date: Fri, 6 Nov 2026 15:41:30 +0100 Message-ID: <20261106144134.1370928-4-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:58 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249658 This vulnerability, marked as High [1], was fixed upstream [2] since v8.23.0. Backport the fix to curl v8.7.1. [1] https://nvd.nist.gov/vuln/detail/cve-2026-87865 [2] https://curl.se/docs/CVE-2026-87865.html Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-87865.patch | 212 ++++++++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 1 + 2 files changed, 213 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-87865.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-87865.patch b/meta/recipes-support/curl/curl/CVE-2026-87865.patch new file mode 100644 index 0000000000..9abc7bb427 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-87865.patch @@ -0,0 +1,212 @@ +From e86ba6bcce298c3fe5d9f4a5848311cb458dfbc0 Mon Sep 17 00:00:00 2001 +From: Bobbeh Rhino +Date: Tue, 8 Sep 2026 06:33:27 -0400 +Subject: [PATCH] libssh2: match hashed known_hosts entries by host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +libssh2 does not expose the plaintext name for hashed entries. Check +each entry key against the requested hostname before using its key type. +Otherwise an unrelated hashed entry can select the wrong algorithm. + +Add an SFTP regression test 3500 with an unrelated hashed entry before +the requested host. + +Closes #22874 + +CVE: CVE-2026-87865 +Upstream-Status: Backport [https://github.com/curl/curl/commit/323c184b6bdf5b1988a10c0a61560666e1588149] + +Signed-off-by: João Marcos Costa +--- + lib/vssh/libssh2.c | 16 +++++++-- + tests/data/Makefile.inc | 2 +- + tests/data/test3500 | 47 +++++++++++++++++++++++++ + tests/libtest/Makefile.am | 2 +- + tests/libtest/test3500.pl | 72 +++++++++++++++++++++++++++++++++++++++ + 5 files changed, 134 insertions(+), 5 deletions(-) + create mode 100644 tests/data/test3500 + create mode 100755 tests/libtest/test3500.pl + +diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c +index 3cfbe126c6..28946cf598 100644 +--- a/lib/vssh/libssh2.c ++++ b/lib/vssh/libssh2.c +@@ -876,9 +876,19 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) + break; + } + } +- else { +- found = true; +- break; ++ else if(store->key) { ++ int keycheck = libssh2_knownhost_checkp( ++ sshc->kh, conn->origin->hostname, ++ (conn->origin->port != PORT_SSH) ? conn->origin->port : -1, ++ store->key, strlen(store->key), ++ LIBSSH2_KNOWNHOST_TYPE_PLAIN | ++ LIBSSH2_KNOWNHOST_KEYENC_BASE64 | ++ (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK), ++ NULL); ++ if(keycheck == LIBSSH2_KNOWNHOST_CHECK_MATCH) { ++ found = TRUE; ++ break; ++ } + } + } + } +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index aafd309a9d..614b6baf4b 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -262,4 +262,4 @@ test3024 test3025 test3026 test3027 test3028 test3029 test3030 \ + \ + test3100 test3101 test3102 test3103 \ + test3200 \ +-test3201 test3202 ++test3201 test3202 test3500 +diff --git a/tests/data/test3500 b/tests/data/test3500 +new file mode 100644 +index 0000000000..1bcf3bc17d +--- /dev/null ++++ b/tests/data/test3500 +@@ -0,0 +1,47 @@ ++ ++ ++ ++ ++SFTP ++known_hosts ++libssh2 ++ ++ ++ ++# Server-side ++ ++ ++Test data ++for hashed known hosts ++ ++ ++ ++# Client-side ++ ++ ++sftp ++ ++ ++sftp ++libssh2 ++!badlibssh ++ ++ ++%PERL %SRCDIR/libtest/test3500.pl %LOGDIR/server/curl_host_key.pub %LOGDIR/known%TESTNUMBER "[%HOSTIP]:%SSHPORT" ++ ++ ++SFTP matches requested hashed known_hosts entry ++ ++ ++--knownhosts %LOGDIR/known%TESTNUMBER --key %LOGDIR/server/curl_client_key --pubkey %LOGDIR/server/curl_client_key.pub -u %USER: sftp://%HOSTIP:%SSHPORT%SFTP_PWD/%LOGDIR/file%TESTNUMBER.txt ++ ++ ++Test data ++for hashed known hosts ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++ +diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am +index 8ae972a248..bb44e1745f 100644 +--- a/tests/libtest/Makefile.am ++++ b/tests/libtest/Makefile.am +@@ -36,7 +36,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib + +-EXTRA_DIST = test307.pl test610.pl test613.pl test1013.pl test1022.pl \ ++EXTRA_DIST = test307.pl test610.pl test613.pl test1013.pl test1022.pl test3500.pl \ + Makefile.inc notexists.pl CMakeLists.txt mk-lib1521.pl .checksrc + + CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ +diff --git a/tests/libtest/test3500.pl b/tests/libtest/test3500.pl +new file mode 100755 +index 0000000000..d95f54cecf +--- /dev/null ++++ b/tests/libtest/test3500.pl +@@ -0,0 +1,72 @@ ++#!/usr/bin/env perl ++#*************************************************************************** ++# _ _ ____ _ ++# Project ___| | | | _ \| | ++# / __| | | | |_) | | ++# | (__| |_| | _ <| |___ ++# \___|\___/|_| \_\_____| ++# ++# Copyright (C) Daniel Stenberg, , 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 ++# ++########################################################################### ++use strict; ++use warnings; ++ ++use Digest::SHA qw(hmac_sha1); ++use MIME::Base64 qw(encode_base64); ++ ++sub errout { ++ print $_[0] . "\n"; ++ exit 1; ++} ++ ++if(@ARGV != 3) { ++ errout "Usage: $0 host-public-key known-hosts-file target"; ++} ++ ++my ($hostkey_file, $knownhosts_file, $target) = @ARGV; ++open(my $hostkey, "<", $hostkey_file) or errout "$!"; ++my $hostkey_line = <$hostkey>; ++close($hostkey) or errout "$!"; ++ ++my ($hostkey_algo, $hostkey_data) = split(/\s+/, $hostkey_line); ++if(!$hostkey_algo || !$hostkey_data) { ++ errout "Failed parsing SSH host public key"; ++} ++ ++my $rsa_key = ++ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgSyqrUP2xhqLqkyopVapoKeucYIp" . ++ "ZXeUqj+Q9WLWyXka5re62Y3R/lxZUXtkJjlpdD2LNMFenNlDQvPaXH5Utllt+c3z" . ++ "wOkOLy7RXX5S37SfQFm/0fPkZqoZfMDB6XDcwA4cakjCRn4oZyKs8dWAxoNaTtYc" . ++ "nKKMJ6rmc8PttykJw9fwiKAjPyYf21/BMvWIzu9req+TrDA/Jcd2UAug94CikJIX" . ++ "uwKmSYleAOo4eJWx8GyujgEgZn05eq+K1LSg9RqRVIxOdqjoE5K3abBfs0rmUuLd" . ++ "MFh7nHseTFXYbKzpz46V7iZMfFuoyURrzVsqGUm+/m7dxBM98In12kOm3"; ++my $ed25519_key = ++ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAqmXRY8k+W9GtpWxYru6ELAXYHdXq" . ++ "jf33ziITGTiJUN"; ++my $other_key = $hostkey_algo eq "ssh-ed25519" ? $rsa_key : $ed25519_key; ++ ++my $salt = "curl-knownhosts-test"; ++my $salt64 = encode_base64($salt, ""); ++my $hash64 = encode_base64(hmac_sha1("unrelated.invalid", $salt), ""); ++my $target_hash64 = encode_base64(hmac_sha1($target, $salt), ""); ++ ++open(my $knownhosts, ">", $knownhosts_file) or errout "$!"; ++print $knownhosts "|1|$salt64|$hash64 $other_key\n"; ++print $knownhosts "|1|$salt64|$target_hash64 $hostkey_algo $hostkey_data\n"; ++close($knownhosts) or errout "$!"; ++ ++exit 0; diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index 9ca79a14fc..40de36e151 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -45,6 +45,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-80230.patch \ file://CVE-2026-86409.patch \ file://CVE-2026-87864.patch \ + file://CVE-2026-87865.patch \ " SRC_URI:append:class-nativesdk = " \ From patchwork Fri Nov 6 14:41:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103270 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.7468.1793976111975781542 for ; Fri, 06 Nov 2026 06:41:52 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=Qp0QvGKY; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 21D694E4145C for ; Fri, 6 Nov 2026 14:41:50 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E3EB75FFBC; Fri, 6 Nov 2026 14:41:49 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D95BE103292BC; Fri, 6 Nov 2026 15:41:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976109; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=PJ38XVN28VUaFmVL8m2KIaYbz7qh4tRT8k7gdSFtgxA=; b=Qp0QvGKYpzbIjNBKKNGNQEQ1NRvH5sN5cWWLrdojVU9flqr68ozFbNSqoHkPHA6dbbEhBI vAx4MdFQQ1UW3dNmciuAOBmBerifB+f0HBvYeM9PmGRVxzasY8vSiunBBey/prUlLDKt3/ oqBHATZ6KlzSso/9V9INj6eom6KUWypIkry113lUyy+7Rn3Z/b8XhjSquS+VwG9pY7dpsz XBiHVBtfm2bcUJbaGMK7cIXMc7bTJxjfSIKXEO1ky7YBZEzrOQQ0HaHxlVxtRcV+/WeRKQ GXgq8KNJMsQsR6cMoRKf96xAf4sIpISDLrAtSgvlvvw9xUYOt6Unip4FChv9jQ== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 4/7] curl: fix CVE-2026-92386 Date: Fri, 6 Nov 2026 15:41:31 +0100 Message-ID: <20261106144134.1370928-5-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:57 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249659 This vulnerability, marked as High [1], was fixed upstream [2] since v8.23.0. Backport the fix to curl v8.7.1. [1] https://nvd.nist.gov/vuln/detail/cve-2026-92386 [2] https://curl.se/docs/CVE-2026-92386.html Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-92386.patch | 32 +++++++++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 1 + 2 files changed, 33 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-92386.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-92386.patch b/meta/recipes-support/curl/curl/CVE-2026-92386.patch new file mode 100644 index 0000000000..9ad6044d8c --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-92386.patch @@ -0,0 +1,32 @@ +From a83871b1853ec4fcb514d10d24378b57135b5169 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 16 Sep 2026 11:09:18 +0200 +Subject: [PATCH] cookie: accept slightly longer lines in cookie jars +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Closes #22964 + +CVE: CVE-2026-92386 +Upstream-Status: Backport [https://github.com/curl/curl/commit/445aa87e13f91c94bc742f54343a2eac924e1765] +Signed-off-by: João Marcos Costa +--- + lib/cookie.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 67494d2855..7f7cd741c9 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -1244,7 +1244,9 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, + c->running = FALSE; /* this is not running, this is init */ + if(fp) { + struct dynbuf buf; +- Curl_dyn_init(&buf, MAX_COOKIE_LINE); ++ /* accept a little longer lines so that a full cookie fits and does not ++ abort the file read */ ++ Curl_dyn_init(&buf, MAX_COOKIE_LINE + 48); + while(Curl_get_line(&buf, fp)) { + char *lineptr = Curl_dyn_ptr(&buf); + bool headerline = FALSE; diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index 40de36e151..12db6c0c24 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -46,6 +46,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-86409.patch \ file://CVE-2026-87864.patch \ file://CVE-2026-87865.patch \ + file://CVE-2026-92386.patch \ " SRC_URI:append:class-nativesdk = " \ From patchwork Fri Nov 6 14:41:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103271 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.7297.1793976112490857600 for ; Fri, 06 Nov 2026 06:41:52 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=cbO4jP7y; spf=pass (domain: bootlin.com, ip: 185.246.84.56, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id BF8631A14EE for ; Fri, 6 Nov 2026 14:41:50 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 90FBC5FFBC; Fri, 6 Nov 2026 14:41:50 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BD5AE103293BD; Fri, 6 Nov 2026 15:41:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976110; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=QmuwB6A0UiHqGlurUe5bYOfLGii/60i6wqvyeeRK/6Q=; b=cbO4jP7yy0UhoP7/GUBxwpf5DlJ2S/UHcVG2KO9Er+opm83OLW4+FlsI6uolkvLrhZQphN EqfXPrINyG0mq74aHfp6Z3Q702KaDTTMM3VTailjyqOqBTj+byYMavf5irfao5nrZ3Locl 5/zjW6FJiIldfxFJAlXTo7bl3Td4116FniB3GxvjbK9HPnUzDByYZhp1k9lDE5WG+0iJ99 L1I35sdMrQ5lCiw2WrbfvUPkKZ5dhO1rL/wQz3g0LEgt9DaRryiopwz/ZBxuIUkzVDXfeq UYPJYqkRm2TeouZQTLsl/p8wTudbmystkNhw3vAmqlknvPqkS5HtMY+dF2PFZw== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 5/7] curl: fix CVE-2026-92389 Date: Fri, 6 Nov 2026 15:41:32 +0100 Message-ID: <20261106144134.1370928-6-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:57 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249660 This vulnerability, marked as High [1], was fixed upstream [2] since v8.23.0. Backport the fix to curl v8.7.1. [1] https://nvd.nist.gov/vuln/detail/cve-2026-92389 [2] https://curl.se/docs/CVE-2026-92389.html Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-92389.patch | 56 +++++++++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 1 + 2 files changed, 57 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-92389.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-92389.patch b/meta/recipes-support/curl/curl/CVE-2026-92389.patch new file mode 100644 index 0000000000..1f568fe2a0 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-92389.patch @@ -0,0 +1,56 @@ +From ab9213549c9c7f087cbaa818492705b482c4309d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jo=C3=A3o=20Marcos=20Costa?= +Date: Fri, 6 Nov 2026 10:31:16 +0100 +Subject: [PATCH] tftp: verify direction in a few places +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Closes #22974 + +CVE: CVE-2026-92389 +Upstream-Status: Backport [https://github.com/curl/curl/commit/63dd390fab905a239a97e2700532929343ebc4e9] + +Signed-off-by: João Marcos Costa +--- + lib/tftp.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/lib/tftp.c b/lib/tftp.c +index ff2b7b7457..def944ddd5 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -545,10 +545,14 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, + break; + + case TFTP_EVENT_ACK: /* Connected for transmit */ ++ if(!data->state.upload) ++ return CURLE_TFTP_ILLEGAL; + result = tftp_connect_for_tx(state, event); + break; + + case TFTP_EVENT_DATA: /* Connected for receive */ ++ if(!data->state.upload) ++ return CURLE_TFTP_ILLEGAL; + result = tftp_connect_for_rx(state, event); + break; + +@@ -709,6 +713,9 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) + char *bufptr; + bool eos; + ++ if(!data->state.upload) ++ return CURLE_TFTP_ILLEGAL; ++ + switch(event) { + + case TFTP_EVENT_ACK: +@@ -1131,6 +1138,8 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) + + switch(state->event) { + case TFTP_EVENT_DATA: ++ if(!data->state.upload) ++ return CURLE_TFTP_ILLEGAL; + /* Don't pass to the client empty or retransmitted packets */ + if(state->rbytes > 4 && + (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) { diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index 12db6c0c24..39e804a1c3 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -47,6 +47,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-87864.patch \ file://CVE-2026-87865.patch \ file://CVE-2026-92386.patch \ + file://CVE-2026-92389.patch \ " SRC_URI:append:class-nativesdk = " \ From patchwork Fri Nov 6 14:41:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103272 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.7470.1793976113413926888 for ; Fri, 06 Nov 2026 06:41:53 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=wyHL+0Ub; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id B44574E4145B for ; Fri, 6 Nov 2026 14:41:51 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8A0745FFBC; Fri, 6 Nov 2026 14:41:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 62A24103288D3; Fri, 6 Nov 2026 15:41:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976110; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=8Fohwr1aFSrRWwOsAE8FIdV6lFmZ93y/AK29NdzWo4w=; b=wyHL+0Ub4iA6VtAfbrhqVLV7iiIcltEJubcQF7VMKvqFaFQBzyi5p/qolSsZRY7VVbJUyi //oI1Ts6QLkm5mp5zcpketq0MRdhAlc4pRPCaQpq7kGxz4K7m6xeyH4iEQB9w1vJqQwI/C LbuCNvfGE2TQbwG/ohftqcCxIS0it8y8Hkur/T3abLXeT9OWFcj6skhTEVJbXN27BHA3da /z538R+MMpKOugdN4fs4EJvKdHRPQIbLcv79HCnnogmMuzkqDvigq7bsIXQZxKkWRjESD1 NjD1ZxpKB+51PalzJDBxehsTmJFHIaD/RhuHiNiqDm8yVyPtww++4Vfrwx3+Ew== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 6/7] curl: fix CVE-2026-92391 Date: Fri, 6 Nov 2026 15:41:33 +0100 Message-ID: <20261106144134.1370928-7-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:58 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249661 This vulnerability, marked as High [1], was fixed upstream [2] since v8.23.0. Backport the fix to curl v8.7.1. [1] https://nvd.nist.gov/vuln/detail/cve-2026-92391 [2] https://curl.se/docs/CVE-2026-92391.html Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-92391.patch | 185 ++++++++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 1 + 2 files changed, 186 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-92391.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-92391.patch b/meta/recipes-support/curl/curl/CVE-2026-92391.patch new file mode 100644 index 0000000000..d7d9c3e18a --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-92391.patch @@ -0,0 +1,185 @@ +From 7ba6d6df009e5dba8cced2607005825a142ff525 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 13 Sep 2026 00:06:44 +0200 +Subject: [PATCH] mime: do curl_mime_free() non-recursively +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Verify with test 3595: deeply nested curl_mime_free() + +Closes #22927 + +CVE: CVE-2026-92391 +Upstream-Status: Backport [https://github.com/curl/curl/commit/d7546809d5bd548b69ec49fca26565c8f6f0d344] + +Signed-off-by: João Marcos Costa +--- + lib/mime.c | 28 +++++++++++++---- + tests/data/Makefile.inc | 2 +- + tests/data/test3595 | 21 +++++++++++++ + tests/libtest/lib3595.c | 70 +++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 114 insertions(+), 7 deletions(-) + create mode 100644 tests/data/test3595 + create mode 100644 tests/libtest/lib3595.c + +diff --git a/lib/mime.c b/lib/mime.c +index 5bc6d38931..254d6c93aa 100644 +--- a/lib/mime.c ++++ b/lib/mime.c +@@ -1180,20 +1180,36 @@ void Curl_mime_cleanpart(curl_mimepart *part) + } + } + +-/* Recursively delete a mime handle and its parts. */ ++/* Non-recursively delete a mime handle and its parts. */ + void curl_mime_free(curl_mime *mime) + { + curl_mimepart *part; + +- if(mime) { +- mime_subparts_unbind(mime); /* Be sure it's not referenced anymore. */ +- while(mime->firstpart) { +- part = mime->firstpart; ++ if(!mime) ++ return; ++ ++ mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */ ++ ++ while(mime) { ++ part = mime->firstpart; ++ if(part) { + mime->firstpart = part->nextpart; ++ if(part->kind == MIMEKIND_MULTIPART && part->arg && ++ part->freefunc == mime_subparts_free) { ++ curl_mime *subparts = (curl_mime *)part->arg; ++ part->freefunc = NULL; ++ cleanup_part_content(part); ++ subparts->parent = mime->parent; ++ mime->parent = (curl_mimepart *)subparts; ++ } + Curl_mime_cleanpart(part); + free(part); + } +- free(mime); ++ else { ++ curl_mime *parent = (curl_mime *)mime->parent; ++ free(mime); ++ mime = parent; ++ } + } + } + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 614b6baf4b..9efae9cefe 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -262,4 +262,4 @@ test3024 test3025 test3026 test3027 test3028 test3029 test3030 \ + \ + test3100 test3101 test3102 test3103 \ + test3200 \ +-test3201 test3202 test3500 ++test3201 test3202 test3500 test3595 +diff --git a/tests/data/test3595 b/tests/data/test3595 +new file mode 100644 +index 0000000000..b2b1dd26c2 +--- /dev/null ++++ b/tests/data/test3595 +@@ -0,0 +1,21 @@ ++ ++ ++ ++ ++mime ++ ++ ++ ++# Client-side ++ ++ ++lib%TESTNUMBER ++ ++ ++curl_mime_free ++ ++ ++ ++ ++ ++ +diff --git a/tests/libtest/lib3595.c b/tests/libtest/lib3595.c +new file mode 100644 +index 0000000000..1f343f503e +--- /dev/null ++++ b/tests/libtest/lib3595.c +@@ -0,0 +1,70 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, , 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" ++ ++static CURLcode test_lib3595(const char *arg) ++{ ++ UNITTEST_BEGIN_SIMPLE ++ ++#if !defined(CURL_DISABLE_MIME) && \ ++ (!defined(CURL_DISABLE_HTTP) || \ ++ !defined(CURL_DISABLE_SMTP) || \ ++ !defined(CURL_DISABLE_IMAP)) ++ ++ curl_mime *root = NULL; ++ curl_mime *current = NULL; ++ curl_mime *sub = NULL; ++ curl_mimepart *part = NULL; ++ int i; ++ ++ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { ++ curl_mfprintf(stderr, "curl_global_init() failed\n"); ++ return TEST_ERR_MAJOR_BAD; ++ } ++ ++ /* Create a deeply nested mime structure to verify that non-recursive ++ curl_mime_free works properly. */ ++ (void)arg; ++ root = curl_mime_init(NULL); ++ fail_unless(root != NULL, "curl_mime_init root failed"); ++ current = root; ++ ++ for(i = 0; i < 50; i++) { ++ part = curl_mime_addpart(current); ++ fail_unless(part != NULL, "curl_mime_addpart failed"); ++ sub = curl_mime_init(NULL); ++ fail_unless(sub != NULL, "curl_mime_init sub failed"); ++ curl_mime_subparts(part, sub); ++ current = sub; ++ } ++ ++ /* Free deep structure */ ++ curl_mime_free(root); ++ curl_global_cleanup(); ++#else ++ (void)arg; ++#endif ++ ++ UNITTEST_END_SIMPLE ++} diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index 39e804a1c3..3bd1b92d44 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -48,6 +48,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-87865.patch \ file://CVE-2026-92386.patch \ file://CVE-2026-92389.patch \ + file://CVE-2026-92391.patch \ " SRC_URI:append:class-nativesdk = " \ From patchwork Fri Nov 6 14:41:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= X-Patchwork-Id: 103269 X-Patchwork-Delegate: jeremy.rosen@smile.fr Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.7471.1793976114200796741 for ; Fri, 06 Nov 2026 06:41:54 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=dkim header.b=Dn68cI9p; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: joaomarcos.costa@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 7FFCA4E4145C; Fri, 6 Nov 2026 14:41:52 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4F7125FFBC; Fri, 6 Nov 2026 14:41:52 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 53B4F103293C4; Fri, 6 Nov 2026 15:41:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1793976111; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=bnoP3Z6Knn9zUFetq6D4Ys9UxbAunRH5QkD+GIrysIk=; b=Dn68cI9ph2rrxB9ND+mQvUsUNdobxIfZhN+FrdQx8deasuln+r+OCLat9AtmaYXjz8GD40 KjSELUV1WElAYsYx5n4umgpboQ0Iy3ShYgidQruWZfai4QoUnC1pG6B4wbV7aUH0VMW6eZ D8Sw1dsWsfX/TFd9FJqeq0yN7cPl6o15m0fD7fe0C02/vYS1s+fwzQ+iXq/Q65JlGIXhEm Y+Y0HmGzVHJd12SA8FIRfT51FwpOJEmmV78iltzEFoK9pmVwiHLcAPA4+T0mWIJYKbp3S4 /he3us7Ejw5QNrZSLQg4eSaaF2TqpyISy63Pg4YOIU9d/cZwD7EIIj1/aed7Hg== From: =?utf-8?q?Jo=C3=A3o_Marcos_Costa_=28Schneider_Electric=29?= To: openembedded-core@lists.openembedded.org Cc: thomas.petazzoni@bootlin.com, yoann.congal@smile.fr, =?utf-8?q?Jo=C3=A3o?= =?utf-8?q?_Marcos_Costa_=28Schneider_Electric=29?= Subject: [scarthgap][PATCH 7/7] curl: fix CVE-2026-94266 Date: Fri, 6 Nov 2026 15:41:34 +0100 Message-ID: <20261106144134.1370928-8-joaomarcos.costa@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> References: <20261106144134.1370928-1-joaomarcos.costa@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Fri, 06 Nov 2026 14:41:57 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249662 This vulnerability, marked as High [1], was fixed upstream [2] since v8.23.0. Backport the fix to curl v8.7.1. The *-pre.patch includes essentially the definition of CURLU_GET_EMPTY, needed by the actual CVE fix, and the calls to curlx_free and curlx_safefree were replaced by their respective counterparts available in curl v8.7.1. Also, in effective_url(), the call to Curl_bufref_ptr() was replaced a plain const char * assignment, as curl v8.7.1 defines stat.url as char* (as opposed to struct bufref in v8.23.0). While I tried backporting the commit [3] that turns it into a bufref, it just raised too many conflicts. [1] https://nvd.nist.gov/vuln/detail/cve-2026-94266 [2] https://curl.se/docs/CVE-2026-94266.html [3] https://github.com/curl/curl/commit/36542b734966fce2ce5689d689a0e4922a103e50 Signed-off-by: João Marcos Costa (Schneider Electric) --- .../curl/curl/CVE-2026-94266-pre.patch | 302 ++++++++++++++++++ .../curl/curl/CVE-2026-94266.patch | 222 +++++++++++++ meta/recipes-support/curl/curl_8.7.1.bb | 2 + 3 files changed, 526 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2026-94266-pre.patch create mode 100644 meta/recipes-support/curl/curl/CVE-2026-94266.patch diff --git a/meta/recipes-support/curl/curl/CVE-2026-94266-pre.patch b/meta/recipes-support/curl/curl/CVE-2026-94266-pre.patch new file mode 100644 index 0000000000..bd04a9cd29 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-94266-pre.patch @@ -0,0 +1,302 @@ +From 63f45b182c53fa98727f37d6ef9ff7e5b4d1ed06 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 17 Apr 2024 11:39:25 +0200 +Subject: [PATCH] urlapi: add CURLU_GET_EMPTY for empty queries and fragments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By default the API inhibits empty queries and fragments extracted. +Unless this new flag is set. + +This also makes the behavior more consistent: without it set, zero +length queries and fragments are considered not present in the URL. With +the flag set, they are returned as a zero length strings if they were in +fact present in the URL. + +This applies when extracting the individual query and fragment +components and for the full URL. + +Closes #13396 + +Upstream-Status: Backport [https://github.com/curl/curl/commit/3eac21d86bc50ba459a9a8a0f3d1130b6d30b57d] + +Signed-off-by: João Marcos Costa +--- + docs/libcurl/curl_url_get.md | 12 ++++++++++ + docs/libcurl/symbols-in-versions | 1 + + include/curl/urlapi.h | 3 +++ + lib/urlapi.c | 37 +++++++++++++++++++++------- + tests/data/test1201 | 4 ++-- + tests/libtest/lib1560.c | 41 ++++++++++++++++++++++++++++++++ + 6 files changed, 88 insertions(+), 10 deletions(-) + +diff --git a/docs/libcurl/curl_url_get.md b/docs/libcurl/curl_url_get.md +index 2f3b89b5e5..100eea7f52 100644 +--- a/docs/libcurl/curl_url_get.md ++++ b/docs/libcurl/curl_url_get.md +@@ -113,6 +113,18 @@ punycode. + + (Added in curl 8.3.0) + ++## CURLU_GET_EMPTY ++ ++When this flag is used in curl_url_get(), it makes the function return empty ++query and fragments parts or when used in the full URL. By default, libcurl ++otherwise considers empty parts non-existing. ++ ++An empty query part is one where this is nothing following the question mark ++(before the possible fragment). An empty fragments part is one where there is ++nothing following the hash sign. ++ ++(Added in curl 8.8.0) ++ + # PARTS + + ## CURLUPART_URL +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index a627dd68b6..2a9a0ff6f5 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -1062,6 +1062,7 @@ CURLU_APPENDQUERY 7.62.0 + CURLU_DEFAULT_PORT 7.62.0 + CURLU_DEFAULT_SCHEME 7.62.0 + CURLU_DISALLOW_USER 7.62.0 ++CURLU_GET_EMPTY 8.8.0 + CURLU_GUESS_SCHEME 7.62.0 + CURLU_NO_AUTHORITY 7.67.0 + CURLU_NO_DEFAULT_PORT 7.62.0 +diff --git a/include/curl/urlapi.h b/include/curl/urlapi.h +index 91f8c4548a..19388c3c01 100644 +--- a/include/curl/urlapi.h ++++ b/include/curl/urlapi.h +@@ -99,6 +99,9 @@ typedef enum { + #define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */ + #define CURLU_PUNYCODE (1<<12) /* get the host name in punycode */ + #define CURLU_PUNY2IDN (1<<13) /* punycode => IDN conversion */ ++#define CURLU_GET_EMPTY (1<<14) /* allow empty queries and fragments ++ when extracting the URL or the ++ components */ + + typedef struct Curl_URL CURLU; + +diff --git a/lib/urlapi.c b/lib/urlapi.c +index dc42489722..a7abd0b248 100644 +--- a/lib/urlapi.c ++++ b/lib/urlapi.c +@@ -79,7 +79,9 @@ struct Curl_URL { + char *path; + char *query; + char *fragment; +- long portnum; /* the numerical version */ ++ unsigned short portnum; /* the numerical version */ ++ BIT(query_present); /* to support blank */ ++ BIT(fragment_present); /* to support blank */ + }; + + #define DEFAULT_SCHEME "https" +@@ -558,7 +560,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host, + if(rest[0]) + return CURLUE_BAD_PORT_NUMBER; + +- u->portnum = port; ++ u->portnum = (unsigned short) port; + /* generate a new port number string to get rid of leading zeroes etc */ + free(u->port); + u->port = aprintf("%ld", port); +@@ -1242,6 +1244,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) + fragment = strchr(path, '#'); + if(fragment) { + fraglen = pathlen - (fragment - path); ++ u->fragment_present = TRUE; + if(fraglen > 1) { + /* skip the leading '#' in the copy but include the terminating null */ + if(flags & CURLU_URLENCODE) { +@@ -1269,6 +1272,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) + size_t qlen = fragment ? (size_t)(fragment - query) : + pathlen - (query - path); + pathlen -= qlen; ++ u->query_present = TRUE; + if(qlen > 1) { + if(flags & CURLU_URLENCODE) { + struct dynbuf enc; +@@ -1404,6 +1408,8 @@ CURLU *curl_url_dup(const CURLU *in) + DUP(u, in, fragment); + DUP(u, in, zoneid); + u->portnum = in->portnum; ++ u->fragment_present = in->fragment_present; ++ u->query_present = in->query_present; + } + return u; + fail: +@@ -1488,10 +1494,16 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, + ptr = u->query; + ifmissing = CURLUE_NO_QUERY; + plusdecode = urldecode; ++ if(ptr && !ptr[0] && !(flags & CURLU_GET_EMPTY)) ++ /* there was a blank query and the user do not ask for it */ ++ ptr = NULL; + break; + case CURLUPART_FRAGMENT: + ptr = u->fragment; + ifmissing = CURLUE_NO_FRAGMENT; ++ if(!ptr && u->fragment_present && flags & CURLU_GET_EMPTY) ++ /* there was a blank fragment and the user asks for it */ ++ ptr = ""; + break; + case CURLUPART_URL: { + char *url; +@@ -1499,13 +1511,18 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, + char *options = u->options; + char *port = u->port; + char *allochost = NULL; ++ bool show_fragment = ++ u->fragment || (u->fragment_present && flags & CURLU_GET_EMPTY); ++ bool show_query = ++ (u->query && u->query[0]) || ++ (u->query_present && flags & CURLU_GET_EMPTY); + punycode = (flags & CURLU_PUNYCODE)?1:0; + depunyfy = (flags & CURLU_PUNY2IDN)?1:0; + if(u->scheme && strcasecompare("file", u->scheme)) { + url = aprintf("file://%s%s%s", + u->path, +- u->fragment? "#": "", +- u->fragment? u->fragment : ""); ++ show_fragment ? "#": "", ++ u->fragment ? u->fragment : ""); + } + else if(!u->host) + return CURLUE_NO_HOST; +@@ -1593,9 +1610,9 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, + port ? ":": "", + port ? port : "", + u->path ? u->path : "/", +- (u->query && u->query[0]) ? "?": "", +- (u->query && u->query[0]) ? u->query : "", +- u->fragment? "#": "", ++ show_query ? "?": "", ++ u->query ? u->query : "", ++ show_fragment ? "#": "", + u->fragment? u->fragment : ""); + free(allochost); + } +@@ -1730,9 +1747,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, + break; + case CURLUPART_QUERY: + storep = &u->query; ++ u->query_present = FALSE; + break; + case CURLUPART_FRAGMENT: + storep = &u->fragment; ++ u->fragment_present = FALSE; + break; + default: + return CURLUE_UNKNOWN_PART; +@@ -1816,9 +1835,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, + appendquery = (flags & CURLU_APPENDQUERY)?1:0; + equalsencode = appendquery; + storep = &u->query; ++ u->query_present = TRUE; + break; + case CURLUPART_FRAGMENT: + storep = &u->fragment; ++ u->fragment_present = TRUE; + break; + case CURLUPART_URL: { + /* +@@ -1969,6 +1990,6 @@ nomem: + /* set after the string, to make it not assigned if the allocation above + fails */ + if(port) +- u->portnum = port; ++ u->portnum = (unsigned short)port; + return CURLUE_OK; + } +diff --git a/tests/data/test1201 b/tests/data/test1201 +index 296e7fa6a0..f4c1a48386 100644 +--- a/tests/data/test1201 ++++ b/tests/data/test1201 +@@ -25,7 +25,7 @@ gopher + Gopher selector + + +-gopher://%HOSTIP:%GOPHERPORT/1/selector/SELECTOR/%TESTNUMBER? ++gopher://%HOSTIP:%GOPHERPORT/1/selector/SELECTOR/%TESTNUMBER + + + +@@ -33,7 +33,7 @@ gopher://%HOSTIP:%GOPHERPORT/1/selector/SELECTOR/%TESTNUMBER? + # Verify data after the test has been "shot" + + +-/selector/SELECTOR/%TESTNUMBER? ++/selector/SELECTOR/%TESTNUMBER + + + +diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c +index 1509c76a7f..2a26874e54 100644 +--- a/tests/libtest/lib1560.c ++++ b/tests/libtest/lib1560.c +@@ -151,6 +151,21 @@ struct clearurlcase { + }; + + static const struct testcase get_parts_list[] ={ ++ {"https://curl.se/#", ++ "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | ", ++ 0, CURLU_GET_EMPTY, CURLUE_OK}, ++ {"https://curl.se/?#", ++ "https | [11] | [12] | [13] | curl.se | [15] | / | | ", ++ 0, CURLU_GET_EMPTY, CURLUE_OK}, ++ {"https://curl.se/?", ++ "https | [11] | [12] | [13] | curl.se | [15] | / | | [17]", ++ 0, CURLU_GET_EMPTY, CURLUE_OK}, ++ {"https://curl.se/?", ++ "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | [17]", ++ 0, 0, CURLUE_OK}, ++ {"https://curl.se/?#", ++ "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | [17]", ++ 0, 0, CURLUE_OK}, + {"https://curl.se/# ", + "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | %20%20", + CURLU_URLENCODE|CURLU_ALLOW_SPACE, 0, CURLUE_OK}, +@@ -508,6 +523,20 @@ static const struct testcase get_parts_list[] ={ + }; + + static const struct urltestcase get_url_list[] = { ++ {"http://user@example.com?#", ++ "http://user@example.com/?#", ++ 0, CURLU_GET_EMPTY, CURLUE_OK}, ++ /* WHATWG disgrees, it wants "https:/0.0.0.0/" */ ++ {"https://0x.0x.0", "https://0x.0x.0/", 0, 0, CURLUE_OK}, ++ ++ {"https://example.com:000000000000000000000443/foo", ++ "https://example.com/foo", ++ 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, ++ {"https://example.com:000000000000000000000/foo", ++ "https://example.com:0/foo", ++ 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, ++ {"https://192.0x0000A80001", "https://192.168.0.1/", 0, 0, CURLUE_OK}, ++ {"https://0xffffffff", "https://255.255.255.255/", 0, 0, CURLUE_OK}, + {"https://1.0x1000000", "https://1.0x1000000/", 0, 0, CURLUE_OK}, + {"https://0x7f.1", "https://127.0.0.1/", 0, 0, CURLUE_OK}, + {"https://1.2.3.256.com", "https://1.2.3.256.com/", 0, 0, CURLUE_OK}, +@@ -770,6 +799,18 @@ static int checkurl(const char *org, const char *url, const char *out) + 3. Extract all components (not URL) + */ + static const struct setgetcase setget_parts_list[] = { ++ {"https://example.com/", ++ "query=\"\",", ++ "https | [11] | [12] | [13] | example.com | [15] | / | | [17]", ++ 0, 0, CURLU_GET_EMPTY, CURLUE_OK}, ++ {"https://example.com/", ++ "fragment=\"\",", ++ "https | [11] | [12] | [13] | example.com | [15] | / | [16] | ", ++ 0, 0, CURLU_GET_EMPTY, CURLUE_OK}, ++ {"https://example.com/", ++ "query=\"\",", ++ "https | [11] | [12] | [13] | example.com | [15] | / | [16] | [17]", ++ 0, 0, 0, CURLUE_OK}, + {"https://example.com", + "path=get,", + "https | [11] | [12] | [13] | example.com | [15] | /get | [16] | [17]", diff --git a/meta/recipes-support/curl/curl/CVE-2026-94266.patch b/meta/recipes-support/curl/curl/CVE-2026-94266.patch new file mode 100644 index 0000000000..0ef6e0c07c --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2026-94266.patch @@ -0,0 +1,222 @@ +From 91b6ecabaed3a6400d5d1a86990a3fec9ccbe09c Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 21 Sep 2026 11:13:13 +0200 +Subject: [PATCH] getinfo: make sure CURLINFO_EFFECTIVE_URL does not contain + creds +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reported-by: Joshua Rogers + +Verified in test 1876 + +Closes #23016 + +CVE: CVE-2026-94266 +Upstream-Status: Backport [https://github.com/curl/curl/commit/7a6bd027d0de2b6857472d35da090ef60cc29f19] + +Signed-off-by: João Marcos Costa +--- + lib/getinfo.c | 45 +++++++++++++++++++++++++-- + lib/transfer.c | 1 + + lib/url.c | 1 + + lib/urldata.h | 1 + + tests/data/Makefile.inc | 2 +- + tests/data/test1876 | 67 +++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 114 insertions(+), 3 deletions(-) + create mode 100644 tests/data/test1876 + +diff --git a/lib/getinfo.c b/lib/getinfo.c +index dd43643d8b..d972e081d8 100644 +--- a/lib/getinfo.c ++++ b/lib/getinfo.c +@@ -73,6 +73,9 @@ CURLcode Curl_initinfo(struct Curl_easy *data) + free(info->contenttype); + info->contenttype = NULL; + ++ free(info->effective_url); ++ info->effective_url= NULL; ++ + free(info->wouldredirect); + info->wouldredirect = NULL; + +@@ -91,13 +94,51 @@ CURLcode Curl_initinfo(struct Curl_easy *data) + return CURLE_OK; + } + ++static CURLcode effective_url(struct Curl_easy *data, ++ const char **param_charp) ++{ ++ const char *s = data->state.url; ++ *param_charp = s ? s : ""; ++ if(s) { ++ char *url = NULL; ++ /* Make a copy of the URL without credentials */ ++ CURLU *u = curl_url(); ++ CURLUcode uc; ++ if(!u) ++ return CURLE_OUT_OF_MEMORY; ++ ++ uc = curl_url_set(u, CURLUPART_URL, s, ++ CURLU_NON_SUPPORT_SCHEME | ++ (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_USER, NULL, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); ++ if(!uc) ++ uc = curl_url_get(u, CURLUPART_URL, &url, CURLU_GET_EMPTY); ++ ++ curl_url_cleanup(u); ++ ++ if(uc || !url) ++ return CURLE_OUT_OF_MEMORY; ++ if(strcmp(url, s)) { ++ /* they are different */ ++ free(data->info.effective_url); ++ data->info.effective_url = url; ++ *param_charp = url; ++ } ++ else ++ curl_free(url); ++ } ++ return CURLE_OK; ++} ++ + static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info, + const char **param_charp) + { + switch(info) { + case CURLINFO_EFFECTIVE_URL: +- *param_charp = data->state.url?data->state.url:(char *)""; +- break; ++ return effective_url(data, param_charp); + case CURLINFO_EFFECTIVE_METHOD: { + const char *m = data->set.str[STRING_CUSTOMREQUEST]; + if(!m) { +diff --git a/lib/transfer.c b/lib/transfer.c +index a73462928d..d4550f8184 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -645,6 +645,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) + data->state.authhost.want = data->set.httpauth; + data->state.authproxy.want = data->set.proxyauth; + Curl_safefree(data->info.wouldredirect); ++ Curl_safefree(data->info.effective_url); + Curl_data_priority_clear_state(data); + + if(data->state.httpreq == HTTPREQ_PUT) +diff --git a/lib/url.c b/lib/url.c +index 9e1ca0336c..5153406287 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -291,6 +291,7 @@ CURLcode Curl_close(struct Curl_easy **datap) + #endif + Curl_safefree(data->info.contenttype); + Curl_safefree(data->info.wouldredirect); ++ Curl_safefree(data->info.effective_url); + + /* this destroys the channel and we cannot use it anymore after this */ + Curl_resolver_cancel(data); +diff --git a/lib/urldata.h b/lib/urldata.h +index 4fc595a639..7c5a3daa67 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1031,6 +1031,7 @@ struct PureInfo { + long numconnects; /* how many new connection did libcurl created */ + char *contenttype; /* the content type of the object */ + char *wouldredirect; /* URL this would've been redirected to if asked to */ ++ char *effective_url; /* when needed */ + curl_off_t retry_after; /* info from Retry-After: header */ + unsigned int header_size; /* size of read header(s) in bytes */ + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 9efae9cefe..9d4f9281d0 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -219,7 +219,7 @@ test1680 test1681 test1682 test1683 \ + \ + test1700 test1701 test1702 test1703 test1704 \ + \ +-test1800 test1801 \ ++test1800 test1801 test1876 \ + \ + test1900 test1903 test1904 test1905 test1906 test1907 \ + test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \ +diff --git a/tests/data/test1876 b/tests/data/test1876 +new file mode 100644 +index 0000000000..4fc3b9fd02 +--- /dev/null ++++ b/tests/data/test1876 +@@ -0,0 +1,67 @@ ++ ++ ++ ++ ++netrc ++ ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 301 redir ++Content-Length: 0 ++Content-Type: text/html ++Location: %TESTNUMBER0002 ++ ++ ++ ++ ++HTTP/1.1 200 OK ++Content-Length: 0 ++Content-Type: text/html ++ ++ ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++verify no credentials present in effective URL after redirect ++ ++ ++machine %HOSTIP ++login netrcuser ++password netrcSECRET123 ++ ++ ++ ++http://%HOSTIP:%HTTPPORT/%TESTNUMBER --netrc-optional --netrc-file %LOGDIR/netrc -L -w 'EFFECTIVE_URL=%{url_effective}\n' ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++GET /%TESTNUMBER HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++Authorization: Basic %b64[netrcuser:netrcSECRET123]b64% ++User-Agent: curl/%VERSION ++Accept: */* ++ ++GET /%TESTNUMBER0002 HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++Authorization: Basic %b64[netrcuser:netrcSECRET123]b64% ++User-Agent: curl/%VERSION ++Accept: */* ++ ++ ++ ++EFFECTIVE_URL=http://%HOSTIP:%HTTPPORT/%TESTNUMBER0002 ++ ++ ++ +-- +2.55.0 + diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index 3bd1b92d44..90ec2cd9d8 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb @@ -49,6 +49,8 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2026-92386.patch \ file://CVE-2026-92389.patch \ file://CVE-2026-92391.patch \ + file://CVE-2026-94266-pre.patch \ + file://CVE-2026-94266.patch \ " SRC_URI:append:class-nativesdk = " \