diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-01-24 23:18:18 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-02-09 22:13:18 +0100 |
commit | 4233a39933277b0d715d59d72942a8fd65bcec4a (patch) | |
tree | a7ef2db87b697d54c19ee03a115508b60f27f623 /lib/libmtd_legacy.c | |
parent | b636250e211198210ab996671bccc2983300c6f5 (diff) |
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 <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/libmtd_legacy.c')
-rw-r--r-- | lib/libmtd_legacy.c | 31 |
1 files changed, 20 insertions, 11 deletions
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; |