[PATCH 2 of 2] QUIC: improved split frames error handling

Roman Arutyunyan arut at nginx.com
Tue May 2 13:59:26 UTC 2023


On Tue, May 02, 2023 at 04:14:58PM +0400, Sergey Kandaurov wrote:
> 
> > On 1 May 2023, at 19:26, Sergey Kandaurov <pluknet at nginx.com> wrote:
> > 
> > # HG changeset patch
> > # User Sergey Kandaurov <pluknet at nginx.com>
> > # Date 1682954724 -14400
> > #      Mon May 01 19:25:24 2023 +0400
> > # Branch quic
> > # Node ID b10aa30b15a802870eb23716ce3937a1085c4c98
> > # Parent  8aa3363bc83d4354b3142e3972cce5c0ef523539
> > QUIC: improved split frames error handling.
> > 
> > Do not update frame data chain on ngx_quic_read_buffer() error.
> > It may be used later as part of error handling, which envolves
> > writing CONNECTION_CLOSE and pending frames, including the one
> > with the corrupted chain pointer.  Since ngx_quic_read_buffer()
> > returns the original chain, there is no point in updating it,
> > so this was simplified.
> > 
> > diff --git a/src/event/quic/ngx_event_quic_frames.c b/src/event/quic/ngx_event_quic_frames.c
> > --- a/src/event/quic/ngx_event_quic_frames.c
> > +++ b/src/event/quic/ngx_event_quic_frames.c
> > @@ -359,8 +359,7 @@ ngx_quic_split_frame(ngx_connection_t *c
> >     ngx_memzero(&qb, sizeof(ngx_quic_buffer_t));
> >     qb.chain = f->data;
> > 
> > -    f->data = ngx_quic_read_buffer(c, &qb, of->length);
> > -    if (f->data == NGX_CHAIN_ERROR) {
> > +    if (ngx_quic_read_buffer(c, &qb, of->length) == NGX_CHAIN_ERROR) {
> >         return NGX_ERROR;
> >     }
> > 
> 
> Below is an updated version after discussion with Roman.
> It uses conservative approach to maintain API and not rely on that the
> passed output chain pointer will not be modified.  Theoretically it can
> if the limit inside ngx_quic_read_buffer() is zero on the first iteration
> so that the passed chain pointer will be zeroed.  Another possibility is
> ngx_quic_split_chain() potentially may be rewritten to insert a new
> element in ngx_quic_split_chain() first.
> 
> # HG changeset patch
> # User Sergey Kandaurov <pluknet at nginx.com>
> # Date 1683029654 -14400
> #      Tue May 02 16:14:14 2023 +0400
> # Branch quic
> # Node ID 491623c24eb30876f60196e6ca99e5284de43cd5
> # Parent  8aa3363bc83d4354b3142e3972cce5c0ef523539
> QUIC: fixed split frames error handling.
> 
> Do not corrupt frame data chain pointer on ngx_quic_read_buffer() error.
> The error leads to closing a QUIC connection where the frame may be used
> as part of the QUIC connection tear down, which envolves writing pending
> frames, including this one.
> 
> diff --git a/src/event/quic/ngx_event_quic_frames.c b/src/event/quic/ngx_event_quic_frames.c
> --- a/src/event/quic/ngx_event_quic_frames.c
> +++ b/src/event/quic/ngx_event_quic_frames.c
> @@ -319,6 +319,7 @@ ngx_int_t
>  ngx_quic_split_frame(ngx_connection_t *c, ngx_quic_frame_t *f, size_t len)
>  {
>      size_t                     shrink;
> +    ngx_chain_t               *out;
>      ngx_quic_frame_t          *nf;
>      ngx_quic_buffer_t          qb;
>      ngx_quic_ordered_frame_t  *of, *onf;
> @@ -359,11 +360,13 @@ ngx_quic_split_frame(ngx_connection_t *c
>      ngx_memzero(&qb, sizeof(ngx_quic_buffer_t));
>      qb.chain = f->data;
>  
> -    f->data = ngx_quic_read_buffer(c, &qb, of->length);
> -    if (f->data == NGX_CHAIN_ERROR) {
> +    out = ngx_quic_read_buffer(c, &qb, of->length);
> +    if (out == NGX_CHAIN_ERROR) {
>          return NGX_ERROR;
>      }
>  
> +    f->data = out;
> +
>      nf = ngx_quic_alloc_frame(c);
>      if (nf == NULL) {
>          return NGX_ERROR;
> 
> 
> -- 
> Sergey Kandaurov
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> https://mailman.nginx.org/mailman/listinfo/nginx-devel

Both this and the patch #1 look good.

--
Roman Arutyunyan


More information about the nginx-devel mailing list