diff options
author | Daniel Stenberg <daniel@haxx.se> | 2024-01-27 13:54:10 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2024-01-27 21:49:20 +0100 |
commit | 066ed4e51417492605ac3465cb052e62f322d78b (patch) | |
tree | 2781b8e13d25594ce3b9ed78c97f2dca0f1a4cd4 | |
parent | 6422ab6745c37f491d83c897ddb70b1bf782790e (diff) | |
download | curl-066ed4e51417492605ac3465cb052e62f322d78b.tar.gz |
http: only act on 101 responses when they are HTTP/1.1
For 101 responses claiming to be any other protocol, bail out. This
would previously trigger an assert.
Add test 1704 to verify.
Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66184
Closes #12811
-rw-r--r-- | lib/http.c | 56 | ||||
-rw-r--r-- | tests/data/Makefile.inc | 2 | ||||
-rw-r--r-- | tests/data/test1704 | 66 |
3 files changed, 98 insertions, 26 deletions
diff --git a/lib/http.c b/lib/http.c index 0c2a46090..679931e4b 100644 --- a/lib/http.c +++ b/lib/http.c @@ -4036,34 +4036,40 @@ static CURLcode http_rw_headers(struct Curl_easy *data, } break; case 101: - /* Switching Protocols */ - if(k->upgr101 == UPGR101_H2) { - /* Switching to HTTP/2 */ - DEBUGASSERT(conn->httpversion < 20); - infof(data, "Received 101, Switching to HTTP/2"); - k->upgr101 = UPGR101_RECEIVED; - - /* we'll get more headers (HTTP/2 response) */ - k->header = TRUE; - k->headerline = 0; /* restart the header line counter */ - switch_to_h2 = TRUE; - } + if(conn->httpversion == 11) { + /* Switching Protocols only allowed from HTTP/1.1 */ + if(k->upgr101 == UPGR101_H2) { + /* Switching to HTTP/2 */ + infof(data, "Received 101, Switching to HTTP/2"); + k->upgr101 = UPGR101_RECEIVED; + + /* we'll get more headers (HTTP/2 response) */ + k->header = TRUE; + k->headerline = 0; /* restart the header line counter */ + switch_to_h2 = TRUE; + } #ifdef USE_WEBSOCKETS - else if(k->upgr101 == UPGR101_WS) { - /* verify the response */ - result = Curl_ws_accept(data, buf, blen); - if(result) - return result; - k->header = FALSE; /* no more header to parse! */ - *pconsumed += blen; /* ws accept handled the data */ - blen = 0; - if(data->set.connect_only) - k->keepon &= ~KEEP_RECV; /* read no more content */ - } + else if(k->upgr101 == UPGR101_WS) { + /* verify the response */ + result = Curl_ws_accept(data, buf, blen); + if(result) + return result; + k->header = FALSE; /* no more header to parse! */ + *pconsumed += blen; /* ws accept handled the data */ + blen = 0; + if(data->set.connect_only) + k->keepon &= ~KEEP_RECV; /* read no more content */ + } #endif + else { + /* Not switching to another protocol */ + k->header = FALSE; /* no more header to parse! */ + } + } else { - /* Not switching to another protocol */ - k->header = FALSE; /* no more header to parse! */ + /* invalid for other HTTP versions */ + failf(data, "unexpected 101 response code"); + return CURLE_WEIRD_SERVER_REPLY; } break; default: diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 5b9e3a9ed..c3d496f64 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -215,7 +215,7 @@ test1670 test1671 \ \ test1680 test1681 test1682 test1683 \ \ -test1700 test1701 test1702 test1703 \ +test1700 test1701 test1702 test1703 test1704 \ \ test1800 test1801 \ \ diff --git a/tests/data/test1704 b/tests/data/test1704 new file mode 100644 index 000000000..a8f285eea --- /dev/null +++ b/tests/data/test1704 @@ -0,0 +1,66 @@ +<testcase> +<info> +<keywords> +HTTP +HTTP GET +HTTP/2 +</keywords> +</info> + +# +# Server-side +<reply> +<data nocheck="yes"> +HTTP/2 101 OK
+ +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+
+-maa- +</data> +</reply> + +# +# Client-side +<client> +<features> +h2c +</features> +<server> +http +</server> +<name> +HTTP/1 doing HTTP/2 Upgrade: getting a HTTP/2 101 response +</name> +<command> +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --http2 +</command> +</client> + +# +# Verify data after the test has been "shot" +<verify> +<strip> +^X-Forwarded-Proto:.* +^Via:.* +</strip> +<protocol> +GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+Connection: Upgrade, HTTP2-Settings
+Upgrade: h2c
+HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA
+
+</protocol> + +# CURLE_WEIRD_SERVER_REPLY (8) +<errorcode> +8 +</errorcode> +</verify> +</testcase> |