From 865a3ead184e3d578b641eea90b4c68533f93ff5 Mon Sep 17 00:00:00 2001 From: Iris Chang Date: Mon, 2 Apr 2018 15:59:24 +0800 Subject: [PATCH] f2fs-tools: use pointer and memory alloaction instead of defining "structure stat" in function stack Problem: Function f2fs_dev_is_unmounted() and get_device_info() define local variable "struct stat xxx". If the callstack is very deep and stack is smaller, it will result in stack corruption. Solution: It is better to use pointer and memory allocation instead of defining "structure stat" in function stack. Signed-off-by: Iris Chang [Jaegeuk Kim: fix build errors.] Signed-off-by: Jaegeuk Kim --- lib/libf2fs.c | 28 ++++++++++++++++++++-------- mkfs/f2fs_format_utils.c | 25 +++++++++++++++++-------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/lib/libf2fs.c b/lib/libf2fs.c index bb7fe2e..c2daf8a 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -656,7 +656,7 @@ int f2fs_dev_is_umounted(char *path) #ifdef ANDROID_WINDOWS_HOST return 0; #else - struct stat st_buf; + struct stat *st_buf; int is_rootdev = 0; int ret = 0; @@ -703,16 +703,19 @@ int f2fs_dev_is_umounted(char *path) * If f2fs is umounted with -l, the process can still use * the file system. In this case, we should not format. */ - if (stat(path, &st_buf) == 0 && S_ISBLK(st_buf.st_mode)) { + st_buf = malloc(sizeof(struct stat)); + if (stat(path, st_buf) == 0 && S_ISBLK(st_buf->st_mode)) { int fd = open(path, O_RDONLY | O_EXCL); if (fd >= 0) { close(fd); } else if (errno == EBUSY) { MSG(0, "\tError: In use by the system!\n"); + free(st_buf); return -1; } } + free(st_buf); return ret; #endif } @@ -764,7 +767,7 @@ int get_device_info(int i) #ifndef BLKGETSIZE64 uint32_t total_sectors; #endif - struct stat stat_buf; + struct stat *stat_buf; #ifdef HDIO_GETGIO struct hd_geometry geom; #endif @@ -800,16 +803,18 @@ int get_device_info(int i) } } - if (fstat(fd, &stat_buf) < 0 ) { + stat_buf = malloc(sizeof(struct stat)); + if (fstat(fd, stat_buf) < 0 ) { MSG(0, "\tError: Failed to get the device stat!\n"); + free(stat_buf); return -1; } if (c.sparse_mode) { dev->total_sectors = c.device_size / dev->sector_size; - } else if (S_ISREG(stat_buf.st_mode)) { - dev->total_sectors = stat_buf.st_size / dev->sector_size; - } else if (S_ISBLK(stat_buf.st_mode)) { + } else if (S_ISREG(stat_buf->st_mode)) { + dev->total_sectors = stat_buf->st_size / dev->sector_size; + } else if (S_ISBLK(stat_buf->st_mode)) { #ifdef BLKSSZGET if (ioctl(fd, BLKSSZGET, §or_size) < 0) MSG(0, "\tError: Using the default sector size\n"); @@ -819,11 +824,13 @@ int get_device_info(int i) #ifdef BLKGETSIZE64 if (ioctl(fd, BLKGETSIZE64, &dev->total_sectors) < 0) { MSG(0, "\tError: Cannot get the device size\n"); + free(stat_buf); return -1; } #else if (ioctl(fd, BLKGETSIZE, &total_sectors) < 0) { MSG(0, "\tError: Cannot get the device size\n"); + free(stat_buf); return -1; } dev->total_sectors = total_sectors; @@ -864,6 +871,7 @@ int get_device_info(int i) #endif } else { MSG(0, "\tError: Volume type is not supported!!!\n"); + free(stat_buf); return -1; } @@ -872,11 +880,12 @@ int get_device_info(int i) c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size; } else if (c.sector_size != c.devices[i].sector_size) { MSG(0, "\tError: Different sector sizes!!!\n"); + free(stat_buf); return -1; } #if !defined(WITH_ANDROID) && defined(__linux__) - if (S_ISBLK(stat_buf.st_mode)) + if (S_ISBLK(stat_buf->st_mode)) f2fs_get_zoned_model(i); if (dev->zoned_model != F2FS_ZONED_NONE) { @@ -885,11 +894,13 @@ int get_device_info(int i) if (f2fs_get_zone_blocks(i)) { MSG(0, "\tError: Failed to get number of blocks per zone\n"); + free(stat_buf); return -1; } if (f2fs_check_zones(i)) { MSG(0, "\tError: Failed to check zone configuration\n"); + free(stat_buf); return -1; } MSG(0, "Info: Host-%s zoned block device:\n", @@ -914,6 +925,7 @@ int get_device_info(int i) } c.total_sectors += dev->total_sectors; + free(stat_buf); return 0; } diff --git a/mkfs/f2fs_format_utils.c b/mkfs/f2fs_format_utils.c index e481a8f..bf9ffbd 100644 --- a/mkfs/f2fs_format_utils.c +++ b/mkfs/f2fs_format_utils.c @@ -20,6 +20,7 @@ #include #include +#include #ifndef ANDROID_WINDOWS_HOST #include #endif @@ -44,13 +45,15 @@ static int trim_device(int i) { #ifndef ANDROID_WINDOWS_HOST unsigned long long range[2]; - struct stat stat_buf; + struct stat *stat_buf; struct device_info *dev = c.devices + i; u_int64_t bytes = dev->total_sectors * dev->sector_size; int fd = dev->fd; - if (fstat(fd, &stat_buf) < 0 ) { + stat_buf = malloc(sizeof(struct stat)); + if (fstat(fd, stat_buf) < 0 ) { MSG(1, "\tError: Failed to get the device stat!!!\n"); + free(stat_buf); return -1; } @@ -59,23 +62,27 @@ static int trim_device(int i) #if defined(WITH_BLKDISCARD) && defined(BLKDISCARD) MSG(0, "Info: [%s] Discarding device\n", dev->path); - if (S_ISREG(stat_buf.st_mode)) { + if (S_ISREG(stat_buf->st_mode)) { #if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE) if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, range[0], range[1]) < 0) { MSG(0, "Info: fallocate(PUNCH_HOLE|KEEP_SIZE) is failed\n"); } #endif + free(stat_buf); return 0; - } else if (S_ISBLK(stat_buf.st_mode)) { - if (dev->zoned_model != F2FS_ZONED_NONE) + } else if (S_ISBLK(stat_buf->st_mode)) { + if (dev->zoned_model != F2FS_ZONED_NONE) { + free(stat_buf); return f2fs_reset_zones(i); + } #ifdef BLKSECDISCARD if (ioctl(fd, BLKSECDISCARD, &range) < 0) { MSG(0, "Info: This device doesn't support BLKSECDISCARD\n"); } else { MSG(0, "Info: Secure Discarded %lu MB\n", - (unsigned long)stat_buf.st_size >> 20); + (unsigned long)stat_buf->st_size >> 20); + free(stat_buf); return 0; } #endif @@ -84,10 +91,12 @@ static int trim_device(int i) } else { MSG(0, "Info: Discarded %llu MB\n", range[1] >> 20); } - } else + } else { + free(stat_buf); return -1; + } #endif - + free(stat_buf); #endif return 0; } -- 2.7.4