Fix a buffer overflow that occurs when fat_set_blk_dev() is called multiple times for the same partition.
On the first call, fat_sect_size starts at 0 and gets set to the FAT sector size (e.g., 4096) after reading the boot sector. On subsequent calls to the same partition, fat_sect_size retains this value, causing disk_read() to attempt reading 4096 bytes into a 512-byte buffer, resulting in memory corruption. The fix adds caching to detect when the same device/partition is being accessed and returns early without re-initialization. For new partitions, fat_sect_size is reset to 0 to ensure proper initialization sequence. This patch is based on the changes in the upstream submission: https://lore.kernel.org/u-boot/[email protected]/ Signed-off-by: Balaji Selvanathan <[email protected]> --- fs/fat/fat.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 05acd24d8bd..8138f7418a1 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -257,10 +257,28 @@ exit: int fat_set_blk_dev(struct blk_desc *dev_desc, struct disk_partition *info) { - ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); + static struct blk_desc *last_dev; + static struct disk_partition last_part_info = {0}; + + /* Check if we're already initialized for the same device/partition */ + if (last_dev == dev_desc && + last_part_info.start == info->start && + last_part_info.size == info->size && + fat_sect_size != 0) { + cur_dev = dev_desc; + cur_part_info = *info; + return 0; + } cur_dev = dev_desc; cur_part_info = *info; + last_dev = dev_desc; + last_part_info = *info; + + /* Reset fat_sect_size for new device/partition */ + fat_sect_size = 0; + + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); /* Make sure it has a valid FAT header */ if (disk_read(0, 1, buffer) != 1) { -- 2.34.1

