Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 01 Mar 2026 03:24:16 +0000
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 6da9d465c54b - main - bhyveload: simplify cb_open() and eliminate minor TOCTOU
Message-ID:  <69a3b160.264d7.32722ca9@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=6da9d465c54bf2e3496e83db025c5d22f3b3cc17

commit 6da9d465c54bf2e3496e83db025c5d22f3b3cc17
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2026-03-01 03:23:59 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-03-01 03:23:59 +0000

    bhyveload: simplify cb_open() and eliminate minor TOCTOU
    
    It's not at all clear why I wrote it like this, but we can do better.
    
    I wouldn't think this really has any meaningful security implications
    since the hierarchy in question can't really be modified by the guest
    scripts, but it would seem to make it a little more robust.
    
    Fixes:  6779d44bd878e3c ("bhyveload: use a dirfd to support -h")
    Reviewed by:    bnovkov, markj
    Differential Revision:  https://reviews.freebsd.org/D55379
---
 usr.sbin/bhyveload/bhyveload.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/usr.sbin/bhyveload/bhyveload.c b/usr.sbin/bhyveload/bhyveload.c
index 2b1bfec9a62d..4cc566f334c3 100644
--- a/usr.sbin/bhyveload/bhyveload.c
+++ b/usr.sbin/bhyveload/bhyveload.c
@@ -169,11 +169,9 @@ cb_open(void *arg __unused, const char *filename, void **hp)
 {
 	struct cb_file *cf;
 	struct stat sb;
-	int fd, flags;
+	int fd;
 
 	cf = NULL;
-	fd = -1;
-	flags = O_RDONLY | O_RESOLVE_BENEATH;
 	if (hostbase_fd == -1)
 		return (ENOENT);
 
@@ -185,20 +183,21 @@ cb_open(void *arg __unused, const char *filename, void **hp)
 	if (filename[0] == '\0')
 		filename = ".";
 
-	if (fstatat(hostbase_fd, filename, &sb, AT_RESOLVE_BENEATH) < 0)
-		return (errno);
-
-	if (!S_ISDIR(sb.st_mode) && !S_ISREG(sb.st_mode))
-		return (EINVAL);
-
-	if (S_ISDIR(sb.st_mode))
-		flags |= O_DIRECTORY;
-
 	/* May be opening the root dir */
-	fd = openat(hostbase_fd, filename, flags);
+	fd = openat(hostbase_fd, filename, O_RDONLY | O_RESOLVE_BENEATH);
 	if (fd < 0)
 		return (errno);
 
+	if (fstat(fd, &sb) < 0) {
+		int serrno = errno;
+
+		close(fd);
+		return (serrno);
+	} else if (!S_ISDIR(sb.st_mode) && !S_ISREG(sb.st_mode)) {
+		close(fd);
+		return (EINVAL);
+	}
+
 	cf = malloc(sizeof(struct cb_file));
 	if (cf == NULL) {
 		close(fd);
@@ -217,7 +216,6 @@ cb_open(void *arg __unused, const char *filename, void **hp)
 			return (ENOMEM);
 		}
 	} else {
-		assert(S_ISREG(cf->cf_stat.st_mode));
 		cf->cf_isdir = 0;
 		cf->cf_u.fd = fd;
 	}


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69a3b160.264d7.32722ca9>