From nobody Mon Jan 22 17:30:00 2024 X-Original-To: dev-commits-src-branches@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 4TJcfw48fGz57r9r; Mon, 22 Jan 2024 17:30: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 4TJcfw3G4nz4fR6; Mon, 22 Jan 2024 17:30:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705944600; 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=kmGzaSASlQXsIeCbZigD8D6l56u1wFa0HJ5PJY6FVxk=; b=kauRvwO0Oh1W39Uk1eslFjR44D72o3cSx1S1u2V8C+KyI3+ErTANCbQBpXH3y7KOTwUEG2 6X3dJQrjn9VmM6ydUMkdKmpa2Fb15K6FjLpKFmlLoVUowtBahZI/7C2o7lF8E6LzTXWpMd ZDhA1fNCZrjuRjer59U7c+gcQ9JDCd1e9m7R17s0rvlcxLn1xqn8leti6O7sONF7aCOfix YDM0pkmn3Q7I1++50l7WTTVlUEg8J17CnodrFtBcxQbaoS6rr/StBge3Io7mKyZNiRUwKC 0jszFzLQgpNClqKgpoT08PR0O8F9TGzuKD4j1sqQKbbdaPMY983V+DfUFq7cEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705944600; 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=kmGzaSASlQXsIeCbZigD8D6l56u1wFa0HJ5PJY6FVxk=; b=blMKL8sU9PZZuemhmx4i7oVtK5SaKIkWG782VY3q95lypYffJvVdlYf5L69GN6B2qSf0D5 naH/YAQpO04qwA2scfhZRIH5vj1+565w+P1qlPZ2z+z9/aoMX+c/pJTstGnxzTfV7+zBVn gHO31uBaiqxHxQQ7m6jJalz/LDYdZHti3mOhrF5dbb1a4Cl/L6m+rjBL/id5emYpSdPmgG D3bO7m5RYaoOpqJqbuq5eftDlnJlTCslRUXmWRgq0VqfqSRy6wPRY2WG6Zow78zB7OgdZE gLmS0YETPKX/rn56uO37i9uGkTHhV3/oLcl1tEkjw9lqrt/KxWUovHv3CfZMjw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1705944600; a=rsa-sha256; cv=none; b=IO0bU0hhrIqnh75vxgn5fU3mLUZObvGA90sDey3M1Dlu0nPLJf6cRTme40e6J+aiY0GPx4 FhozhaGAUcU+XaqACxD0vp2dYwojZxwMcBp9GNk3Vk748gDAElMbVikj49/kWU6toaA1tF BHbiIMzVcMYEkt4r4jVfcEEVs+N+E+xxmeb9+wtvufSjDQ7HUlSkqCNC4J1jCdcIUJ/BAG jIZ2YQeKdF3b+RQTJAKMYZaTLqve6/G9oiH77zcc0PNcr4Wesm/XBeNwnG/c75QqYJOsnb SxA8znG65/OVBg6ex0VuLeDW8HBkBPMdgB0eZ2O6hOTR6AqbkXW7NrPBgGQjcw== 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 4TJcfw2K2gz19pB; Mon, 22 Jan 2024 17:30: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 40MHU0mg006500; Mon, 22 Jan 2024 17:30:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40MHU0o9006475; Mon, 22 Jan 2024 17:30:00 GMT (envelope-from git) Date: Mon, 22 Jan 2024 17:30:00 GMT Message-Id: <202401221730.40MHU0o9006475@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: 3299277af825 - stable/14 - bhyveload: hold /boot and do relative lookups for the loader List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/stable/14 X-Git-Reftype: branch X-Git-Commit: 3299277af8257c4a1cd59b3d813fcacbbe358ca9 Auto-Submitted: auto-generated The branch stable/14 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=3299277af8257c4a1cd59b3d813fcacbbe358ca9 commit 3299277af8257c4a1cd59b3d813fcacbbe358ca9 Author: Kyle Evans AuthorDate: 2024-01-03 22:17:59 +0000 Commit: Kyle Evans CommitDate: 2024-01-22 17:18:37 +0000 bhyveload: hold /boot and do relative lookups for the loader The next change will push bhyveload into capability mode right after we allocate vcpu state, before we've setup or entered the loader, to limit the surface area that a rogue loader script can touch. With an explicit -l loader, we don't need to preopen /boot because changing interpreters isn't allowed. We'll just dlopen() entirely in advance in that case to eliminate some complexity. Reviewed by: allanjude (earlier version), markj (cherry picked from commit bf7c4fcbbb05ff99afde0744d013feeb35d77191) (cherry picked from commit 67082f077f39d9c7b7bd561c14622e6f3ef23681) --- usr.sbin/bhyveload/bhyveload.c | 73 +++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/usr.sbin/bhyveload/bhyveload.c b/usr.sbin/bhyveload/bhyveload.c index 4c1dbd583e1f..7503598ba94b 100644 --- a/usr.sbin/bhyveload/bhyveload.c +++ b/usr.sbin/bhyveload/bhyveload.c @@ -94,11 +94,9 @@ static int ndisks; static int consin_fd, consout_fd; static int hostbase_fd = -1; -static int need_reinit; - static void *loader_hdl; static char *loader; -static int explicit_loader; +static int explicit_loader_fd = -1; static jmp_buf jb; static char *vmname, *progname; @@ -618,7 +616,7 @@ cb_swap_interpreter(void *arg __unused, const char *interp_req) * not try to pivot to a different loader on them. */ free(loader); - if (explicit_loader == 1) { + if (explicit_loader_fd != -1) { perror("requested loader interpreter does not match guest userboot"); cb_exit(NULL, 1); } @@ -627,9 +625,8 @@ cb_swap_interpreter(void *arg __unused, const char *interp_req) cb_exit(NULL, 1); } - if (asprintf(&loader, "/boot/userboot_%s.so", interp_req) == -1) + if (asprintf(&loader, "userboot_%s.so", interp_req) == -1) err(EX_OSERR, "malloc"); - need_reinit = 1; longjmp(jb, 1); } @@ -744,13 +741,38 @@ hostbase_open(const char *base) err(EX_OSERR, "open"); } +static void +loader_open(int bootfd) +{ + int fd; + + if (loader == NULL) { + loader = strdup("userboot.so"); + if (loader == NULL) + err(EX_OSERR, "malloc"); + } + + assert(bootfd >= 0 || explicit_loader_fd >= 0); + if (explicit_loader_fd >= 0) + fd = explicit_loader_fd; + else + fd = openat(bootfd, loader, O_RDONLY | O_RESOLVE_BENEATH); + if (fd == -1) + err(EX_OSERR, "openat"); + + loader_hdl = fdlopen(fd, RTLD_LOCAL); + if (!loader_hdl) + errx(EX_OSERR, "dlopen: %s", dlerror()); +} + int main(int argc, char** argv) { void (*func)(struct loader_callbacks *, void *, int, int); uint64_t mem_size; - int opt, error, memflags; + int bootfd, opt, error, memflags, need_reinit; + bootfd = -1; progname = basename(argv[0]); memflags = 0; @@ -787,7 +809,9 @@ main(int argc, char** argv) loader = strdup(optarg); if (loader == NULL) err(EX_OSERR, "malloc"); - explicit_loader = 1; + explicit_loader_fd = open(loader, O_RDONLY); + if (explicit_loader_fd == -1) + err(EX_OSERR, "%s", loader); break; case 'm': @@ -830,6 +854,18 @@ main(int argc, char** argv) exit(1); } + /* + * If we weren't given an explicit loader to use, we need to support the + * guest requesting a different one. + */ + if (explicit_loader_fd == -1) { + bootfd = open("/boot", O_DIRECTORY | O_PATH); + if (bootfd == -1) { + perror("open"); + exit(1); + } + } + vcpu = vm_vcpu_open(ctx, BSP); /* @@ -837,7 +873,12 @@ main(int argc, char** argv) * cb_swap_interpreter will swap out loader as appropriate and set * need_reinit so that we end up in a clean state once again. */ - setjmp(jb); + if (setjmp(jb) != 0) { + dlclose(loader_hdl); + loader_hdl = NULL; + + need_reinit = 1; + } if (need_reinit) { error = vm_reinit(ctx); @@ -854,19 +895,7 @@ main(int argc, char** argv) exit(1); } - if (loader == NULL) { - loader = strdup("/boot/userboot.so"); - if (loader == NULL) - err(EX_OSERR, "malloc"); - } - if (loader_hdl != NULL) - dlclose(loader_hdl); - loader_hdl = dlopen(loader, RTLD_LOCAL); - if (!loader_hdl) { - printf("%s\n", dlerror()); - free(loader); - return (1); - } + loader_open(bootfd); func = dlsym(loader_hdl, "loader_main"); if (!func) { printf("%s\n", dlerror());