diff options
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2023-28321.patch | 302 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl_7.82.0.bb | 1 |
2 files changed, 303 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2023-28321.patch b/meta/recipes-support/curl/curl/CVE-2023-28321.patch new file mode 100644 index 0000000000..bcd8b112db --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2023-28321.patch | |||
| @@ -0,0 +1,302 @@ | |||
| 1 | From 199f2d440d8659b42670c1b796220792b01a97bf Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Daniel Stenberg <daniel@haxx.se> | ||
| 3 | Date: Mon, 24 Apr 2023 21:07:02 +0200 | ||
| 4 | Subject: [PATCH] hostcheck: fix host name wildcard checking | ||
| 5 | |||
| 6 | The leftmost "label" of the host name can now only match against single | ||
| 7 | '*'. Like the browsers have worked for a long time. | ||
| 8 | |||
| 9 | - extended unit test 1397 for this | ||
| 10 | - move some SOURCE variables from unit/Makefile.am to unit/Makefile.inc | ||
| 11 | |||
| 12 | Reported-by: Hiroki Kurosawa | ||
| 13 | Closes #11018 | ||
| 14 | |||
| 15 | CVE: CVE-2023-28321 | ||
| 16 | Upstream-Status: Backport [https://github.com/curl/curl/commit/199f2d440d8659b42] | ||
| 17 | Comments: Hunks removed as changes already exist | ||
| 18 | Removed hunks from files: | ||
| 19 | tests/unit/Makefile.am | ||
| 20 | tests/unit/Makefile.inc | ||
| 21 | Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com> | ||
| 22 | --- | ||
| 23 | lib/vtls/hostcheck.c | 50 +++++++-------- | ||
| 24 | tests/data/test1397 | 10 ++- | ||
| 25 | tests/unit/Makefile.am | 94 ---------------------------- | ||
| 26 | tests/unit/Makefile.inc | 94 ++++++++++++++++++++++++++++ | ||
| 27 | tests/unit/unit1397.c | 134 ++++++++++++++++++++++++---------------- | ||
| 28 | 5 files changed, 202 insertions(+), 180 deletions(-) | ||
| 29 | |||
| 30 | diff --git a/lib/vtls/hostcheck.c b/lib/vtls/hostcheck.c | ||
| 31 | index e827dc58f378c..d061c6356f97f 100644 | ||
| 32 | --- a/lib/vtls/hostcheck.c | ||
| 33 | +++ b/lib/vtls/hostcheck.c | ||
| 34 | @@ -71,7 +71,12 @@ static bool pmatch(const char *hostname, size_t hostlen, | ||
| 35 | * apparent distinction between a name and an IP. We need to detect the use of | ||
| 36 | * an IP address and not wildcard match on such names. | ||
| 37 | * | ||
| 38 | + * Only match on "*" being used for the leftmost label, not "a*", "a*b" nor | ||
| 39 | + * "*b". | ||
| 40 | + * | ||
| 41 | * Return TRUE on a match. FALSE if not. | ||
| 42 | + * | ||
| 43 | + * @unittest: 1397 | ||
| 44 | */ | ||
| 45 | |||
| 46 | static bool hostmatch(const char *hostname, | ||
| 47 | @@ -79,53 +84,42 @@ static bool hostmatch(const char *hostname, | ||
| 48 | const char *pattern, | ||
| 49 | size_t patternlen) | ||
| 50 | { | ||
| 51 | - const char *pattern_label_end, *wildcard, *hostname_label_end; | ||
| 52 | - size_t prefixlen, suffixlen; | ||
| 53 | + const char *pattern_label_end; | ||
| 54 | |||
| 55 | - /* normalize pattern and hostname by stripping off trailing dots */ | ||
| 56 | + DEBUGASSERT(pattern); | ||
| 57 | DEBUGASSERT(patternlen); | ||
| 58 | + DEBUGASSERT(hostname); | ||
| 59 | + DEBUGASSERT(hostlen); | ||
| 60 | + | ||
| 61 | + /* normalize pattern and hostname by stripping off trailing dots */ | ||
| 62 | if(hostname[hostlen-1]=='.') | ||
| 63 | hostlen--; | ||
| 64 | if(pattern[patternlen-1]=='.') | ||
| 65 | patternlen--; | ||
| 66 | |||
| 67 | - wildcard = memchr(pattern, '*', patternlen); | ||
| 68 | - if(!wildcard) | ||
| 69 | + if(strncmp(pattern, "*.", 2)) | ||
| 70 | return pmatch(hostname, hostlen, pattern, patternlen); | ||
| 71 | |||
| 72 | /* detect IP address as hostname and fail the match if so */ | ||
| 73 | - if(Curl_host_is_ipnum(hostname)) | ||
| 74 | + else if(Curl_host_is_ipnum(hostname)) | ||
| 75 | return FALSE; | ||
| 76 | |||
| 77 | /* We require at least 2 dots in the pattern to avoid too wide wildcard | ||
| 78 | match. */ | ||
| 79 | pattern_label_end = memchr(pattern, '.', patternlen); | ||
| 80 | if(!pattern_label_end || | ||
| 81 | - (memrchr(pattern, '.', patternlen) == pattern_label_end) || | ||
| 82 | - strncasecompare(pattern, "xn--", 4)) | ||
| 83 | + (memrchr(pattern, '.', patternlen) == pattern_label_end)) | ||
| 84 | return pmatch(hostname, hostlen, pattern, patternlen); | ||
| 85 | - | ||
| 86 | - hostname_label_end = memchr(hostname, '.', hostlen); | ||
| 87 | - if(!hostname_label_end) | ||
| 88 | - return FALSE; | ||
| 89 | else { | ||
| 90 | - size_t skiphost = hostname_label_end - hostname; | ||
| 91 | - size_t skiplen = pattern_label_end - pattern; | ||
| 92 | - if(!pmatch(hostname_label_end, hostlen - skiphost, | ||
| 93 | - pattern_label_end, patternlen - skiplen)) | ||
| 94 | - return FALSE; | ||
| 95 | + const char *hostname_label_end = memchr(hostname, '.', hostlen); | ||
| 96 | + if(hostname_label_end) { | ||
| 97 | + size_t skiphost = hostname_label_end - hostname; | ||
| 98 | + size_t skiplen = pattern_label_end - pattern; | ||
| 99 | + return pmatch(hostname_label_end, hostlen - skiphost, | ||
| 100 | + pattern_label_end, patternlen - skiplen); | ||
| 101 | + } | ||
| 102 | } | ||
| 103 | - /* The wildcard must match at least one character, so the left-most | ||
| 104 | - label of the hostname is at least as large as the left-most label | ||
| 105 | - of the pattern. */ | ||
| 106 | - if(hostname_label_end - hostname < pattern_label_end - pattern) | ||
| 107 | - return FALSE; | ||
| 108 | - | ||
| 109 | - prefixlen = wildcard - pattern; | ||
| 110 | - suffixlen = pattern_label_end - (wildcard + 1); | ||
| 111 | - return strncasecompare(pattern, hostname, prefixlen) && | ||
| 112 | - strncasecompare(wildcard + 1, hostname_label_end - suffixlen, | ||
| 113 | - suffixlen) ? TRUE : FALSE; | ||
| 114 | + return FALSE; | ||
| 115 | } | ||
| 116 | |||
| 117 | /* | ||
| 118 | diff --git a/tests/data/test1397 b/tests/data/test1397 | ||
| 119 | index 84f962abebee3..f31b2c2a3f330 100644 | ||
| 120 | --- a/tests/data/test1397 | ||
| 121 | +++ b/tests/data/test1397 | ||
| 122 | @@ -2,8 +2,7 @@ | ||
| 123 | <info> | ||
| 124 | <keywords> | ||
| 125 | unittest | ||
| 126 | -ssl | ||
| 127 | -wildcard | ||
| 128 | +Curl_cert_hostcheck | ||
| 129 | </keywords> | ||
| 130 | </info> | ||
| 131 | |||
| 132 | @@ -16,9 +15,8 @@ none | ||
| 133 | <features> | ||
| 134 | unittest | ||
| 135 | </features> | ||
| 136 | - <name> | ||
| 137 | -Check wildcard certificate matching function Curl_cert_hostcheck | ||
| 138 | - </name> | ||
| 139 | +<name> | ||
| 140 | +Curl_cert_hostcheck unit tests | ||
| 141 | +</name> | ||
| 142 | </client> | ||
| 143 | - | ||
| 144 | </testcase> | ||
| 145 | diff --git a/tests/unit/unit1397.c b/tests/unit/unit1397.c | ||
| 146 | index 2f3d3aa4d09e1..3ae75618d5d10 100644 | ||
| 147 | --- a/tests/unit/unit1397.c | ||
| 148 | +++ b/tests/unit/unit1397.c | ||
| 149 | @@ -23,7 +23,6 @@ | ||
| 150 | ***************************************************************************/ | ||
| 151 | #include "curlcheck.h" | ||
| 152 | |||
| 153 | -#include "vtls/hostcheck.h" /* from the lib dir */ | ||
| 154 | |||
| 155 | static CURLcode unit_setup(void) | ||
| 156 | { | ||
| 157 | @@ -32,63 +31,94 @@ static CURLcode unit_setup(void) | ||
| 158 | |||
| 159 | static void unit_stop(void) | ||
| 160 | { | ||
| 161 | - /* done before shutting down and exiting */ | ||
| 162 | } | ||
| 163 | |||
| 164 | -UNITTEST_START | ||
| 165 | - | ||
| 166 | /* only these backends define the tested functions */ | ||
| 167 | -#if defined(USE_OPENSSL) || defined(USE_GSKIT) | ||
| 168 | - | ||
| 169 | - /* here you start doing things and checking that the results are good */ | ||
| 170 | +#if defined(USE_OPENSSL) || defined(USE_GSKIT) || defined(USE_SCHANNEL) | ||
| 171 | +#include "vtls/hostcheck.h" | ||
| 172 | +struct testcase { | ||
| 173 | + const char *host; | ||
| 174 | + const char *pattern; | ||
| 175 | + bool match; | ||
| 176 | +}; | ||
| 177 | |||
| 178 | -fail_unless(Curl_cert_hostcheck(STRCONST("www.example.com"), | ||
| 179 | - STRCONST("www.example.com")), "good 1"); | ||
| 180 | -fail_unless(Curl_cert_hostcheck(STRCONST("*.example.com"), | ||
| 181 | - STRCONST("www.example.com")), | ||
| 182 | - "good 2"); | ||
| 183 | -fail_unless(Curl_cert_hostcheck(STRCONST("xxx*.example.com"), | ||
| 184 | - STRCONST("xxxwww.example.com")), "good 3"); | ||
| 185 | -fail_unless(Curl_cert_hostcheck(STRCONST("f*.example.com"), | ||
| 186 | - STRCONST("foo.example.com")), "good 4"); | ||
| 187 | -fail_unless(Curl_cert_hostcheck(STRCONST("192.168.0.0"), | ||
| 188 | - STRCONST("192.168.0.0")), "good 5"); | ||
| 189 | +static struct testcase tests[] = { | ||
| 190 | + {"", "", FALSE}, | ||
| 191 | + {"a", "", FALSE}, | ||
| 192 | + {"", "b", FALSE}, | ||
| 193 | + {"a", "b", FALSE}, | ||
| 194 | + {"aa", "bb", FALSE}, | ||
| 195 | + {"\xff", "\xff", TRUE}, | ||
| 196 | + {"aa.aa.aa", "aa.aa.bb", FALSE}, | ||
| 197 | + {"aa.aa.aa", "aa.aa.aa", TRUE}, | ||
| 198 | + {"aa.aa.aa", "*.aa.bb", FALSE}, | ||
| 199 | + {"aa.aa.aa", "*.aa.aa", TRUE}, | ||
| 200 | + {"192.168.0.1", "192.168.0.1", TRUE}, | ||
| 201 | + {"192.168.0.1", "*.168.0.1", FALSE}, | ||
| 202 | + {"192.168.0.1", "*.0.1", FALSE}, | ||
| 203 | + {"h.ello", "*.ello", FALSE}, | ||
| 204 | + {"h.ello.", "*.ello", FALSE}, | ||
| 205 | + {"h.ello", "*.ello.", FALSE}, | ||
| 206 | + {"h.e.llo", "*.e.llo", TRUE}, | ||
| 207 | + {"h.e.llo", " *.e.llo", FALSE}, | ||
| 208 | + {" h.e.llo", "*.e.llo", TRUE}, | ||
| 209 | + {"h.e.llo.", "*.e.llo", TRUE}, | ||
| 210 | + {"*.e.llo.", "*.e.llo", TRUE}, | ||
| 211 | + {"************.e.llo.", "*.e.llo", TRUE}, | ||
| 212 | + {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" | ||
| 213 | + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" | ||
| 214 | + "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" | ||
| 215 | + "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" | ||
| 216 | + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" | ||
| 217 | + ".e.llo.", "*.e.llo", TRUE}, | ||
| 218 | + {"\xfe\xfe.e.llo.", "*.e.llo", TRUE}, | ||
| 219 | + {"h.e.llo.", "*.e.llo.", TRUE}, | ||
| 220 | + {"h.e.llo", "*.e.llo.", TRUE}, | ||
| 221 | + {".h.e.llo", "*.e.llo.", FALSE}, | ||
| 222 | + {"h.e.llo", "*.*.llo.", FALSE}, | ||
| 223 | + {"h.e.llo", "h.*.llo", FALSE}, | ||
| 224 | + {"h.e.llo", "h.e.*", FALSE}, | ||
| 225 | + {"hello", "*.ello", FALSE}, | ||
| 226 | + {"hello", "**llo", FALSE}, | ||
| 227 | + {"bar.foo.example.com", "*.example.com", FALSE}, | ||
| 228 | + {"foo.example.com", "*.example.com", TRUE}, | ||
| 229 | + {"baz.example.net", "b*z.example.net", FALSE}, | ||
| 230 | + {"foobaz.example.net", "*baz.example.net", FALSE}, | ||
| 231 | + {"xn--l8j.example.local", "x*.example.local", FALSE}, | ||
| 232 | + {"xn--l8j.example.net", "*.example.net", TRUE}, | ||
| 233 | + {"xn--l8j.example.net", "*j.example.net", FALSE}, | ||
| 234 | + {"xn--l8j.example.net", "xn--l8j.example.net", TRUE}, | ||
| 235 | + {"xn--l8j.example.net", "xn--l8j.*.net", FALSE}, | ||
| 236 | + {"xl8j.example.net", "*.example.net", TRUE}, | ||
| 237 | + {"fe80::3285:a9ff:fe46:b619", "*::3285:a9ff:fe46:b619", FALSE}, | ||
| 238 | + {"fe80::3285:a9ff:fe46:b619", "fe80::3285:a9ff:fe46:b619", TRUE}, | ||
| 239 | + {NULL, NULL, FALSE} | ||
| 240 | +}; | ||
| 241 | |||
| 242 | -fail_if(Curl_cert_hostcheck(STRCONST("xxx.example.com"), | ||
| 243 | - STRCONST("www.example.com")), "bad 1"); | ||
| 244 | -fail_if(Curl_cert_hostcheck(STRCONST("*"), | ||
| 245 | - STRCONST("www.example.com")),"bad 2"); | ||
| 246 | -fail_if(Curl_cert_hostcheck(STRCONST("*.*.com"), | ||
| 247 | - STRCONST("www.example.com")), "bad 3"); | ||
| 248 | -fail_if(Curl_cert_hostcheck(STRCONST("*.example.com"), | ||
| 249 | - STRCONST("baa.foo.example.com")), "bad 4"); | ||
| 250 | -fail_if(Curl_cert_hostcheck(STRCONST("f*.example.com"), | ||
| 251 | - STRCONST("baa.example.com")), "bad 5"); | ||
| 252 | -fail_if(Curl_cert_hostcheck(STRCONST("*.com"), | ||
| 253 | - STRCONST("example.com")), "bad 6"); | ||
| 254 | -fail_if(Curl_cert_hostcheck(STRCONST("*fail.com"), | ||
| 255 | - STRCONST("example.com")), "bad 7"); | ||
| 256 | -fail_if(Curl_cert_hostcheck(STRCONST("*.example."), | ||
| 257 | - STRCONST("www.example.")), "bad 8"); | ||
| 258 | -fail_if(Curl_cert_hostcheck(STRCONST("*.example."), | ||
| 259 | - STRCONST("www.example")), "bad 9"); | ||
| 260 | -fail_if(Curl_cert_hostcheck(STRCONST(""), STRCONST("www")), "bad 10"); | ||
| 261 | -fail_if(Curl_cert_hostcheck(STRCONST("*"), STRCONST("www")), "bad 11"); | ||
| 262 | -fail_if(Curl_cert_hostcheck(STRCONST("*.168.0.0"), | ||
| 263 | - STRCONST("192.168.0.0")), "bad 12"); | ||
| 264 | -fail_if(Curl_cert_hostcheck(STRCONST("www.example.com"), | ||
| 265 | - STRCONST("192.168.0.0")), "bad 13"); | ||
| 266 | - | ||
| 267 | -#ifdef ENABLE_IPV6 | ||
| 268 | -fail_if(Curl_cert_hostcheck(STRCONST("*::3285:a9ff:fe46:b619"), | ||
| 269 | - STRCONST("fe80::3285:a9ff:fe46:b619")), "bad 14"); | ||
| 270 | -fail_unless(Curl_cert_hostcheck(STRCONST("fe80::3285:a9ff:fe46:b619"), | ||
| 271 | - STRCONST("fe80::3285:a9ff:fe46:b619")), | ||
| 272 | - "good 6"); | ||
| 273 | -#endif | ||
| 274 | +UNITTEST_START | ||
| 275 | +{ | ||
| 276 | + int i; | ||
| 277 | + for(i = 0; tests[i].host; i++) { | ||
| 278 | + if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern, | ||
| 279 | + strlen(tests[i].pattern), | ||
| 280 | + tests[i].host, | ||
| 281 | + strlen(tests[i].host))) { | ||
| 282 | + fprintf(stderr, | ||
| 283 | + "HOST: %s\n" | ||
| 284 | + "PTRN: %s\n" | ||
| 285 | + "did %sMATCH\n", | ||
| 286 | + tests[i].host, | ||
| 287 | + tests[i].pattern, | ||
| 288 | + tests[i].match ? "NOT ": ""); | ||
| 289 | + unitfail++; | ||
| 290 | + } | ||
| 291 | + } | ||
| 292 | +} | ||
| 293 | |||
| 294 | -#endif | ||
| 295 | +UNITTEST_STOP | ||
| 296 | +#else | ||
| 297 | |||
| 298 | - /* you end the test code like this: */ | ||
| 299 | +UNITTEST_START | ||
| 300 | |||
| 301 | UNITTEST_STOP | ||
| 302 | +#endif | ||
diff --git a/meta/recipes-support/curl/curl_7.82.0.bb b/meta/recipes-support/curl/curl_7.82.0.bb index 422c2bec0f..3241867d7e 100644 --- a/meta/recipes-support/curl/curl_7.82.0.bb +++ b/meta/recipes-support/curl/curl_7.82.0.bb | |||
| @@ -47,6 +47,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ | |||
| 47 | file://CVE-2023-27536.patch \ | 47 | file://CVE-2023-27536.patch \ |
| 48 | file://CVE-2023-28319.patch \ | 48 | file://CVE-2023-28319.patch \ |
| 49 | file://CVE-2023-28320.patch \ | 49 | file://CVE-2023-28320.patch \ |
| 50 | file://CVE-2023-28321.patch \ | ||
| 50 | " | 51 | " |
| 51 | SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c" | 52 | SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c" |
| 52 | 53 | ||
