From nobody Mon Jan 22 17:30:02 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 4TJcfz3NhTz57qsb; Mon, 22 Jan 2024 17:30:03 +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 4TJcfz1MBGz4fWg; Mon, 22 Jan 2024 17:30:03 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705944603; 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=UPXUkfNcTja/ct9jUKp+nCXPc2Pweb7d4wWQ8J1Lyp4=; b=Lc6SsO2d39C9a20K/BGn5ZmkGKQXbpFntG++Vkt+9/0FtT8koEPUhNPdg++Rfj4zmJjOx2 PlD2vCDfVnNDz1C7Sdf6PWyeHQuu2L4T/a1jH+NBHhIYYrAw6ieg9MlS3j0QosE5wPUQhr ATcOOV78fDF6pG/YWVsSNmmQY0BA2LF1LFZZh+ZHPJNhliQaV2doS3ZDmS0qx6p2cMT7UX YExS2J9L2QFJ0CVkZH+VcFqWnM2shPyPmUsuAD0u/CXqBydC+d9IuJSrK9HZVkL6trJV8X fuyPQcDJ0aXMY7Kq05ZlVIVWKWJslOeJYzUXRjXx9ZmTAUt6aO+tSYo81/2/bA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705944603; 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=UPXUkfNcTja/ct9jUKp+nCXPc2Pweb7d4wWQ8J1Lyp4=; b=HljoEP0xO0BkhZiRqArjVjP/fh/0oNk96+ZcraIOLdRQ1rnrxK6C7DmznNZovniVSFK0/x l5oLVKpdv4NISxLCtjUKaPEL61hHRyc1OnTr6lIB/NrtvbARN5P6a0wLJgR3+wBd5yGXnb U1ZS89InpzfdAmKJcfMNbfHNpoCcq0MK7+ymw/Ubz/XuqWbSU44w6Z87NSNIFkxiKeoGWM Sv0Vl9Eqt54ZkvpIfufvQ5GeUB/iiPY4GrHVCqf/8Jrpn6gR7pbtp/8k3yC1QHSz7tBu8s 74RyoXCIVhzOvph8VszJwN7pedxuNxcVS1YWdleJJfnVrOxDJd0tKtqnAKTKhA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1705944603; a=rsa-sha256; cv=none; b=KvAEOfu7kqMeJWg1V3uyqMsXk45Fijchh1CFp+PmZZJgTvVpNQySy+pr4rUy+qKDrpf1OP Uc2ZuW+lPkWquxvYRkdsartI+lgqSWCZwkPSjoCgcU+fsZpHpUeRPy7SbjcupsU//bksNW ze6rdQsW1V8FGRxu5KTEkc5GSE/fwz8r98detXfkOhOOBSF+TaaBR6erDlzFtAcUtvqLUH Zh3iK3UmELc2C0z2VECvx1zU3notxENEXLyMIIz+S/J+dJkFLdlX9Ja3XwsmyfhwB9/ZM7 XSqrPAnfWTgRc6Hx93N7Pzxm/VfgK1AmSi4mNBs4zbuUPRt/CHRkAzwjFLEPdg== 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 4TJcfz0Sq3z19pC; Mon, 22 Jan 2024 17:30:03 +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 40MHU2ou008492; Mon, 22 Jan 2024 17:30:02 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40MHU2g6008488; Mon, 22 Jan 2024 17:30:02 GMT (envelope-from git) Date: Mon, 22 Jan 2024 17:30:02 GMT Message-Id: <202401221730.40MHU2g6008488@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: b7390f6f8412 - stable/13 - bhyveload: hold /boot and do relative lookups for the loader 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: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: b7390f6f8412fe46413b7fba6d3e74709d8e21e2 Auto-Submitted: auto-generated The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=b7390f6f8412fe46413b7fba6d3e74709d8e21e2 commit b7390f6f8412fe46413b7fba6d3e74709d8e21e2 Author: Kyle Evans AuthorDate: 2024-01-03 22:17:59 +0000 Commit: Kyle Evans CommitDate: 2024-01-22 17:17:48 +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 797f8b88dad2..c11b1814cfc7 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; @@ -615,7 +613,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); } @@ -624,9 +622,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); } @@ -741,13 +738,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; @@ -784,7 +806,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': @@ -827,12 +851,29 @@ 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); + } + } + /* * setjmp in the case the guest wants to swap out interpreter, * 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); @@ -849,19 +890,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());