From nobody Wed Feb 14 06:06:00 2024 X-Original-To: dev-commits-src-all@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 4TZSP42wM4z5B53g; Wed, 14 Feb 2024 06:06:00 +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 4TZSP426lrz4Rx4; Wed, 14 Feb 2024 06:06:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1707890760; 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=nA0poWkLUPH8cI2K4uny/Dr0K6L90X9K+wva4CibnFM=; b=TPHLUm4u2RVzo15Ht5aT/X/SZFKc8PbKvnEYeeNdodELl4WUESkH0s6dniQTpMi5zjZf9b Uqa+agPoKv1MP0etrk2XetCa6uB0ZHWKleoEBb+cvXHJOc+8h9pxQLi9Hjw0Ca/dXYBsF+ oQ15lYdd7eQ/3aOfnvf7rDId0F/D3BT9SmUp3aP5vQaHbNEAgdQOPLj5P1pWSkbBH9Dcjo eAkEJAinN7KvvV3XJEqxCp4ihb+JqkeslQa6A9JJpohI4zqiS36Od4+s0Wmf8vhwCrBvkY qzE/172bQ/DQxoJfOqinvrkhbiganBTCN5MRhSDGtt5SzmcR4l7D6KRpFnpISw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1707890760; a=rsa-sha256; cv=none; b=eknDiTVSSUJ2bf8e5WmMwCZEZcOjMV6P+ilwj/p+oxB0N7cePD6UjoLsB+N/jK1TI1F3bq HtE3OLnrnW+fvpSSkpzpi+DWi4g5PNfA4niU3+BVoAwytpY2j4JRDR2AJrNoR0eSQ+0auH QlPYd4lBzoRiQrGCR4KrS6gUpLq7k8BiaN4JBEfcI7biNMwTprlzvsR0xvy4olBB48td82 1DwUU7Ogyka9ZkwtW4bnfJl7WqjpCy655aPqVZNllDUTCqnN9k2o0bdiIcb7L189jH0Yk7 M4hak6PAJyPhaSWv1GWS5j4oagirtwvL5415sDEPsfUjDlip1pEse/Z7b44lhw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1707890760; 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=nA0poWkLUPH8cI2K4uny/Dr0K6L90X9K+wva4CibnFM=; b=RITgDOtttZ0ollmvFo2hN30G8y23MuM0xRijOvcH5mc6NzVf33dzHDjkNm5v63mKc4gq/C ZZWXgPu/yGqZf/sT/D6LCejZcERGS23jaysWj5r9U0ktE7RkBatiYp7FHuyQMGUaoEk1xW Qb9NBGI0TDW63LXpiiJjqTNMEvfoefZx9DassyFVQOR3KKS0v/N7GWhvYNw3svgsMf134q gu6yc22haYXyygWUjUkdlkD94vk1nXYByyktTLw5k0dreN2e+rtFO6gEMdL2mTWRDWTAWR eGkwLaMnYmWDnoVypxSrZGJgyw0XnBipcBCNpewFXjwvHUqdOjFcGgUi4xBZPw== 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 4TZSP41Ckyzmts; Wed, 14 Feb 2024 06:06:00 +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 41E660qN085230; Wed, 14 Feb 2024 06:06:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 41E6606U085227; Wed, 14 Feb 2024 06:06:00 GMT (envelope-from git) Date: Wed, 14 Feb 2024 06:06:00 GMT Message-Id: <202402140606.41E6606U085227@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Gordon Tetlow Subject: git: 48598b1670ce - releng/13.2 - bhyveload: use a dirfd to support -h List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gordon X-Git-Repository: src X-Git-Refname: refs/heads/releng/13.2 X-Git-Reftype: branch X-Git-Commit: 48598b1670ce542419420f969d5a5bd47167eb17 Auto-Submitted: auto-generated The branch releng/13.2 has been updated by gordon: URL: https://cgit.FreeBSD.org/src/commit/?id=48598b1670ce542419420f969d5a5bd47167eb17 commit 48598b1670ce542419420f969d5a5bd47167eb17 Author: Kyle Evans AuthorDate: 2024-01-03 22:17:59 +0000 Commit: Gordon Tetlow CommitDate: 2024-02-14 05:43: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 Approved by: so Security: FreeBSD-SA-24:01.bhyveload Security: CVE-2024-25940 (cherry picked from commit 6779d44bd878e3cf4723f7386b11da6508ab5431) (cherry picked from commit 78345dbd7a004e0a6d1b717e7dbc758ae67ca293) --- usr.sbin/bhyveload/bhyveload.c | 85 ++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/usr.sbin/bhyveload/bhyveload.c b/usr.sbin/bhyveload/bhyveload.c index 1a24b5f0044a..4f15771b514d 100644 --- a/usr.sbin/bhyveload/bhyveload.c +++ b/usr.sbin/bhyveload/bhyveload.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -93,11 +94,11 @@ __FBSDID("$FreeBSD$"); #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; @@ -163,42 +164,61 @@ static int cb_open(void *arg, 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 @@ -712,6 +732,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) { @@ -746,7 +777,7 @@ main(int argc, char** argv) break; case 'h': - host_base = optarg; + hostbase_open(optarg); break; case 'l':