From nobody Tue Apr 7 16:30:00 2026 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 4fqs9h2dm3z6YXbT for ; Tue, 07 Apr 2026 16: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 "R12" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fqs9h28dYz44ZV for ; Tue, 07 Apr 2026 16: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=1775579400; 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=upEOdYYRj8Gqp6zvJnU9SPyFXFf9WUFp/Ge85nbYOnk=; b=jB0ZeNfiGcK8HxjlGgsVmbrcmdrqy+YGhvB/mVRid2qDgfmJFWSAOw0W6afiKOQAf3j8QS Y+AiSSg2hqLzhli7cfDBWAc015EqVDfU1Ri7MwKG7oJ/6Q2HSh0MyN9Nyp1CNwWqMdUEIb XDIvtt+8/BVXl5rXBx2tGDf92leV4DylG4uCYlvq9jm1/EXEom81GP+RPuYO2SQXCifmST hR2GNl3IKVGCKXcowuZge/Oa5z2FBlDVDC8uZLspA4WPaZ7/o61YvyTNejg8IQixUAWg3n 8VzNKhmzrVo5im7ssX2o6zvLjq35PgZeOZGx7h+do0U8kZHNn0NLtpFCfszSHw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1775579400; a=rsa-sha256; cv=none; b=Ubb59l50PPvZP2ja0vt3+wCV28aryZToZDLPrbXOsHzV2akI6ebLRaFJc89c8RR5thY+0U /yZAv2KLsOaayJ0ZxBpixIV4Hkj+itOUhN3h9/aruKYRYsMlTWTE9pxbTagC3VSoyHLTe+ TvFKjhYHVU8heEmFJjSp5mYEvuUDT0DDPEKgjoOZt52f1jEQ3a3LbBudOZGvRu3yerG4aP oZmcJeDjnI57VsuSXbnfTl5heDt0o5Ga8iifia3OFwZCB6EBirVxe1mGqUMLBe9PaIpGlW 3jJpJ5tvETPnS3jvF5q27o+zB/q8b5IX1IWSy81G8fQ9Z5AFtAdNvO33bFH4/Q== 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=1775579400; 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=upEOdYYRj8Gqp6zvJnU9SPyFXFf9WUFp/Ge85nbYOnk=; b=A80rng4fW06cfxXZoGQkUpxVIIRmNQKEloTggtJ5OVR6UgeiUjddAlAMr1BfBVzoBWttC5 OWc7+yZTROev3QIStHy/bv8MHdJO/z/6MUY317ssBy1ghBczpdUdC+EadSwwfUnR1aV6ud YnYhCrtUZoPwmF6eeWqovpaLlvVThfKjCVumhEkyVXeqHIJy6kf+pi6hPFkuhi58aPOeh7 pJL5d2bxIgULl4R9KaYRAyQm3Cttfn0zuzutIWwQvGsQkQrH/fvaaq1EEVT0O0ywbOd5qB 9TjPiG+1tpUCVrXwcfMjFey3XX5ypSbcgbgw1o0NUwwv2uSoa1dqTpPf/nZuDQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fqs9h1fqbznX0 for ; Tue, 07 Apr 2026 16:30:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 18524 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 07 Apr 2026 16:30:00 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Simon J. Gerraty Subject: git: a371b008d13f - main - Add boot_setenv 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: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: sjg X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a371b008d13f84cf4448bf6d700641ecc15c206b Auto-Submitted: auto-generated Date: Tue, 07 Apr 2026 16:30:00 +0000 Message-Id: <69d53108.18524.3b40af3e@gitrepo.freebsd.org> The branch main has been updated by sjg: URL: https://cgit.FreeBSD.org/src/commit/?id=a371b008d13f84cf4448bf6d700641ecc15c206b commit a371b008d13f84cf4448bf6d700641ecc15c206b Author: Simon J. Gerraty AuthorDate: 2026-04-07 16:29:07 +0000 Commit: Simon J. Gerraty CommitDate: 2026-04-07 16:29:07 +0000 Add boot_setenv Move is_restricted_var() to libsa/environment.c so it can be leveraged by boot_setenv called from subr_boot with not truted input. Also, allow for local tuning via ENV_IS_RESTRICTED_ALLOWED_LIST and ENV_IS_RESTRICTED_LIST Sponsored by: Hewlett Packard Enterprise Development LP. Reviewed by: kevans, imp Differential Revision: https://reviews.freebsd.org/D56287 --- stand/common/commands.c | 60 ++----------------------------------- stand/efi/loader/main.c | 5 ++++ stand/libsa/environment.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++ stand/libsa/stand.h | 3 ++ sys/kern/subr_boot.c | 2 +- 5 files changed, 88 insertions(+), 58 deletions(-) diff --git a/stand/common/commands.c b/stand/common/commands.c index 19452047a0ca..41687ece42fd 100644 --- a/stand/common/commands.c +++ b/stand/common/commands.c @@ -291,63 +291,6 @@ command_show(int argc, char *argv[]) return (CMD_OK); } -#ifdef LOADER_VERIEXEC -static int -is_restricted_var(const char *var) -{ - /* - * We impose restrictions if input is not verified - * allowing for exceptions. - * These entries should include the '=' - */ - const char *allowed[] = { - "boot_function=", - "boot_phase=", - "boot_recover_cli=", - "boot_recover_volume=", - "boot_safe=", - "boot_set=", - "boot_single=", - "boot_verbose=", - NULL, - }; - const char *restricted[] = { - "boot", - "init", - "loader.ve.", - "rootfs", - "secur", - "vfs.", - NULL, - }; - const char **cp; - int ok = -1; - -#ifdef LOADER_VERIEXEC_TESTING - printf("Checking: %s\n", var); -#endif - for (cp = restricted; *cp; cp++) { - if (strncmp(var, *cp, strlen(*cp)) == 0) { - ok = 0; - break; - } - } - if (!ok) { - /* - * Check for exceptions. - * These should match up to '='. - */ - for (cp = allowed; *cp; cp++) { - if (strncmp(var, *cp, strlen(*cp)) == 0) { - ok = 1; - break; - } - } - } - return (ok == 0); -} -#endif - COMMAND_SET(set, "set", "set a variable", command_set); static int @@ -364,6 +307,9 @@ command_set(int argc, char *argv[]) ves = ve_status_get(-1); if (ves == VE_UNVERIFIED_OK) { +#ifdef LOADER_VERIEXEC_TESTING + printf("Checking: %s\n", var); +#endif if (is_restricted_var(argv[1])) { printf("Ignoring restricted variable: %s\n", argv[1]); diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index 1fd6c8d74195..e54f3e1f9f35 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -1242,6 +1242,11 @@ main(int argc, CHAR16 *argv[]) /* Report the RSDP early. */ acpi_detect(); +#ifdef LOADER_VERIEXEC + /* tell boot_setenv to be careful */ + set_check_restricted(true); +#endif + /* * Chicken-and-egg problem; we want to have console output early, but * some console attributes may depend on reading from eg. the boot diff --git a/stand/libsa/environment.c b/stand/libsa/environment.c index d139249a8e84..3882db6ee9e1 100644 --- a/stand/libsa/environment.c +++ b/stand/libsa/environment.c @@ -222,6 +222,82 @@ env_noset(struct env_var *ev __unused, int flags __unused, return (EPERM); } +bool +is_restricted_var(const char *name) +{ + /* + * We impose restrictions if input is not verified/trusted + * allowing for exceptions. + * These entries should probably include the '=' + */ + const char *allowed[] = { + "boot_function=", + "boot_phase=", + "boot_recover_cli=", + "boot_recover_volume=", + "boot_safe=", + "boot_set=", + "boot_single=", + "boot_verbose=", +#ifdef ENV_IS_RESTRICTED_ALLOWED_LIST + ENV_IS_RESTRICTED_ALLOWED_LIST, +#endif + NULL, + }; + /* + * These are prefixes we want to be careful with. + */ + const char *restricted[] = { + "boot", + "init", + "loader.ve.", + "rootfs", + "secur", + "vfs.", +#ifdef ENV_IS_RESTRICTED_LIST + ENV_IS_RESTRICTED_LIST, +#endif + NULL, + }; + const char **cp; + int ok = -1; + + for (cp = restricted; *cp; cp++) { + if (strncmp(name, *cp, strlen(*cp)) == 0) { + ok = 0; + break; + } + } + if (!ok) { + for (cp = allowed; *cp; cp++) { + if (strncmp(name, *cp, strlen(*cp)) == 0) { + ok = 1; + break; + } + } + } + return (ok == 0); +} + +static bool check_restricted = false; + +void +set_check_restricted(bool b) +{ + check_restricted = b; +} + +/* called from subr_boot with not quite trusted input */ +int +boot_setenv(const char *name, const char *value) +{ + if (check_restricted && is_restricted_var(name)) { + errno = EPERM; + return -1; + } + return setenv(name, value, 1); +} + int env_nounset(struct env_var *ev __unused) { diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index aaba0aa7fb39..4f7f21867cea 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -381,6 +381,9 @@ extern int setenv(const char *name, const char *value, int overwrite); extern int putenv(char *string); extern int unsetenv(const char *name); +extern bool is_restricted_var(const char *name); +extern void set_check_restricted(bool); +extern int boot_setenv(const char *name, const char *value); extern ev_sethook_t env_noset; /* refuse set operation */ extern ev_unsethook_t env_nounset; /* refuse unset operation */ diff --git a/sys/kern/subr_boot.c b/sys/kern/subr_boot.c index b721abf7013c..00c8e66617b8 100644 --- a/sys/kern/subr_boot.c +++ b/sys/kern/subr_boot.c @@ -53,7 +53,7 @@ #define GETENV(k) kern_getenv(k) #define FREE(v) freeenv(v) #else /* Boot loader */ -#define SETENV(k, v) setenv(k, v, 1) +#define SETENV(k, v) boot_setenv(k, v) #define GETENV(k) getenv(k) #define FREE(v) #endif