diff mbox series

[scarthgap,6/6] curl: Fix CVE-2026-12064

Message ID 20260904090007.27374-6-devanshp@cisco.com
State New
Headers show
Series [scarthgap,1/6] curl: Fix CVE-2026-8286 | expand

Commit Message

From: Devansh Patel <devanshp@cisco.com>

This patch applies the upstream fix as referenced in [2], using the
commit shown in [1]. The config2setopts.c change is adapted to curl
8.7.1's equivalent url_proto() implementation in tool_operate.c while
preserving upstream out-of-memory error propagation.

[1] https://github.com/curl/curl/commit/ab3bb8cd8be8f9d4acb97da0418abc279182041e
[2] https://curl.se/docs/CVE-2026-12064.html

Signed-off-by: Devansh Patel <devanshp@cisco.com>
---
 .../curl/curl/CVE-2026-12064.patch            | 258 ++++++++++++++++++
 meta/recipes-support/curl/curl_8.7.1.bb       |   1 +
 2 files changed, 259 insertions(+)
 create mode 100644 meta/recipes-support/curl/curl/CVE-2026-12064.patch
diff mbox series

Patch

diff --git a/meta/recipes-support/curl/curl/CVE-2026-12064.patch b/meta/recipes-support/curl/curl/CVE-2026-12064.patch
new file mode 100644
index 0000000000..4444401864
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2026-12064.patch
@@ -0,0 +1,258 @@ 
+From 1bdb3dbcc85bd754b8f5af73159decd926a0b7a4 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Fri, 12 Jun 2026 09:01:22 +0200
+Subject: [PATCH] config2setopts: use default protocol properly
+
+Verified by test 1724, 1725 and 2036
+
+Closes #21983
+
+CVE: CVE-2026-12064
+Upstream-Status: Backport [https://github.com/curl/curl/commit/ab3bb8cd8be8f9d4acb97da0418abc279182041e]
+
+Backport Changes:
+- Adapt the config2setopts.c change to curl 8.7.1's equivalent url_proto()
+  implementation in tool_operate.c. Since CURLU_NO_GUESS_SCHEME is not
+  available, parse without scheme guessing when --proto-default is set and
+  use the configured default only when the URL has no explicit scheme.
+- Preserve upstream error handling by propagating CURLUE_OUT_OF_MEMORY from
+  both curl_url_set() and curl_url_get() as CURLE_OUT_OF_MEMORY.
+- Register the regression tests in the target Makefile.inc. Renumber upstream
+  test2036 to test1726 because test2036 already exists in curl 8.7.1. Use
+  the target's %SSH_PWD substitution in test1725. Declare the no-server
+  test1726 explicitly because the older test harness requires it.
+
+(cherry picked from commit ab3bb8cd8be8f9d4acb97da0418abc279182041e)
+Signed-off-by: Devansh Patel <devanshp@cisco.com>
+---
+ docs/cmdline-opts/proto-default.md |  6 +++-
+ src/tool_operate.c                 | 45 +++++++++++++++----------
+ tests/data/Makefile.inc            |  1 +
+ tests/data/test1724                | 53 ++++++++++++++++++++++++++++++
+ tests/data/test1725                | 29 ++++++++++++++++
+ tests/data/test1726                | 29 ++++++++++++++++
+ 6 files changed, 144 insertions(+), 19 deletions(-)
+ create mode 100644 tests/data/test1724
+ create mode 100644 tests/data/test1725
+ create mode 100644 tests/data/test1726
+
+diff --git a/docs/cmdline-opts/proto-default.md b/docs/cmdline-opts/proto-default.md
+index 209e5cdc83..903fac73a5 100644
+--- a/docs/cmdline-opts/proto-default.md
++++ b/docs/cmdline-opts/proto-default.md
+@@ -16,7 +16,8 @@ Example:
+
+ # `--proto-default`
+
+-Use *protocol* for any provided URL missing a scheme.
++Use *protocol* for any provided URL missing a scheme. The case-insensitive
++name should be given without any `://` suffix.
+
+ An unknown or unsupported protocol causes error *CURLE_UNSUPPORTED_PROTOCOL*.
+
+@@ -24,3 +25,6 @@ This option does not change the default proxy protocol (http).
+
+ Without this option set, curl guesses protocol based on the hostname, see
+ --url for details.
++
++The default protocol cannot be set to `ipfs` or `ipns`. Those schemes need to
++be used explicitly in the URL.
+diff --git a/src/tool_operate.c b/src/tool_operate.c
+index 7e2c1eefe0..c8059a40d9 100644
+--- a/src/tool_operate.c
++++ b/src/tool_operate.c
+@@ -704,26 +704,35 @@ static CURLcode url_proto(char **url,
+     if(*url) {
+       char *schemep = NULL;
+
+-      if(!curl_url_set(uh, CURLUPART_URL, *url,
+-                       CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME) &&
+-         !curl_url_get(uh, CURLUPART_SCHEME, &schemep,
+-                       CURLU_DEFAULT_SCHEME)) {
+-        if(curl_strequal(schemep, proto_ipfs) ||
+-           curl_strequal(schemep, proto_ipns)) {
+-          result = ipfs_url_rewrite(uh, schemep, url, config);
+-          /* short-circuit proto_token, we know it's ipfs or ipns */
+-          if(curl_strequal(schemep, proto_ipfs))
+-            proto = proto_ipfs;
+-          else if(curl_strequal(schemep, proto_ipns))
+-            proto = proto_ipns;
+-          if(result)
+-            config->synthetic_error = TRUE;
++      CURLUcode uc =
++        curl_url_set(uh, CURLUPART_URL, *url,
++                     CURLU_NON_SUPPORT_SCHEME |
++                     (config->proto_default ? 0 : CURLU_GUESS_SCHEME));
++
++      if((uc == CURLUE_BAD_SCHEME) && config->proto_default)
++        proto = proto_token(config->proto_default);
++      else if(!uc) {
++        uc = curl_url_get(uh, CURLUPART_SCHEME, &schemep,
++                          CURLU_DEFAULT_SCHEME);
++        if(!uc) {
++          if(curl_strequal(schemep, proto_ipfs) ||
++             curl_strequal(schemep, proto_ipns)) {
++            result = ipfs_url_rewrite(uh, schemep, url, config);
++            /* short-circuit proto_token, we know it's ipfs or ipns */
++            if(curl_strequal(schemep, proto_ipfs))
++              proto = proto_ipfs;
++            else if(curl_strequal(schemep, proto_ipns))
++              proto = proto_ipns;
++            if(result)
++              config->synthetic_error = TRUE;
++          }
++          else
++            proto = proto_token(schemep);
+         }
+-        else
+-          proto = proto_token(schemep);
+-
+-        curl_free(schemep);
+       }
++      if(uc == CURLUE_OUT_OF_MEMORY)
++        result = CURLE_OUT_OF_MEMORY;
++      curl_free(schemep);
+     }
+     curl_url_cleanup(uh);
+   }
+diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
+index 9708e37b1f..da87400564 100644
+--- a/tests/data/Makefile.inc
++++ b/tests/data/Makefile.inc
+@@ -220,6 +220,7 @@ test1670 test1671 \
+ test1680 test1681 test1682 test1683 \
+ \
+ test1700 test1701 test1702 test1703 test1704 \
++test1724 test1725 test1726 \
+ \
+ test1800 test1801 \
+ \
+diff --git a/tests/data/test1724 b/tests/data/test1724
+new file mode 100644
+index 0000000000..3cd328e39c
+--- /dev/null
++++ b/tests/data/test1724
+@@ -0,0 +1,53 @@
++<?xml version="1.0" encoding="US-ASCII"?>
++<testcase>
++<info>
++<keywords>
++IPFS
++</keywords>
++</info>
++
++# Server-side
++<reply>
++<data nocheck="yes">
++HTTP/1.1 200 OK
++Date: Tue, 09 Nov 2010 14:49:00 GMT
++Server: test-server/fake
++Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
++ETag: "21025-dc7-39462498"
++Accept-Ranges: bytes
++Content-Length: 21
++Connection: close
++Content-Type: text/plain
++Funny-head: yesyes
++
++Hello curl from IPFS
++</data>
++</reply>
++
++# Client-side
++<client>
++<features>
++ipfs
++</features>
++<server>
++http
++</server>
++<name>
++IPFS with --proto-default HTTP
++</name>
++<command>
++--ipfs-gateway http://%HOSTIP:%HTTPPORT ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u --proto-default http
++</command>
++</client>
++
++# Verify data after the test has been "shot"
++<verify>
++<protocol crlf="headers">
++GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1
++Host: %HOSTIP:%HTTPPORT
++User-Agent: curl/%VERSION
++Accept: */*
++
++</protocol>
++</verify>
++</testcase>
+diff --git a/tests/data/test1725 b/tests/data/test1725
+new file mode 100644
+index 0000000000..e3b2c5abd2
+--- /dev/null
++++ b/tests/data/test1725
+@@ -0,0 +1,29 @@
++<?xml version="1.0" encoding="US-ASCII"?>
++<testcase>
++<info>
++<keywords>
++SCP
++server key check
++</keywords>
++</info>
++
++# Client-side
++<client>
++<server>
++scp
++</server>
++<name>
++SCP incorrect host key with --proto-default SCP
++</name>
++<command>
++--hostpubmd5 00000000000000000000000000000000 --key %LOGDIR/server/curl_client_key --pubkey %LOGDIR/server/curl_client_key.pub -u %USER: %HOSTIP:%SSHPORT%SSH_PWD/%LOGDIR/irrelevant-file --insecure --proto-default SCP
++</command>
++</client>
++
++# Verify data after the test has been "shot"
++<verify>
++<errorcode>
++60
++</errorcode>
++</verify>
++</testcase>
+diff --git a/tests/data/test1726 b/tests/data/test1726
+new file mode 100644
+index 0000000000..61f5b5dbd5
+--- /dev/null
++++ b/tests/data/test1726
+@@ -0,0 +1,29 @@
++<?xml version="1.0" encoding="US-ASCII"?>
++<testcase>
++<info>
++<keywords>
++--proto-default
++</keywords>
++</info>
++
++# Client-side
++<client>
++<server>
++none
++</server>
++<name>
++Attempt to set a default protocol with :// suffix
++</name>
++<command>
++--proto-default https://
++</command>
++</client>
++
++# Verify data after the test has been "shot"
++<verify>
++# CURLE_UNSUPPORTED_PROTOCOL is error code 1
++<errorcode>
++1
++</errorcode>
++</verify>
++</testcase>
diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb
index e9ba10cb97..267182aacd 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 = " \
     file://CVE-2026-8927.patch \
     file://CVE-2026-8932.patch \
     file://CVE-2026-9547.patch \
+    file://CVE-2026-12064.patch \
 "
 
 SRC_URI:append:class-nativesdk = " \