fs_cgsize is read from disk into uspi->s_cgsize without any check. Its only consumer derives a buffer count from it: UCPI_UBH(ucpi)->count = uspi->s_cgsize >> sb->s_blocksize_bits; ... for (i = 1; i < UCPI_UBH(ucpi)->count; i++) { UCPI_UBH(ucpi)->bh[i] = sb_bread(...); struct ufs_buffer_head.bh[] has UFS_MAXFRAG (8) entries, so a crafted fs_cgsize whose block shift exceeds 8 writes past the array while loading a cylinder group. fs_cgsize of zero, or smaller than the fragment size, produces a zero count and leaves the cylinder group in a half-initialized state. Reject those values where the rest of the geometry is already validated. Reported-by: Guikun Yang (bug report of 2026-10-31, ) Signed-off-by: Guikun Yang --- fs/ufs/super.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 1111111..2222222 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1140,6 +1140,14 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize); + if (!uspi->s_cgsize || + uspi->s_cgsize < uspi->s_fsize || + (uspi->s_cgsize >> sb->s_blocksize_bits) > UFS_MAXFRAG) { + pr_err("%s(): invalid cylinder group size (%u)\n", + __func__, uspi->s_cgsize); + goto failed; + } uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak); Tested on the image from the bug report: the crafted fs_cgsize is now rejected at mount with the message above instead of writing past bh[]; the unmodified image still mounts. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") -- 2.43.0