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:	6779d44bd8 ("bhyveload: use a dirfd to support -h")
Reviewed by:	bnovkov, markj
Differential Revision:	https://reviews.freebsd.org/D55379
This commit is contained in:
Kyle Evans committed 2026-02-28 21:23:59 -06:00
1 parent 6099b46002
commit 6da9d465c5
1 file changed
+12 -14
+12 -14
View File
@@ -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;
}