From 562efd3c1dfa82936e7f160637e3fd2abb00787b Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Tue, 16 Jun 2020 17:48:44 +0000 Subject: [PATCH] fsmgr: fix integer overflow in fs_mgr As the EXT4_MAX_BLOCK_SIZE defined as 65536 which reached maxium value of unsigned int. The superblock value maybe larger than 65536. This is found by the Integer Overflow Sanitizer. This patch fixed below boot error when userdata is corrupted: init: processing action (fs) from (/vendor/etc/init/hw/init.freescale.rc:221) init: [libfs_mgr]Invalid ext4 superblock on '/dev/block/by-name/userdata' init: InitFatalReboot: signal 6 init: #00 pc 00000000000af7e8 /system/bin/init (android::init::InitFatalReboot(int)+208) init: #01 pc 00000000000afbd0 /system/bin/init (android::init::InstallRebootSignalHandlers()::$_22::__invoke(int)+32) init: #02 pc 00000000000006bc [vdso:0000ffff9691b000] (__kernel_rt_sigreturn) init: #03 pc 000000000004e070 /system/lib64/bootstrap/libc.so (abort+176) init: #04 pc 000000000003427c /system/lib64/libfs_mgr.so (read_ext4_superblock(std::__1::basic_string, std::__1::allocator > const&, android::fs_mgr::FstabEntry const&, ext4_super_block*, int*)+1804) Test: boot with corrupted ext4 superblock Bug: 156200421 Signed-off-by: Haoran.Wang Change-Id: Ib1b69bf4623f69696cb637b226ec3359fc2ed409 (cherry picked from commit cb472b92e54ba1647c02397565958322f0d74929) Former-commit-id: e28dc48de52af3e216fb3a85df382f3643b39496 --- fs_mgr/fs_mgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 1c5bb6c7f..22d1284ec 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -331,7 +331,7 @@ static bool read_ext4_superblock(const std::string& blk_device, const FstabEntry // try backup superblock, if main superblock is corrupted for (unsigned int blocksize = EXT4_MIN_BLOCK_SIZE; blocksize <= EXT4_MAX_BLOCK_SIZE; blocksize *= 2) { - unsigned int superblock = blocksize * 8; + uint64_t superblock = blocksize * 8; if (blocksize == EXT4_MIN_BLOCK_SIZE) superblock++; if (TEMP_FAILURE_RETRY(pread(fd, sb, sizeof(*sb), superblock * blocksize)) !=