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 | |
| 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')
| -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; | 
