From c86d757267354e3f4892faf8281f3f774f3bb77b Mon Sep 17 00:00:00 2001 From: deepikabhavnani Date: Thu, 11 Jan 2018 14:28:17 -0600 Subject: [PATCH] Fix: Sector/Size overflow from uint32_t FATFilesystem declares sector count and size as uint32_t and block device class arguments are addr and size which is uint64_t While passing arguments to program/read/write API's of block device, multiplication of uint32_t*uint32_t was not typecasted properly to uint64_t which resulted in MSB truncation. Eg. If block 0x800000 is accessed with block size 0x200, addr to be passed (0x800000*0x200)0x100000000, but actual address passed was 0x0 which resulted in over-writting the root directory, and hence corrupted filesystem --- features/filesystem/fat/FATFileSystem.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/features/filesystem/fat/FATFileSystem.cpp b/features/filesystem/fat/FATFileSystem.cpp index 152cc96b335..d7c9309bb91 100644 --- a/features/filesystem/fat/FATFileSystem.cpp +++ b/features/filesystem/fat/FATFileSystem.cpp @@ -196,7 +196,9 @@ DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count) { debug_if(FFS_DBG, "disk_read(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv); DWORD ssize = disk_get_sector_size(pdrv); - int err = _ffs[pdrv]->read(buff, sector*ssize, count*ssize); + bd_addr_t addr = (bd_addr_t)sector*ssize; + bd_size_t size = (bd_size_t)count*ssize; + int err = _ffs[pdrv]->read(buff, addr, size); return err ? RES_PARERR : RES_OK; } @@ -204,12 +206,14 @@ DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count) { debug_if(FFS_DBG, "disk_write(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv); DWORD ssize = disk_get_sector_size(pdrv); - int err = _ffs[pdrv]->erase(sector*ssize, count*ssize); + bd_addr_t addr = (bd_addr_t)sector*ssize; + bd_size_t size = (bd_size_t)count*ssize; + int err = _ffs[pdrv]->erase(addr, size); if (err) { return RES_PARERR; } - err = _ffs[pdrv]->program(buff, sector*ssize, count*ssize); + err = _ffs[pdrv]->program(buff, addr, size); if (err) { return RES_PARERR; } @@ -250,7 +254,9 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) } else { DWORD *sectors = (DWORD*)buff; DWORD ssize = disk_get_sector_size(pdrv); - int err = _ffs[pdrv]->trim(sectors[0]*ssize, (sectors[1]-sectors[0]+1)*ssize); + bd_addr_t addr = (bd_addr_t)sectors[0]*ssize; + bd_size_t size = (bd_size_t)(sectors[1]-sectors[0]+1)*ssize; + int err = _ffs[pdrv]->trim(addr, size); return err ? RES_PARERR : RES_OK; } }