Re: [PATCH] memstick: ms_block: reject a card that reports too many blocks
Ulf Hansson <[email protected]> Mon, 6 Jul 2026 17:47:28 +0200
| Newsgroups | org.kernel.vger.linux-mmc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAPx+jO9y4+g-JfavOTE61ySBETUMfDzb3q1_B835wyW0nR4uUw@mail.gmail.com> |
On Thu, Jul 2, 2026 at 10:27 AM Maoyi Xie <[email protected]> wrote: > > msb_ftl_initialize() computes the zone count from the card block count > with no bound: > > msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE; > ... > for (i = 0; i < msb->zone_count; i++) > msb->free_block_count[i] = MS_BLOCKS_IN_ZONE; > > msb->block_count is a card value. msb_read_boot_blocks() reads > number_of_blocks from the card boot page and byte swaps it. > free_block_count is a fixed int[MS_MAX_ZONES]. MS_MAX_ZONES is 16, so the > valid indices are 0 to 15. The init loop above indexes it by zone_count. > msb_mark_block_used() and msb_mark_block_unused() index it by > pba / MS_BLOCKS_IN_ZONE, for pba up to block_count - 1. A card may report > up to 65535 blocks. A block_count above 8192 (MS_MAX_ZONES * > MS_BLOCKS_IN_ZONE) lets the pba index reach 16. That writes past > free_block_count[] and corrupts struct msb_data. A larger count runs the > init loop past the end too. > > A real Memory Stick has at most 16 zones. So it has at most 8192 blocks. > msb_ftl_initialize() now rejects a card that reports more than > MS_MAX_ZONES * MS_BLOCKS_IN_ZONE blocks. > > Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks") > Cc: [email protected] > Signed-off-by: Maoyi Xie <[email protected]> Applied for fixes, thanks! Kind regards Uffe > --- > I do not have the hardware. I showed the overflow with a small harness. > The harness replays the store loop into free_block_count[]. > > drivers/memstick/core/ms_block.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c > index a01fe31355..ce33907bfc 100644 > --- a/drivers/memstick/core/ms_block.c > +++ b/drivers/memstick/core/ms_block.c > @@ -1338,6 +1338,10 @@ static int msb_ftl_initialize(struct msb_data *msb) > return 0; > > msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE; > + if (msb->block_count > MS_MAX_ZONES * MS_BLOCKS_IN_ZONE) { > + pr_err("Too many blocks: %d\n", msb->block_count); > + return -EINVAL; > + } > msb->logical_block_count = msb->zone_count * 496 - 2; > > msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); > -- > 2.34.1 >