Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.6:Update
curl.27750
curl-CVE-2023-23914-23915.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File curl-CVE-2023-23914-23915.patch of Package curl.27750
From 873b0a13946c6d373d2f5c445134abe70a91e8ed Mon Sep 17 00:00:00 2001 From: Daniel Stenberg <daniel@haxx.se> Date: Tue, 27 Dec 2022 11:50:20 +0100 Subject: [PATCH 1/5] share: add sharing of HSTS cache among handles Closes #10138 --- docs/libcurl/opts/CURLSHOPT_SHARE.3 | 4 +++ docs/libcurl/symbols-in-versions | 1 + include/curl/curl.h | 1 + lib/hsts.c | 15 +++++++++ lib/hsts.h | 2 ++ lib/setopt.c | 48 ++++++++++++++++++++++++----- lib/share.c | 32 +++++++++++++++++-- lib/share.h | 6 +++- lib/transfer.c | 3 ++ lib/url.c | 6 +++- lib/urldata.h | 2 ++ 11 files changed, 109 insertions(+), 11 deletions(-) Index: curl-7.79.1/docs/libcurl/symbols-in-versions =================================================================== --- curl-7.79.1.orig/docs/libcurl/symbols-in-versions +++ curl-7.79.1/docs/libcurl/symbols-in-versions @@ -943,6 +943,7 @@ CURL_LOCK_ACCESS_SINGLE 7.10.3 CURL_LOCK_DATA_CONNECT 7.10.3 CURL_LOCK_DATA_COOKIE 7.10.3 CURL_LOCK_DATA_DNS 7.10.3 +CURL_LOCK_DATA_HSTS 7.88.0 CURL_LOCK_DATA_NONE 7.10.3 CURL_LOCK_DATA_PSL 7.61.0 CURL_LOCK_DATA_SHARE 7.10.4 Index: curl-7.79.1/include/curl/curl.h =================================================================== --- curl-7.79.1.orig/include/curl/curl.h +++ curl-7.79.1/include/curl/curl.h @@ -2821,6 +2821,7 @@ typedef enum { CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_DATA_CONNECT, CURL_LOCK_DATA_PSL, + CURL_LOCK_DATA_HSTS, CURL_LOCK_DATA_LAST } curl_lock_data; Index: curl-7.79.1/lib/hsts.c =================================================================== --- curl-7.79.1.orig/lib/hsts.c +++ curl-7.79.1/lib/hsts.c @@ -38,6 +38,7 @@ #include "rand.h" #include "rename.h" #include "strtoofft.h" +#include "share.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -414,14 +415,23 @@ static CURLcode hsts_add(struct hsts *h, if(2 == rc) { time_t expires = strcmp(date, UNLIMITED) ? Curl_getdate_capped(date) : TIME_T_MAX; - CURLcode result; + CURLcode result = CURLE_OK; char *p = host; bool subdomain = FALSE; + struct stsentry *e; if(p[0] == '.') { p++; subdomain = TRUE; } - result = hsts_create(h, p, subdomain, expires); + /* only add it if not already present */ + e = Curl_hsts(h, p, subdomain); + if(!e) + result = hsts_create(h, p, subdomain, expires); + else { + /* the same host name, use the largest expire time */ + if(expires > e->expires) + e->expires = expires; + } if(result) return result; } @@ -541,4 +551,18 @@ CURLcode Curl_hsts_loadcb(struct Curl_ea return CURLE_OK; } +void Curl_hsts_loadfiles(struct Curl_easy *data) +{ + struct curl_slist *l = data->set.hstslist; + if(l) { + Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE); + + while(l) { + (void)Curl_hsts_loadfile(data, data->hsts, l->data); + l = l->next; + } + Curl_share_unlock(data, CURL_LOCK_DATA_HSTS); + } +} + #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ Index: curl-7.79.1/lib/hsts.h =================================================================== --- curl-7.79.1.orig/lib/hsts.h +++ curl-7.79.1/lib/hsts.h @@ -57,9 +57,11 @@ CURLcode Curl_hsts_loadfile(struct Curl_ struct hsts *h, const char *file); CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h); +void Curl_hsts_loadfiles(struct Curl_easy *data); #else #define Curl_hsts_cleanup(x) #define Curl_hsts_loadcb(x,y) CURLE_OK #define Curl_hsts_save(x,y,z) +#define Curl_hsts_loadfiles(x) #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ #endif /* HEADER_CURL_HSTS_H */ Index: curl-7.79.1/lib/setopt.c =================================================================== --- curl-7.79.1.orig/lib/setopt.c +++ curl-7.79.1/lib/setopt.c @@ -2230,9 +2230,14 @@ CURLcode Curl_vsetopt(struct Curl_easy * data->cookies = NULL; #endif +#ifndef CURL_DISABLE_HSTS + if(data->share->hsts == data->hsts) + data->hsts = NULL; +#endif +#ifdef USE_SSL if(data->share->sslsession == data->state.session) data->state.session = NULL; - +#endif #ifdef USE_LIBPSL if(data->psl == &data->share->psl) data->psl = data->multi? &data->multi->psl: NULL; @@ -2266,10 +2271,19 @@ CURLcode Curl_vsetopt(struct Curl_easy * data->cookies = data->share->cookies; } #endif /* CURL_DISABLE_HTTP */ +#ifndef CURL_DISABLE_HSTS + if(data->share->hsts) { + /* first free the private one if any */ + Curl_hsts_cleanup(&data->hsts); + data->hsts = data->share->hsts; + } +#endif /* CURL_DISABLE_HTTP */ +#ifdef USE_SSL if(data->share->sslsession) { data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions; data->state.session = data->share->sslsession; } +#endif #ifdef USE_LIBPSL if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL)) data->psl = &data->share->psl; @@ -2958,19 +2972,39 @@ CURLcode Curl_vsetopt(struct Curl_easy * case CURLOPT_HSTSWRITEDATA: data->set.hsts_write_userp = va_arg(param, void *); break; - case CURLOPT_HSTS: + case CURLOPT_HSTS: { + struct curl_slist *h; if(!data->hsts) { data->hsts = Curl_hsts_init(); if(!data->hsts) return CURLE_OUT_OF_MEMORY; } argptr = va_arg(param, char *); - result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr); - if(result) - return result; - if(argptr) - (void)Curl_hsts_loadfile(data, data->hsts, argptr); + if(argptr) { + result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr); + if(result) + return result; + /* this needs to build a list of file names to read from, so that it can + read them later, as we might get a shared HSTS handle to load them + into */ + h = curl_slist_append(data->set.hstslist, argptr); + if(!h) { + curl_slist_free_all(data->set.hstslist); + data->set.hstslist = NULL; + return CURLE_OUT_OF_MEMORY; + } + data->set.hstslist = h; /* store the list for later use */ + } + else { + /* clear the list of HSTS files */ + curl_slist_free_all(data->set.hstslist); + data->set.hstslist = NULL; + if(!data->share || !data->share->hsts) + /* throw away the HSTS cache unless shared */ + Curl_hsts_cleanup(&data->hsts); + } break; + } case CURLOPT_HSTS_CTRL: arg = va_arg(param, long); if(arg & CURLHSTS_ENABLE) { Index: curl-7.79.1/lib/share.c =================================================================== --- curl-7.79.1.orig/lib/share.c +++ curl-7.79.1/lib/share.c @@ -27,9 +27,11 @@ #include "share.h" #include "psl.h" #include "vtls/vtls.h" -#include "curl_memory.h" +#include "hsts.h" -/* The last #include file should be: */ +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" #include "memdebug.h" struct Curl_share * @@ -91,6 +93,18 @@ curl_share_setopt(struct Curl_share *sha #endif break; + case CURL_LOCK_DATA_HSTS: +#ifndef CURL_DISABLE_HSTS + if(!share->hsts) { + share->hsts = Curl_hsts_init(); + if(!share->hsts) + res = CURLSHE_NOMEM; + } +#else /* CURL_DISABLE_HSTS */ + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + case CURL_LOCK_DATA_SSL_SESSION: #ifdef USE_SSL if(!share->sslsession) { @@ -143,6 +157,16 @@ curl_share_setopt(struct Curl_share *sha #endif break; + case CURL_LOCK_DATA_HSTS: +#ifndef CURL_DISABLE_HSTS + if(share->hsts) { + Curl_hsts_cleanup(&share->hsts); + } +#else /* CURL_DISABLE_HSTS */ + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + case CURL_LOCK_DATA_SSL_SESSION: #ifdef USE_SSL Curl_safefree(share->sslsession); @@ -209,6 +233,10 @@ curl_share_cleanup(struct Curl_share *sh Curl_cookie_cleanup(share->cookies); #endif +#ifndef CURL_DISABLE_HSTS + Curl_hsts_cleanup(&share->hsts); +#endif + #ifdef USE_SSL if(share->sslsession) { size_t i; Index: curl-7.79.1/lib/share.h =================================================================== --- curl-7.79.1.orig/lib/share.h +++ curl-7.79.1/lib/share.h @@ -57,10 +57,14 @@ struct Curl_share { #ifdef USE_LIBPSL struct PslCache psl; #endif - +#ifndef CURL_DISABLE_HSTS + struct hsts *hsts; +#endif +#ifdef USE_SSL struct Curl_ssl_session *sslsession; size_t max_ssl_sessions; long sessionage; +#endif }; CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data, Index: curl-7.79.1/lib/transfer.c =================================================================== --- curl-7.79.1.orig/lib/transfer.c +++ curl-7.79.1/lib/transfer.c @@ -1468,6 +1468,9 @@ CURLcode Curl_pretransfer(struct Curl_ea if(data->state.resolve) result = Curl_loadhostpairs(data); + /* If there is a list of hsts files to read */ + Curl_hsts_loadfiles(data); + if(!result) { /* Allow data->set.use_port to set which port to use. This needs to be * disabled for example when we follow Location: headers to URLs using Index: curl-7.79.1/lib/url.c =================================================================== --- curl-7.79.1.orig/lib/url.c +++ curl-7.79.1/lib/url.c @@ -427,7 +427,11 @@ CURLcode Curl_close(struct Curl_easy **d Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]); Curl_altsvc_cleanup(&data->asi); Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]); - Curl_hsts_cleanup(&data->hsts); +#ifndef CURL_DISABLE_HSTS + if(!data->share || !data->share->hsts) + Curl_hsts_cleanup(&data->hsts); + curl_slist_free_all(data->set.hstslist); /* clean up list */ +#endif #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) Curl_http_auth_cleanup_digest(data); #endif Index: curl-7.79.1/lib/urldata.h =================================================================== --- curl-7.79.1.orig/lib/urldata.h +++ curl-7.79.1/lib/urldata.h @@ -1670,6 +1670,8 @@ struct UserDefined { /* function to convert from UTF-8 encoding: */ curl_conv_callback convfromutf8; #ifndef CURL_DISABLE_HSTS + struct curl_slist *hstslist; /* list of HSTS files set by + curl_easy_setopt(HSTS) calls */ curl_hstsread_callback hsts_read; void *hsts_read_userp; curl_hstswrite_callback hsts_write; Index: curl-7.79.1/src/tool_operate.c =================================================================== --- curl-7.79.1.orig/src/tool_operate.c +++ curl-7.79.1/src/tool_operate.c @@ -2595,6 +2595,7 @@ CURLcode operate(struct GlobalConfig *gl curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_PSL); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_HSTS); /* Get the required arguments for each operation */ do { Index: curl-7.79.1/tests/FILEFORMAT.md =================================================================== --- curl-7.79.1.orig/tests/FILEFORMAT.md +++ curl-7.79.1/tests/FILEFORMAT.md @@ -527,14 +527,14 @@ changing protocol data such as port numb One perl op per line that operates on the protocol dump. This is pretty advanced. Example: `s/^EPRT .*/EPRT stripped/`. -### `<protocol [nonewline="yes"]>` +### `<protocol [nonewline="yes"][crlf="yes"]>` the protocol dump curl should transmit, if 'nonewline' is set, we will cut off the trailing newline of this given data before comparing with the one actually sent by the client The `<strip>` and `<strippart>` rules are applied before comparisons are made. -### `<proxy [nonewline="yes"]>` +### `<proxy [nonewline="yes"][crlf="yes"]>` The protocol dump curl should transmit to a HTTP proxy (when the http-proxy server is used), if 'nonewline' is set, we will cut off the trailing newline Index: curl-7.79.1/tests/runtests.pl =================================================================== --- curl-7.79.1.orig/tests/runtests.pl +++ curl-7.79.1/tests/runtests.pl @@ -4486,6 +4486,11 @@ sub singletest { } } + if($hash{'crlf'} || + ($has_hyper && ($keywords{"HTTP"} || $keywords{"HTTPS"}))) { + map subNewlines(0, \$_), @protstrip; + } + $res = compare($testnum, $testname, "proxy", \@out, \@protstrip); if($res) { return $errorreturncode; Index: curl-7.79.1/tests/data/Makefile.inc =================================================================== --- curl-7.79.1.orig/tests/data/Makefile.inc +++ curl-7.79.1/tests/data/Makefile.inc @@ -68,6 +68,7 @@ test400 test401 test402 test403 test404 test409 test410 \ \ test430 test431 test432 test433 test434 test435 \ +test446 \ \ test490 test491 test492 test493 test494 \ \ Index: curl-7.79.1/tests/data/test446 =================================================================== --- /dev/null +++ curl-7.79.1/tests/data/test446 @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<testcase> +<info> +<keywords> +HTTP +HTTP proxy +HSTS +trailing-dot +</keywords> +</info> + +<reply> + +# we use this as response to a CONNECT +<connect nocheck="yes"> +HTTP/1.1 200 OK + +</connect> +<data crlf="yes"> +HTTP/1.1 200 OK +Content-Length: 6 +Strict-Transport-Security: max-age=604800 + +-foo- +</data> +<data2 crlf="yes"> +HTTP/1.1 200 OK +Content-Length: 6 +Strict-Transport-Security: max-age=6048000 + +-baa- +</data2> +</reply> + +<client> +<server> +https +http-proxy +</server> +<features> +HSTS +proxy +https +debug +</features> +<setenv> +CURL_HSTS_HTTP=yes +CURL_TIME=2000000000 +</setenv> + +<name> +HSTS with two URLs +</name> +<command> +-x http://%HOSTIP:%PROXYPORT --hsts log/hsts%TESTNUMBER http://this.hsts.example./%TESTNUMBER http://another.example.com/%TESTNUMBER0002 +</command> +</client> + +<verify> +# we let it CONNECT to the server to confirm HSTS but deny from there +<proxy crlf="yes"> +GET http://this.hsts.example./%TESTNUMBER HTTP/1.1 +Host: this.hsts.example. +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + +GET http://another.example.com/%TESTNUMBER0002 HTTP/1.1 +Host: another.example.com +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + +</proxy> + +<file name="log/hsts%TESTNUMBER" mode="text"> +# Your HSTS cache. https://curl.se/docs/hsts.html +# This file was generated by libcurl! Edit at your own risk. +this.hsts.example "20330525 03:33:20" +another.example.com "20330727 03:33:20" +</file> + +</verify> +</testcase> Index: curl-7.79.1/docs/libcurl/curl_share_setopt.3 =================================================================== --- curl-7.79.1.orig/docs/libcurl/curl_share_setopt.3 +++ curl-7.79.1/docs/libcurl/curl_share_setopt.3 @@ -99,6 +99,9 @@ refreshed, this avoids updates in too ma Note that when you use the multi interface, all easy handles added to the same multi handle will share PSL cache by default without using this option. +.IP CURL_LOCK_DATA_HSTS +The in-memory HSTS cache. + .RE .IP CURLSHOPT_UNSHARE This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor