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

Reply via email to