Re: [PATCH] hpfs: add array bounds validation in hpfs_bplus_lookup
From: Deepanshu Kartikey
Date: Tue Mar 31 2026 - 04:54:55 EST
On Sat, Jan 17, 2026 at 11:10 AM Deepanshu Kartikey
<kartikey406@xxxxxxxxx> wrote:
>
> When traversing a corrupted HPFS filesystem, the n_used_nodes field in
> the btree header can contain a value larger than what fits in the
> allocated buffer. This causes out-of-bounds array access when iterating
> through btree->u.internal[] or btree->u.external[] arrays, leading to
> a KASAN-detected use-after-free.
>
> Validate that n_used_nodes does not exceed the maximum number of nodes
> that can fit in the buffer before accessing the arrays.
>
> Reported-by: syzbot+8debf4b3f7c7391cd8eb@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=8debf4b3f7c7391cd8eb
> Tested-by: syzbot+8debf4b3f7c7391cd8eb@xxxxxxxxxxxxxxxxxxxxxxxxx
> Signed-off-by: Deepanshu Kartikey <kartikey406@xxxxxxxxx>
> ---
> fs/hpfs/anode.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c
> index a4f5321eafae..6e1b43f5c9cf 100644
> --- a/fs/hpfs/anode.c
> +++ b/fs/hpfs/anode.c
> @@ -21,6 +22,31 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
> int c1, c2 = 0;
> go_down:
> if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1;
> +
> + if (bp_internal(btree)) {
> + unsigned int max_internal_nodes;
> +
> + max_internal_nodes = (bh->b_size - ((char *)btree->u.internal - (char *)bh->b_data))
> + / sizeof(btree->u.internal[0]);
> + if (btree->n_used_nodes > max_internal_nodes) {
> + hpfs_error(s, "btree->n_used_nodes = %u, but max for internal node is %u",
> + btree->n_used_nodes, max_internal_nodes);
> + brelse(bh);
> + return -1;
> + }
> + } else {
> + unsigned int max_external_nodes;
> +
> + max_external_nodes = (bh->b_size - ((char *)btree->u.external - (char *)bh->b_data))
> + / sizeof(btree->u.external[0]);
> + if (btree->n_used_nodes > max_external_nodes) {
> + hpfs_error(s, "btree->n_used_nodes = %u, but max for external node is %u",
> + btree->n_used_nodes, max_external_nodes);
> + brelse(bh);
> + return -1;
> + }
> + }
> +
> if (bp_internal(btree)) {
> for (i = 0; i < btree->n_used_nodes; i++)
> if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) {
> --
> 2.43.0
>
Hi Mikulas,
Gentle ping on this patch . I have submitted this patch on 17th jan 2026
Please let me know if anything else required
Thanks
Deepanshu