From 4233a39933277b0d715d59d72942a8fd65bcec4a Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Fri, 24 Jan 2020 23:18:18 +0100 Subject: mtd-utils: Fix various TOCTOU issues This patch restructures various code parts that follow the pattern of "stat(x, &sb) ... makes_sense(&sb) ... open(x)". Signed-off-by: David Oberhollenzer --- jffsX-utils/mkfs.jffs2.c | 4 +--- lib/libmtd_legacy.c | 31 ++++++++++++++++++++----------- misc-utils/ftl_check.c | 14 ++++++++------ misc-utils/ftl_format.c | 14 ++++++++------ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/jffsX-utils/mkfs.jffs2.c b/jffsX-utils/mkfs.jffs2.c index f46cc22..9cc5eaf 100644 --- a/jffsX-utils/mkfs.jffs2.c +++ b/jffsX-utils/mkfs.jffs2.c @@ -1772,9 +1772,7 @@ int main(int argc, char **argv) } out_fd = 1; } - if (lstat(rootdir, &sb)) { - sys_errmsg_die("%s", rootdir); - } + if (chdir(rootdir)) sys_errmsg_die("%s", rootdir); diff --git a/lib/libmtd_legacy.c b/lib/libmtd_legacy.c index 2b7f65f..4eb4a70 100644 --- a/lib/libmtd_legacy.c +++ b/lib/libmtd_legacy.c @@ -221,18 +221,21 @@ int legacy_get_mtd_oobavail(const char *node) struct nand_ecclayout_user usrlay; int fd, ret; - if (stat(node, &st)) + fd = open(node, O_RDONLY); + if (fd == -1) return sys_errmsg("cannot open \"%s\"", node); + if (fstat(fd, &st)) { + ret = sys_errmsg("cannot open \"%s\"", node); + goto out_close; + } + if (!S_ISCHR(st.st_mode)) { errno = EINVAL; - return errmsg("\"%s\" is not a character device", node); + ret = errmsg("\"%s\" is not a character device", node); + goto out_close; } - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - ret = ioctl(fd, ECCGETLAYOUT, &usrlay); if (ret < 0) { if (errno == EOPNOTSUPP) @@ -273,15 +276,24 @@ int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd) loff_t offs = 0; struct proc_parse_info pi; - if (stat(node, &st)) { + fd = open(node, O_RDONLY); + if (fd == -1) { sys_errmsg("cannot open \"%s\"", node); if (errno == ENOENT) normsg("MTD subsystem is old and does not support " "sysfs, so MTD character device nodes have " "to exist"); + return -1; + } + + if (fstat(fd, &st)) { + sys_errmsg("cannot stat \"%s\"", node); + close(fd); + return -1; } if (!S_ISCHR(st.st_mode)) { + close(fd); errno = EINVAL; return errmsg("\"%s\" is not a character device", node); } @@ -291,6 +303,7 @@ int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd) mtd->minor = minor(st.st_rdev); if (mtd->major != MTD_DEV_MAJOR) { + close(fd); errno = EINVAL; return errmsg("\"%s\" has major number %d, MTD devices have " "major %d", node, mtd->major, MTD_DEV_MAJOR); @@ -298,10 +311,6 @@ int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd) mtd->mtd_num = mtd->minor / 2; - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - if (ioctl(fd, MEMGETINFO, &ui)) { sys_errmsg("MEMGETINFO ioctl request failed"); goto out_close; diff --git a/misc-utils/ftl_check.c b/misc-utils/ftl_check.c index 5a04155..5b2dae5 100644 --- a/misc-utils/ftl_check.c +++ b/misc-utils/ftl_check.c @@ -206,18 +206,20 @@ int main(int argc, char *argv[]) exit(errflg > 0 ? 0 : EXIT_FAILURE); } - if (stat(argv[optind], &buf) != 0) { + fd = open(argv[optind], O_RDONLY); + if (fd == -1) { + perror("open failed"); + exit(EXIT_FAILURE); + } + if (fstat(fd, &buf) != 0) { perror("status check failed"); + close(fd); exit(EXIT_FAILURE); } if (!(buf.st_mode & S_IFCHR)) { fprintf(stderr, "%s is not a character special device\n", argv[optind]); - exit(EXIT_FAILURE); - } - fd = open(argv[optind], O_RDONLY); - if (fd == -1) { - perror("open failed"); + close(fd); exit(EXIT_FAILURE); } diff --git a/misc-utils/ftl_format.c b/misc-utils/ftl_format.c index bf3c8f2..34d436c 100644 --- a/misc-utils/ftl_format.c +++ b/misc-utils/ftl_format.c @@ -312,18 +312,20 @@ int main(int argc, char *argv[]) exit(errflg > 0 ? EXIT_SUCCESS : EXIT_FAILURE); } - if (stat(argv[optind], &buf) != 0) { + fd = open(argv[optind], O_RDWR); + if (fd == -1) { + perror("open failed"); + exit(EXIT_FAILURE); + } + if (fstat(fd, &buf) != 0) { perror("status check failed"); + close(fd); exit(EXIT_FAILURE); } if (!(buf.st_mode & S_IFCHR)) { fprintf(stderr, "%s is not a character special device\n", argv[optind]); - exit(EXIT_FAILURE); - } - fd = open(argv[optind], O_RDWR); - if (fd == -1) { - perror("open failed"); + close(fd); exit(EXIT_FAILURE); } -- cgit v1.2.3