From: Daniel Stenberg Date: Sat, 27 Jan 2024 12:54:10 +0000 (+0100) Subject: http: only act on 101 responses when they are HTTP/1.1 X-Git-Tag: curl-8_6_0~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=066ed4e51417492605ac3465cb052e62f322d78b;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/http.c b/lib/http.c index 0c2a460903..679931e4b4 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 5b9e3a9ed2..c3d496f646 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 0000000000..a8f285eeab --- /dev/null +++ b/tests/data/test1704 @@ -0,0 +1,66 @@ + + + +HTTP +HTTP GET +HTTP/2 + + + +# +# Server-side + + +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- + + + +# +# Client-side + + +h2c + + +http + + +HTTP/1 doing HTTP/2 Upgrade: getting a HTTP/2 101 response + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --http2 + + + +# +# Verify data after the test has been "shot" + + +^X-Forwarded-Proto:.* +^Via:.* + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* +Connection: Upgrade, HTTP2-Settings +Upgrade: h2c +HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA + + + +# CURLE_WEIRD_SERVER_REPLY (8) + +8 + + +