BUG/MEDIUM: shctx: Use the next block when data exactly filled a block

When the hot list was removed in 3.0, a regression was introduced.
Theorically, it is possible to override data in a block when new data are
appended. It happens when data are copied. If the data size is a multiple of
the block size, all data are copied and the last used block is full. But
instead of saving a reference on the next block as the restart point for the
next copies, we keep a reference on the last full one. On the next read, we
reuse this block and old data are crushed. To hit the bug, no new blocks
should be reserved between the two data copy attempts.

Concretely, for now, it seems not possible to hit the bug. But with a block
size set to 1024, if more than 1024 bytes are reseved, with a first copy of
1024 bytes and a second one with remaining data, data in the first block
will be crushed.

So to fix the bug, the reference of the last block used to write data (which
is in fact the next one to use to perform the next copy) is only updated
when a block is full. In that case the next block is used.

This patch should be backported as far as 3.0 after a period of observation.
This commit is contained in:
Christopher Faulet 2026-02-03 07:46:22 +01:00
parent b248b1c021
commit 9e17087aeb

View file

@ -206,9 +206,12 @@ int shctx_row_data_append(struct shared_context *shctx, struct shared_block *fir
data += remain;
len -= remain;
first->len += remain; /* update len in the head of the row */
first->last_append = block;
block = LIST_ELEM(block->list.n, struct shared_block*, list);
/* Update <last_append> block only if the previous one is full */
if (start + remain == shctx->block_size)
first->last_append = block;
} while (block != first);
return len;