From: Iris Chang <iris.ch...@mediatek.com>

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.ch...@mediatek.com>
---
 lib/libf2fs.c            | 28 ++++++++++++++++++++--------
 mkfs/f2fs_format_utils.c | 23 ++++++++++++++++-------
 2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 5c56416..05b026b 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -643,7 +643,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;
 
@@ -690,16 +690,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
 }
@@ -751,7 +754,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
@@ -787,16 +790,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");
@@ -806,11 +811,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;
@@ -851,6 +858,7 @@ int get_device_info(int i)
 #endif
        } else {
                MSG(0, "\tError: Volume type is not supported!!!\n");
+               free(stat_buf);
                return -1;
        }
 
@@ -859,11 +867,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) {
@@ -872,11 +881,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",
@@ -901,6 +912,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..4933fa5 100644
--- a/mkfs/f2fs_format_utils.c
+++ b/mkfs/f2fs_format_utils.c
@@ -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,7 +62,7 @@ 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) {
@@ -67,15 +70,18 @@ static int trim_device(int i)
                }
 #endif
                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,11 +90,14 @@ 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
 
 #endif
+       free(stat_buf);
        return 0;
 }
 
-- 
2.15.0.531.g2ccb3012c9-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to