From: Stefan Eissing Date: Wed, 19 Jul 2023 08:42:07 +0000 (+0200) Subject: quiche: fix segfault and other things X-Git-Tag: curl-8_2_1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6c8a0e50d4868051afdfe4528d4f2980097d648;p=thirdparty%2Fcurl.git quiche: fix segfault and other things - refs #11449 where a segfault is reported when IP Eyeballing did not immediately connect but made several attempts - The transfer initiating the eyeballing was initialized too early, leadding to references to the filter instance that was then replaced in the subsequent eyeball attempts. That led to a use after free in the buffer handling for the transfer - transfers are initiated now more lazy (like in the ngtcp2 filter), when the stream is actually opened - suppress reporting on quiche event errors for "other" transfers than the current one to not fail a transfer due to faults in another one. - revert recent return value handling for quiche_h3_recv_body() to not indicate an error but an EAGAIN situation. We wish quiche would document what functions return. Fixes #11449 Closes #11469 Reported-by: ウさん --- diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c index 3ef1ea19f5..39cc16e944 100644 --- a/lib/vquic/curl_quiche.c +++ b/lib/vquic/curl_quiche.c @@ -426,7 +426,7 @@ static ssize_t stream_resp_read(void *reader_ctx, return nread; } else { - *err = stream->resp_got_header? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR; + *err = CURLE_AGAIN; return -1; } } @@ -457,8 +457,8 @@ static CURLcode cf_recv_body(struct Curl_cfilter *cf, if(nwritten < 0 && result != CURLE_AGAIN) { DEBUGF(LOG_CF(data, cf, "[h3sid=%"PRId64"] recv_body error %zd", stream->id, nwritten)); - failf(data, "Error %zd in HTTP/3 response body for stream[%"PRId64"]", - nwritten, stream->id); + failf(data, "Error %d in HTTP/3 response body for stream[%"PRId64"]", + result, stream->id); stream->closed = TRUE; stream->reset = TRUE; stream->send_closed = TRUE; @@ -591,8 +591,13 @@ static CURLcode cf_poll_events(struct Curl_cfilter *cf, "for [h3sid=%"PRId64"] -> %d", stream? stream->id : -1, cf_ev_name(ev), stream3_id, result)); - quiche_h3_event_free(ev); - return result; + if(data == sdata) { + /* Only report this error to the caller if it is about the + * transfer we were called with. Otherwise we fail a transfer + * due to a problem in another one. */ + quiche_h3_event_free(ev); + return result; + } } quiche_h3_event_free(ev); } @@ -1147,10 +1152,8 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, (void)arg1; (void)arg2; switch(event) { - case CF_CTRL_DATA_SETUP: { - result = h3_data_setup(cf, data); + case CF_CTRL_DATA_SETUP: break; - } case CF_CTRL_DATA_PAUSE: result = h3_data_pause(cf, data, (arg1 != 0)); break; @@ -1339,11 +1342,6 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, } #endif - /* we do not get a setup event for the initial transfer */ - result = h3_data_setup(cf, data); - if(result) - return result; - result = cf_flush_egress(cf, data); if(result) return result;