From nobody Wed Jan 03 22:19:27 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 4T53zh1PBZz56q5m; Wed, 3 Jan 2024 22:19:28 +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 4T53zh0sGkz4cT7; Wed, 3 Jan 2024 22:19:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704320368; 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=2pO99qV7CGp/YxUI2rhYh5W37asdoUymMm7fgvJlPm4=; b=fII2apRax0mGOFTLL8AQ5Lu+A8OBKxwH9kKN2HJp8UdQPN2FJx2MgPhe9bGMukBtsRL7xm pa/5DHjOyvPTMpGUKqEhhbs9qdGR4XIvJ58NkFddS3HaYKHoIYa0jZB/V303e2hVIoOIuF inU31HStPzgzU6Yn+njonsqlu8dbLS3tGtcT1B+8v3XHO0JoKJdnERPzGGt/mkYpdBUuk+ 5BfoHb+yc4lxU/rKZDBCU01JKbQdXd4keAGtGjsg2CCXmAbHTY9OXF41OczEthZ/89F8fs RqsR6K/bgjaclUc/INNp8nh0VK3IAyceTXhMekySpctiH8uUY3IfTymsvDZd8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704320368; 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=2pO99qV7CGp/YxUI2rhYh5W37asdoUymMm7fgvJlPm4=; b=LS4WNg04rQJMHQGfNbOlmraSuwetflXWoZ3ygxyrGAQFTkRCi0lJW/x2IMpxYmmrvAMTWN PZGv4/VwFlrsdRr7GAPClyZk3nZam+wKwQC5e7ADKrRoXHgMD92LvzhYox49zCrqYkkvFH /O32Ye8yF0c2N4iczE37Kvy2/obqR9pXVdmtmj4Gocr9XXMi8jE+gp27ck1B19qqqB0Qf+ ZA7WBWlPywteQ8KW6mqUiPYJZTi7HtVw5dknDqUj5G3ynPxF1N7CLQ0aCEJf4TzZSvLENV EdVujmgatECghuGmVdgzxpTV18vR2HIfJTOcIWovdBQElr2NXhAxbjoEikAxBg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704320368; a=rsa-sha256; cv=none; b=dDPJiyRKyDbzn1g9XS5rhsX5x6gy3yM3rqVOECDU75E+7d0GbQnenMbjsiZXcS9emVthp3 mMekbIOUju5jZGWyr76FLlEOUOidAhaV61GnZGJa+yq5NnLIxJjsEHsmkQ3RCFak5kWjOA GOLz2EnxdsRivSGP8rMuMTStdlMneRfoBC511DhJLNig3wmrq19ftHolQjCqQ1fbPyIfOw EqRQvULNIaZCk46o378zIIkHy9vg1JF0oNKCdtrBrDjJjX9/OGe24nsgjSsIDh17F0iQNg WKxhR2kvImC2LOBoPpL6NeQKAw7rRuoNFQvAkMcy/TmriMhkVjcrbjFMQ+DV6g== 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 4T53zg7450z135w; Wed, 3 Jan 2024 22:19:27 +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 403MJRGl090905; Wed, 3 Jan 2024 22:19:27 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 403MJR4h090902; Wed, 3 Jan 2024 22:19:27 GMT (envelope-from git) Date: Wed, 3 Jan 2024 22:19:27 GMT Message-Id: <202401032219.403MJR4h090902@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: bf7c4fcbbb05 - main - 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/main X-Git-Reftype: branch X-Git-Commit: bf7c4fcbbb05ff99afde0744d013feeb35d77191 Auto-Submitted: auto-generated The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=bf7c4fcbbb05ff99afde0744d013feeb35d77191 commit bf7c4fcbbb05ff99afde0744d013feeb35d77191 Author: Kyle Evans AuthorDate: 2024-01-03 22:17:59 +0000 Commit: Kyle Evans CommitDate: 2024-01-03 22:19:15 +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 Differential Revision: https://reviews.freebsd.org/D43285 --- 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..855ce5947a93 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; 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());