f2fs-tools: use pointer and memory alloaction instead of defining "structure stat...
authorIris Chang <iris.chang@mediatek.com>
Mon, 2 Apr 2018 07:59:24 +0000 (15:59 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 5 Apr 2018 05:22:33 +0000 (22:22 -0700)
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 <iris.chang@mediatek.com>
[Jaegeuk Kim: fix build errors.]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
lib/libf2fs.c
mkfs/f2fs_format_utils.c

index bb7fe2e..c2daf8a 100644 (file)
@@ -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, &sector_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;
 }
 
index e481a8f..bf9ffbd 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <stdlib.h>
 #ifndef ANDROID_WINDOWS_HOST
 #include <sys/ioctl.h>
 #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;
 }