From: Zhao Zhang sysv68_partition() reads a single sector for the slice table, but it trusts ios_slccnt from disk and walks that many entries after skipping the synthetic whole-disk slice. A crafted image can set ios_slccnt larger than the 64 struct slice records that fit in one sector and trigger an out-of-bounds read while scanning partitions. Limit the slice count to the number of records that fit in the sector returned by read_part_sector(), then drop the whole-disk entry only when the bounded count is non-zero. Fixes: 19d0e8ce856a ("partition: add support for sysv68 partitions") Cc: stable@vger.kernel.org Reported-by: Yuan Tan Reported-by: Zhengchuan Liang Reported-by: Xin Liu Assisted-by: Codex:GPT-5.4 Signed-off-by: Zhao Zhang Signed-off-by: Ren Wei --- block/partitions/sysv68.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/block/partitions/sysv68.c b/block/partitions/sysv68.c index 470e0f9de7be..5110ed83c541 100644 --- a/block/partitions/sysv68.c +++ b/block/partitions/sysv68.c @@ -48,7 +48,8 @@ struct slice { int sysv68_partition(struct parsed_partitions *state) { - int i, slices; + sector_t slice_sector; + unsigned int i, slices; int slot = 1; Sector sect; unsigned char *data; @@ -65,14 +66,16 @@ int sysv68_partition(struct parsed_partitions *state) return 0; } slices = be16_to_cpu(b->dk_ios.ios_slccnt); - i = be32_to_cpu(b->dk_ios.ios_slcblk); + slice_sector = be32_to_cpu(b->dk_ios.ios_slcblk); put_dev_sector(sect); - data = read_part_sector(state, i, §); + data = read_part_sector(state, slice_sector, §); if (!data) return -1; - slices -= 1; /* last slice is the whole disk */ + slices = min_t(unsigned int, slices, SECTOR_SIZE / sizeof(*slice)); + if (slices) + slices -= 1; /* last slice is the whole disk */ seq_buf_printf(&state->pp_buf, "sysV68: %s(s%u)", state->name, slices); slice = (struct slice *)data; for (i = 0; i < slices; i++, slice++) { -- 2.47.3