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
This commit is contained in:
Daniel Stenberg 2024-01-27 13:54:10 +01:00
parent 6422ab6745
commit 066ed4e514
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 97 additions and 25 deletions

View file

@ -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;
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;
}
/* 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: