From: Hugo Landau Date: Tue, 6 Jun 2023 15:25:12 +0000 (+0100) Subject: QUIC APL: Validate receive stream state X-Git-Tag: openssl-3.2.0-alpha1~429 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e0bd282517f5853f2cfc73e90fc04be7a70dfd66;p=thirdparty%2Fopenssl.git QUIC APL: Validate receive stream state Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21135) --- diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index ee4d64561c9..544e21e5a7c 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -2046,6 +2046,38 @@ struct quic_read_again_args { int peek; }; +QUIC_NEEDS_LOCK +static int quic_validate_for_read(QUIC_XSO *xso, int *err, int *eos) +{ + *eos = 0; + + if (xso == NULL || xso->stream == NULL) { + *err = ERR_R_INTERNAL_ERROR; + return 0; + } + + switch (xso->stream->recv_state) { + default: + case QUIC_RSTREAM_STATE_NONE: + *err = SSL_R_STREAM_SEND_ONLY; + return 0; + + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + case QUIC_RSTREAM_STATE_DATA_RECVD: + return 1; + + case QUIC_RSTREAM_STATE_DATA_READ: + *eos = 1; + return 0; + + case QUIC_RSTREAM_STATE_RESET_RECVD: + case QUIC_RSTREAM_STATE_RESET_READ: + *err = SSL_R_STREAM_RESET; + return 0; + } +} + QUIC_NEEDS_LOCK static int quic_read_actual(QCTX *ctx, QUIC_STREAM *stream, @@ -2053,16 +2085,21 @@ static int quic_read_actual(QCTX *ctx, size_t *bytes_read, int peek) { - int is_fin = 0; + int is_fin = 0, err, eos; QUIC_CONNECTION *qc = ctx->qc; + if (!quic_validate_for_read(ctx->xso, &err, &eos)) { + if (eos) + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN); + else + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, err, NULL); + } + /* If the receive part of the stream is over, issue EOF. */ if (stream->recv_fin_retired) + /* XXX TODO REMOVE */ return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN); - if (!ossl_quic_stream_has_recv_buffer(stream)) - return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); - if (peek) { if (!ossl_quic_rstream_peek(stream->rstream, buf, buf_len, bytes_read, &is_fin)) @@ -2165,11 +2202,6 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek ctx.xso = ctx.qc->default_xso; } - if (ctx.xso->stream == NULL) { - ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); - goto out; - } - if (!quic_read_actual(&ctx, ctx.xso->stream, buf, len, bytes_read, peek)) { ret = 0; /* quic_read_actual raised error here */ goto out; @@ -2708,7 +2740,7 @@ int ossl_quic_stream_reset(SSL *ssl, QUIC_STREAM_MAP *qsm; QUIC_STREAM *qs; uint64_t error_code; - int ok; + int ok, err; if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/0, &ctx)) return 0; @@ -2717,6 +2749,9 @@ int ossl_quic_stream_reset(SSL *ssl, qs = ctx.xso->stream; error_code = (args != NULL ? args->quic_error_code : 0); + if (!quic_validate_for_write(ctx.xso, &err)) + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); + ok = ossl_quic_stream_map_reset_stream_send_part(qsm, qs, error_code); quic_unlock(ctx.qc);