xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-support/curl/curl/CVE-2023-23914_5-1.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From 076a2f629119222aeeb50f5a03bf9f9052fabb9a Mon Sep 17 00:00:00 2001
2From: Daniel Stenberg <daniel@haxx.se>
3Date: Tue, 27 Dec 2022 11:50:20 +0100
4Subject: [PATCH] share: add sharing of HSTS cache among handles
5
6Closes #10138
7
8CVE: CVE-2023-23914 CVE-2023-23915
9Upstream-Status: Backport [https://github.com/curl/curl/commit/076a2f629119222aeeb50f5a03bf9f9052fabb9a]
10Comment: Refreshed hunk from hsts.c and urldata.h
11Signed-off-by: Pawan Badganchi <Pawan.Badganchi@kpit.com>
12Signed-off-by: Mingli Yu <mingli.yu@windriver.com>
13---
14 include/curl/curl.h                 |  1 +
15 lib/hsts.c                          | 15 +++++++++
16 lib/hsts.h                          |  2 ++
17 lib/setopt.c                        | 48 ++++++++++++++++++++++++-----
18 lib/share.c                         | 32 +++++++++++++++++--
19 lib/share.h                         |  6 +++-
20 lib/transfer.c                      |  3 ++
21 lib/url.c                           |  6 +++-
22 lib/urldata.h                       |  2 ++
23 9 files changed, 109 insertions(+), 11 deletions(-)
24
25--- a/include/curl/curl.h
26+++ b/include/curl/curl.h
27@@ -2953,6 +2953,7 @@ typedef enum {
28   CURL_LOCK_DATA_SSL_SESSION,
29   CURL_LOCK_DATA_CONNECT,
30   CURL_LOCK_DATA_PSL,
31+  CURL_LOCK_DATA_HSTS,
32   CURL_LOCK_DATA_LAST
33 } curl_lock_data;
34
35--- a/lib/hsts.c
36+++ b/lib/hsts.c
37@@ -37,6 +37,7 @@
38 #include "parsedate.h"
39 #include "rand.h"
40 #include "rename.h"
41+#include "share.h"
42 #include "strtoofft.h"
43
44 /* The last 3 #include files should be in this order */
45@@ -561,4 +562,18 @@
46   return CURLE_OK;
47 }
48
49+void Curl_hsts_loadfiles(struct Curl_easy *data)
50+{
51+  struct curl_slist *l = data->set.hstslist;
52+  if(l) {
53+    Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE);
54+
55+    while(l) {
56+      (void)Curl_hsts_loadfile(data, data->hsts, l->data);
57+      l = l->next;
58+    }
59+    Curl_share_unlock(data, CURL_LOCK_DATA_HSTS);
60+  }
61+}
62+
63 #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
64--- a/lib/hsts.h
65+++ b/lib/hsts.h
66@@ -59,9 +59,11 @@ CURLcode Curl_hsts_loadfile(struct Curl_
67                             struct hsts *h, const char *file);
68 CURLcode Curl_hsts_loadcb(struct Curl_easy *data,
69                           struct hsts *h);
70+void Curl_hsts_loadfiles(struct Curl_easy *data);
71 #else
72 #define Curl_hsts_cleanup(x)
73 #define Curl_hsts_loadcb(x,y) CURLE_OK
74 #define Curl_hsts_save(x,y,z)
75+#define Curl_hsts_loadfiles(x)
76 #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
77 #endif /* HEADER_CURL_HSTS_H */
78--- a/lib/setopt.c
79+++ b/lib/setopt.c
80@@ -2260,9 +2260,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *
81         data->cookies = NULL;
82 #endif
83
84+#ifndef CURL_DISABLE_HSTS
85+      if(data->share->hsts == data->hsts)
86+        data->hsts = NULL;
87+#endif
88+#ifdef USE_SSL
89       if(data->share->sslsession == data->state.session)
90         data->state.session = NULL;
91-
92+#endif
93 #ifdef USE_LIBPSL
94       if(data->psl == &data->share->psl)
95         data->psl = data->multi? &data->multi->psl: NULL;
96@@ -2296,10 +2301,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *
97         data->cookies = data->share->cookies;
98       }
99 #endif   /* CURL_DISABLE_HTTP */
100+#ifndef CURL_DISABLE_HSTS
101+      if(data->share->hsts) {
102+        /* first free the private one if any */
103+        Curl_hsts_cleanup(&data->hsts);
104+        data->hsts = data->share->hsts;
105+      }
106+#endif   /* CURL_DISABLE_HTTP */
107+#ifdef USE_SSL
108       if(data->share->sslsession) {
109         data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
110         data->state.session = data->share->sslsession;
111       }
112+#endif
113 #ifdef USE_LIBPSL
114       if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
115         data->psl = &data->share->psl;
116@@ -3049,19 +3063,39 @@ CURLcode Curl_vsetopt(struct Curl_easy *
117   case CURLOPT_HSTSWRITEDATA:
118     data->set.hsts_write_userp = va_arg(param, void *);
119     break;
120-  case CURLOPT_HSTS:
121+  case CURLOPT_HSTS: {
122+    struct curl_slist *h;
123     if(!data->hsts) {
124       data->hsts = Curl_hsts_init();
125       if(!data->hsts)
126         return CURLE_OUT_OF_MEMORY;
127     }
128     argptr = va_arg(param, char *);
129-    result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr);
130-    if(result)
131-      return result;
132-    if(argptr)
133-      (void)Curl_hsts_loadfile(data, data->hsts, argptr);
134+    if(argptr) {
135+      result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr);
136+      if(result)
137+        return result;
138+      /* this needs to build a list of file names to read from, so that it can
139+         read them later, as we might get a shared HSTS handle to load them
140+         into */
141+      h = curl_slist_append(data->set.hstslist, argptr);
142+      if(!h) {
143+        curl_slist_free_all(data->set.hstslist);
144+        data->set.hstslist = NULL;
145+        return CURLE_OUT_OF_MEMORY;
146+      }
147+      data->set.hstslist = h; /* store the list for later use */
148+    }
149+    else {
150+      /* clear the list of HSTS files */
151+      curl_slist_free_all(data->set.hstslist);
152+      data->set.hstslist = NULL;
153+      if(!data->share || !data->share->hsts)
154+        /* throw away the HSTS cache unless shared */
155+        Curl_hsts_cleanup(&data->hsts);
156+    }
157     break;
158+  }
159   case CURLOPT_HSTS_CTRL:
160     arg = va_arg(param, long);
161     if(arg & CURLHSTS_ENABLE) {
162--- a/lib/share.c
163+++ b/lib/share.c
164@@ -29,9 +29,11 @@
165 #include "share.h"
166 #include "psl.h"
167 #include "vtls/vtls.h"
168-#include "curl_memory.h"
169+#include "hsts.h"
170
171-/* The last #include file should be: */
172+/* The last 3 #include files should be in this order */
173+#include "curl_printf.h"
174+#include "curl_memory.h"
175 #include "memdebug.h"
176
177 struct Curl_share *
178@@ -89,6 +91,18 @@ curl_share_setopt(struct Curl_share *sha
179 #endif
180       break;
181
182+    case CURL_LOCK_DATA_HSTS:
183+#ifndef CURL_DISABLE_HSTS
184+      if(!share->hsts) {
185+        share->hsts = Curl_hsts_init();
186+        if(!share->hsts)
187+          res = CURLSHE_NOMEM;
188+      }
189+#else   /* CURL_DISABLE_HSTS */
190+      res = CURLSHE_NOT_BUILT_IN;
191+#endif
192+      break;
193+
194     case CURL_LOCK_DATA_SSL_SESSION:
195 #ifdef USE_SSL
196       if(!share->sslsession) {
197@@ -141,6 +155,16 @@ curl_share_setopt(struct Curl_share *sha
198 #endif
199       break;
200
201+    case CURL_LOCK_DATA_HSTS:
202+#ifndef CURL_DISABLE_HSTS
203+      if(share->hsts) {
204+        Curl_hsts_cleanup(&share->hsts);
205+      }
206+#else   /* CURL_DISABLE_HSTS */
207+      res = CURLSHE_NOT_BUILT_IN;
208+#endif
209+      break;
210+
211     case CURL_LOCK_DATA_SSL_SESSION:
212 #ifdef USE_SSL
213       Curl_safefree(share->sslsession);
214@@ -207,6 +231,10 @@ curl_share_cleanup(struct Curl_share *sh
215   Curl_cookie_cleanup(share->cookies);
216 #endif
217
218+#ifndef CURL_DISABLE_HSTS
219+  Curl_hsts_cleanup(&share->hsts);
220+#endif
221+
222 #ifdef USE_SSL
223   if(share->sslsession) {
224     size_t i;
225--- a/lib/share.h
226+++ b/lib/share.h
227@@ -59,10 +59,14 @@ struct Curl_share {
228 #ifdef USE_LIBPSL
229   struct PslCache psl;
230 #endif
231-
232+#ifndef CURL_DISABLE_HSTS
233+  struct hsts *hsts;
234+#endif
235+#ifdef USE_SSL
236   struct Curl_ssl_session *sslsession;
237   size_t max_ssl_sessions;
238   long sessionage;
239+#endif
240 };
241
242 CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data,
243--- a/lib/transfer.c
244+++ b/lib/transfer.c
245@@ -1398,6 +1398,9 @@ CURLcode Curl_pretransfer(struct Curl_ea
246   if(data->state.resolve)
247     result = Curl_loadhostpairs(data);
248
249+  /* If there is a list of hsts files to read */
250+  Curl_hsts_loadfiles(data);
251+
252   if(!result) {
253     /* Allow data->set.use_port to set which port to use. This needs to be
254      * disabled for example when we follow Location: headers to URLs using
255--- a/lib/url.c
256+++ b/lib/url.c
257@@ -434,7 +434,11 @@ CURLcode Curl_close(struct Curl_easy **d
258   Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
259   Curl_altsvc_cleanup(&data->asi);
260   Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]);
261-  Curl_hsts_cleanup(&data->hsts);
262+#ifndef CURL_DISABLE_HSTS
263+  if(!data->share || !data->share->hsts)
264+    Curl_hsts_cleanup(&data->hsts);
265+  curl_slist_free_all(data->set.hstslist); /* clean up list */
266+#endif
267 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
268   Curl_http_auth_cleanup_digest(data);
269 #endif
270--- a/lib/urldata.h
271+++ b/lib/urldata.h
272@@ -1670,6 +1670,8 @@
273
274   void *seek_client;    /* pointer to pass to the seek callback */
275 #ifndef CURL_DISABLE_HSTS
276+  struct curl_slist *hstslist; /* list of HSTS files set by
277+                                  curl_easy_setopt(HSTS) calls */
278   curl_hstsread_callback hsts_read;
279   void *hsts_read_userp;
280   curl_hstswrite_callback hsts_write;
281