From 234a10aa9bce34781b5b0b4c4ffb595e7563eb41 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 28 Feb 2022 15:29:56 +0100 Subject: [PATCH] BUG/MEDIUM: htx: Fix a possible null derefs in htx_xfer_blks() In htx_xfer_blks() function, when headers or trailers are partially transferred, we rollback the copy by removing copied blocks. Internally, all blocks between and are removed. But if the transfer was stopped because we failed to reserve a block, the variable is NULL. Thus, we must not try to remove it. It is unexpected to call htx_remove_blk() in this case. htx_remove_blk() was updated to test variable inside the existing BUG_ON(). The block must be defined. For now, this bug may only be encountered when H2 trailers are copied. On H2 headers, the destination buffer is empty. Thus a swap is performed. This patch should fix the issue #1578. It must be backported as far as 2.4. --- src/htx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/htx.c b/src/htx.c index 3cc1a34b0..7e5bd4618 100644 --- a/src/htx.c +++ b/src/htx.c @@ -336,7 +336,7 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) enum htx_blk_type type; uint32_t pos, addr, sz; - BUG_ON(htx->head == -1); + BUG_ON(!blk || htx->head == -1); /* This is the last block in use */ if (htx->head == htx->tail) { @@ -739,12 +739,14 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, } if (unlikely(dstref)) { - /* Headers or trailers part was partially xferred, so rollback the copy - * by removing all block between and , both included. + /* Headers or trailers part was partially xferred, so rollback + * the copy by removing all block between and , + * both included. may be NULL. */ while (dstref && dstref != dstblk) dstref = htx_remove_blk(dst, dstref); - htx_remove_blk(dst, dstblk); + if (dstblk) + htx_remove_blk(dst, dstblk); /* HTX message is empty, it means the headers or trailers * part is too big to be copied at once.