mirror of
https://github.com/curl/curl.git
synced 2025-04-12 16:20:35 +08:00
HTTP/2, HTTP/3: handle detach of onoing transfers
- refs #12356 where a UAF is reported when closing a connection with a stream whose easy handle was cleaned up already - handle DETACH events same as DONE events in h2/h3 filters Fixes #12356 Reported-by: Paweł Wegner Closes #12364
This commit is contained in:
parent
413a0fedd0
commit
b06b6216a3
@ -2486,14 +2486,15 @@ static CURLcode cf_h2_cntrl(struct Curl_cfilter *cf,
|
||||
case CF_CTRL_DATA_PAUSE:
|
||||
result = http2_data_pause(cf, data, (arg1 != 0));
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE_SEND: {
|
||||
case CF_CTRL_DATA_DONE_SEND:
|
||||
result = http2_data_done_send(cf, data);
|
||||
break;
|
||||
}
|
||||
case CF_CTRL_DATA_DONE: {
|
||||
case CF_CTRL_DATA_DETACH:
|
||||
http2_data_done(cf, data, TRUE);
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE:
|
||||
http2_data_done(cf, data, arg1 != 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -238,11 +238,20 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||
|
||||
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
{
|
||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||
|
||||
(void)cf;
|
||||
if(stream) {
|
||||
CURL_TRC_CF(data, cf, "[%"PRId64"] easy handle is done", stream->id);
|
||||
if(ctx->h3conn && !stream->closed) {
|
||||
nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream->id);
|
||||
nghttp3_conn_close_stream(ctx->h3conn, stream->id,
|
||||
NGHTTP3_H3_REQUEST_CANCELLED);
|
||||
nghttp3_conn_set_stream_user_data(ctx->h3conn, stream->id, NULL);
|
||||
stream->closed = TRUE;
|
||||
}
|
||||
|
||||
Curl_bufq_free(&stream->sendbuf);
|
||||
Curl_bufq_free(&stream->recvbuf);
|
||||
Curl_h1_req_parse_free(&stream->h1);
|
||||
@ -2323,10 +2332,12 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
|
||||
case CF_CTRL_DATA_PAUSE:
|
||||
result = h3_data_pause(cf, data, (arg1 != 0));
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE: {
|
||||
case CF_CTRL_DATA_DETACH:
|
||||
h3_data_done(cf, data);
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE:
|
||||
h3_data_done(cf, data);
|
||||
break;
|
||||
}
|
||||
case CF_CTRL_DATA_DONE_SEND: {
|
||||
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||
if(stream && !stream->send_closed) {
|
||||
|
@ -55,7 +55,8 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* #define DEBUG_QUICHE */
|
||||
/* HTTP/3 error values defined in RFC 9114, ch. 8.1 */
|
||||
#define CURL_H3_NO_ERROR (0x0100)
|
||||
|
||||
#define QUIC_MAX_STREAMS (100)
|
||||
|
||||
@ -303,11 +304,22 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||
|
||||
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
{
|
||||
struct cf_quiche_ctx *ctx = cf->ctx;
|
||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
||||
|
||||
(void)cf;
|
||||
if(stream) {
|
||||
CURL_TRC_CF(data, cf, "[%"PRId64"] easy handle is done", stream->id);
|
||||
if(ctx->qconn && !stream->closed) {
|
||||
quiche_conn_stream_shutdown(ctx->qconn, stream->id,
|
||||
QUICHE_SHUTDOWN_READ, CURL_H3_NO_ERROR);
|
||||
if(!stream->send_closed) {
|
||||
quiche_conn_stream_shutdown(ctx->qconn, stream->id,
|
||||
QUICHE_SHUTDOWN_WRITE, CURL_H3_NO_ERROR);
|
||||
stream->send_closed = TRUE;
|
||||
}
|
||||
stream->closed = TRUE;
|
||||
}
|
||||
Curl_bufq_free(&stream->recvbuf);
|
||||
Curl_h1_req_parse_free(&stream->h1);
|
||||
free(stream);
|
||||
@ -1213,10 +1225,12 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf,
|
||||
case CF_CTRL_DATA_PAUSE:
|
||||
result = h3_data_pause(cf, data, (arg1 != 0));
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE: {
|
||||
case CF_CTRL_DATA_DETACH:
|
||||
h3_data_done(cf, data);
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE:
|
||||
h3_data_done(cf, data);
|
||||
break;
|
||||
}
|
||||
case CF_CTRL_DATA_DONE_SEND: {
|
||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
||||
if(stream && !stream->send_closed) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user