Re: [PATCH v2 2/2] dm array: reject an array block whose value size is not the caller's

From: Ming Hung Tsai

Date: Mon Aug 03 2026 - 10:31:32 EST


On Sat, Aug 1, 2026 at 6:55 AM Bryam Vargas via B4 Relay
<devnull+hexlabsecurity.proton.me@xxxxxxxxxx> wrote:
>
> From: Bryam Vargas <hexlabsecurity@xxxxxxxxx>
>
> array_block_check() can only compare the header against itself, so a block
> with value_size 4 and max_entries 1018 is internally consistent and passes.
> dm-cache keeps two arrays -- mappings at 8 bytes and hints at 4 -- and the
> roots for both live in the superblock. Point the mappings root at a hint
> block and __load_mappings() walks it through an info whose value size is 8,
> so element_at() strides 8 bytes over 4-byte entries and reaches offset 8160
> of a 4096-byte block.
>
> get_ablock() and __shadow_ablock() are the two places that hold the block
> and the caller at once. Reject there when the two value sizes disagree.
> Arrays only ever read their own blocks, so this fires on crafted metadata
> only.
>
> Fixes: 6513c29f44f2 ("dm persistent data: add transactional array")
> Suggested-by: Ming-Hung Tsai <mtsai@xxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Bryam Vargas <hexlabsecurity@xxxxxxxxx>

Reviewed-by: Ming-Hung Tsai <mtsai@xxxxxxxxxx>

The fix addresses more than crafted metadata. A lost write on disk
drives can cause a stale block that was freed as a hint block,
triggering this out-of-bounds access issue.