The disk_read() and disk_write() functions of the FAT driver use the
blk_dread() and blk_dwrite() respectively. The blk_* APIs read and write
to the devices in terms of the device block size. However, the FAT
driver reads in terms of the device block size (from fat_set_blk_dev and
read_bootsectandvi) and sector size in the rest of the places.

This causes buffer overflows or partial reads when the FAT sector size
is not equal to device block size. Fix this by using blk_dread in
fat_set_blk_dev and read_bootsectandvi instead of disk_read. And update
disk_read/disk_write to handle FAT sector size and block size mismatch.

Changes in v6:

Added a new config to avoid code size impact to platforms that don't
need this.

Tested on
        blksz | FAT sector size
        ------+----------------
        4096  | 4096
        512   | 512
        4096  | 512
        512   | 4096

CI test results
---------------
        https://github.com/u-boot/u-boot/pull/871
        All checks have passed
        93 successful checks
        No conflicts with base branch

Code size change info
---------------------
       arm: (for 1/1 boards) all +32.0 text +32.0
            qemu_arm       : all +32 text +32
               u-boot: add: 0/0, grow: 2/0 bytes: 24/0 (24)
                 function                                   old     new   delta
                 read_bootsectandvi                         420     432     +12
                 fat_set_blk_dev                            204     216     +12

   aarch64: (for 1/1 boards) all +12.0 rodata -8.0 text +20.0
            qemu_arm64     : all +12 rodata -8 text +20
               u-boot: add: 0/0, grow: 2/0 bytes: 20/0 (20)
                 function                                   old     new   delta
                 read_bootsectandvi                         408     420     +12
                 fat_set_blk_dev                            204     212      +8

   aarch64: (for 1/1 boards) all -2.0 data -8.0 rodata +6.0
            qcom_qcs9100   : all -2 data -8 rodata +6
               u-boot: add: 1/-1, grow: 8/-1 bytes: 708/-224 (484)
                 function                                   old     new   delta
                 disk_rw                                      -     628    +628
                 read_bootsectandvi                         408     428     +20
                 fat_itr_root                               500     520     +20
                 get_cluster                                376     388     +12
                 set_contents                              2076    2084      +8
                 fat_set_blk_dev                            204     212      +8
                 static.set_fatent_value                    536     540      +4
                 get_fatent                                 420     424      +4
                 fat_next_cluster                           368     372      +4
                 disk_read                                  100       -    -100
                 disk_write                                 132       8    -124

Changes in v5: 
https://lore.kernel.org/u-boot/[email protected]/
- Fix CI error reported in 
https://dev.azure.com/u-boot/u-boot/_build/results?buildId=12821&view=logs&j=a007cd84-3be0-5a02-8a7a-a34fb3052485&t=216c79d4-eaff-5600-0b8f-3a63c01a45d6
- All CI tests passed. (Please see https://github.com/u-boot/u-boot/pull/868)
- U-boot SPL for (am335x_evm, am335x_hs_evm, am335x_hs_evm_spi) includes the
  FAT driver. The additional checks done in this patch resulted in increased
  code size causing it to overshoot the '.sram' area.
- Address this by using the existing disk_read & disk_write routines for
  SPL.
- Also bail out in case of sector size mismatch for SPL

Changes in v4: 
https://lore.kernel.org/u-boot/[email protected]/
- Fix clang warning reported in 
https://source.denx.de/u-boot/u-boot/-/jobs/1365316
- Remove unused function 'size_to_blocks()'
- Triggered CI, it fails with this error 
https://dev.azure.com/u-boot/u-boot/_build/results?buildId=12817&view=logs&j=a007cd84-3be0-5a02-8a7a-a34fb3052485&t=216c79d4-eaff-5600-0b8f-3a63c01a45d6&l=405.
 But that seems to be seen on top-of-tree without this change also.

Changes in v3: 
https://lore.kernel.org/u-boot/[email protected]/
- Respin, no changes

Changes in v2: 
https://lore.kernel.org/u-boot/[email protected]/
- fat_sect_size is declared as static
- The else block in disk_write() function has been removed
- The commit message has additional details about testing

v1: 
https://lore.kernel.org/u-boot/[email protected]/

Varadarajan Narayanan (2):
  fs: fat: Handle 'FAT sector size mismatch'
  configs: qcom: Enable FS_FAT_HANDLE_SECTOR_SIZE_MISMATCH

 configs/qcom_defconfig |   1 +
 fs/fat/Kconfig         |   8 +++
 fs/fat/fat.c           | 152 +++++++++++++++++++++++++++++++++++++++--
 fs/fat/fat_write.c     |   2 +
 4 files changed, 158 insertions(+), 5 deletions(-)

-- 
2.34.1

Reply via email to