From nobody Wed Jan 3 22:19:26 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T53zg0mD0z56qGt; Wed, 3 Jan 2024 22:19:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T53zg0Fcfz4cFX; Wed, 3 Jan 2024 22:19:27 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704320367; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xDprSmRJUQgD2LopH1LVsfbeCBtu8GurtnUuWEWNy/s=; b=fkzq1dB8PSV5oGuAIr6qpvbqplqX5J+2mD0J5ji0UVJgUcavq66li9K7yrozcf0X/eVJiI cWtGqVTk4amjwmOTnt5pDakFJelrBdmseit6sQA/TsZGvKlhHXAWj59935vBsPfe5UvnvC BFeDheUo3QOF0tDQsL5oNbmJt7noCdN0P0ZMoEs9RchiWNtqAduPVDg+Sl5SmdKNmkPA6b /M7QpkL16NGIKAB4DZT0vthSW6LnTfu4fS6qzlblt/tv1kXB5kp1xX3S15rXO7qohk03Eb ZTq/Dc+ixZx+7JN2dMQeHxcSELaFi4jCKAOU/Gfe2f9jSkgX53MlAJiytqBGbA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704320367; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xDprSmRJUQgD2LopH1LVsfbeCBtu8GurtnUuWEWNy/s=; b=pvg63e1O/J5g2o2Foui7fmWse+915v9tCYTBS++eRcR49MyX+5u5lezOQn8UBuQNL1RAjO M5zveoL6Zsb2waHyc3extLE9LkGrxyiIzHdlinFFfLqBNTviDEvaF8IDRWY4oeKc55Gt6f tlUhGAeHSWMjD/fy+hKUz+rukJ93OE0ygtpopo766SlIlL49ofHFOKvGToGMiKKCF+jn3j LVSO1lII/vPYZ/IbttY+IdF/wp0k9qZcMjJg+Gb5h5FzlY/kd3Djf+qHyI9kIzbcWGJUm4 Dc89z70OeJpAlp21G9DIHNjBEtkdaKSKyz78GcZ0W/rDJLomD+XS1dD2Fy/W/A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704320367; a=rsa-sha256; cv=none; b=IhlkdEhH8H8kjLywLJuFUxcR2BmPeqmDLxo34h3zXsd4ISNsI41TjwXncM8iY+xw7RtuLf Ll4HQIPzF06617JzqPWBqCIzH/VWeW1vvXakNnmSLNfqTL6brd1vhYiHmFJ7VFLck41y/0 HtOf5qjuIae1I6RiGBIx91YteLf5F5Xpvy+xh3R2Ps8GGl62Jw6uM5fRK1Qod5IWPNJdMP i0Y3kBC3G+WfIVjTTaE0pG47BBnmfbIPgicv+oJ6aC6rsRdu6uCWJWs4ufVh+194QYLO/s GXC6eLs+4MY1utEA+bq+nAt5UsaDD2xlpe1dAsdYhPpAhEZNQaj/GcW3eCTVtA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T53zf6J7lz135v; Wed, 3 Jan 2024 22:19:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 403MJQg1090848; Wed, 3 Jan 2024 22:19:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 403MJQwo090845; Wed, 3 Jan 2024 22:19:26 GMT (envelope-from git) Date: Wed, 3 Jan 2024 22:19:26 GMT Message-Id: <202401032219.403MJQwo090845@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: 6779d44bd878 - main - bhyveload: use a dirfd to support -h List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6779d44bd878e3cf4723f7386b11da6508ab5431 Auto-Submitted: auto-generated The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=6779d44bd878e3cf4723f7386b11da6508ab5431 commit 6779d44bd878e3cf4723f7386b11da6508ab5431 Author: Kyle Evans AuthorDate: 2024-01-03 22:17:59 +0000 Commit: Kyle Evans CommitDate: 2024-01-03 22:19:15 +0000 bhyveload: use a dirfd to support -h Don't allow lookups from the loader scripts, which in rare cases may be in guest control depending on the setup, to leave the specified host root. Open the root dir and strictly do RESOLVE_BENEATH lookups from there. cb_open() has been restructured a bit to work nicely with this, using fdopendir() in the directory case and just using the fd we already opened in the regular file case. hostbase_open() was split out to provide an obvious place to apply rights(4) if that's something we care to do. Reviewed by: allanjude (earlier version), markj Differential Revision: https://reviews.freebsd.org/D43284 --- usr.sbin/bhyveload/bhyveload.c | 84 ++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/usr.sbin/bhyveload/bhyveload.c b/usr.sbin/bhyveload/bhyveload.c index 6b2633cac288..4c1dbd583e1f 100644 --- a/usr.sbin/bhyveload/bhyveload.c +++ b/usr.sbin/bhyveload/bhyveload.c @@ -88,11 +88,11 @@ #define NDISKS 32 -static char *host_base; static struct termios term, oldterm; static int disk_fd[NDISKS]; static int ndisks; static int consin_fd, consout_fd; +static int hostbase_fd = -1; static int need_reinit; @@ -159,42 +159,61 @@ static int cb_open(void *arg __unused, const char *filename, void **hp) { struct cb_file *cf; - char path[PATH_MAX]; + struct stat sb; + int fd, flags; - if (!host_base) + cf = NULL; + fd = -1; + flags = O_RDONLY | O_RESOLVE_BENEATH; + if (hostbase_fd == -1) return (ENOENT); - strlcpy(path, host_base, PATH_MAX); - if (path[strlen(path) - 1] == '/') - path[strlen(path) - 1] = 0; - strlcat(path, filename, PATH_MAX); - cf = malloc(sizeof(struct cb_file)); - if (stat(path, &cf->cf_stat) < 0) { - free(cf); + /* Absolute paths are relative to our hostbase, chop off leading /. */ + if (filename[0] == '/') + filename++; + + /* Lookup of /, use . instead. */ + 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); + if (fd < 0) + return (errno); + + cf = malloc(sizeof(struct cb_file)); + if (cf == NULL) { + close(fd); + return (ENOMEM); } + cf->cf_stat = sb; cf->cf_size = cf->cf_stat.st_size; + if (S_ISDIR(cf->cf_stat.st_mode)) { cf->cf_isdir = 1; - cf->cf_u.dir = opendir(path); - if (!cf->cf_u.dir) - goto out; - *hp = cf; - return (0); - } - if (S_ISREG(cf->cf_stat.st_mode)) { + cf->cf_u.dir = fdopendir(fd); + if (cf->cf_u.dir == NULL) { + close(fd); + free(cf); + return (ENOMEM); + } + } else { + assert(S_ISREG(cf->cf_stat.st_mode)); cf->cf_isdir = 0; - cf->cf_u.fd = open(path, O_RDONLY); - if (cf->cf_u.fd < 0) - goto out; - *hp = cf; - return (0); + cf->cf_u.fd = fd; } - -out: - free(cf); - return (EINVAL); + *hp = cf; + return (0); } static int @@ -714,6 +733,17 @@ usage(void) exit(1); } +static void +hostbase_open(const char *base) +{ + + if (hostbase_fd != -1) + close(hostbase_fd); + hostbase_fd = open(base, O_DIRECTORY | O_PATH); + if (hostbase_fd == -1) + err(EX_OSERR, "open"); +} + int main(int argc, char** argv) { @@ -748,7 +778,7 @@ main(int argc, char** argv) break; case 'h': - host_base = optarg; + hostbase_open(optarg); break; case 'l':