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 --- lib/libmtd_legacy.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'lib') 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; -- cgit v1.2.3