From nobody Tue Oct 11 07:51:54 2022 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 4Mmnzt6099z4fB0w; Tue, 11 Oct 2022 07:51:54 +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 4Mmnzt4349z3GMX; Tue, 11 Oct 2022 07:51:54 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1665474714; 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=YoNTmSoaUNDbEkLDzifFO2WEmFS2aG//W2UoUznoI0A=; b=ON769L2Ors+TY+BI+RKqACVwH67EpGypRh0gC4JDUGyj65rv1n+vDGyaTtjAdsam9WVxLp BMKWz8EPm0aWR8VNE6D6kpPr0vSsj+2u0/6HtabMNZYbjyYymKSfrA8fXd5TuQJ+nUI75T eVZN6k8sGWWczON2eprproRiPc7xg9ZkcqLKlswwWuI5CfFhRTqhgfrILqhi9ByPXWv/dw yDgRVUkVt5TeUQZ3kCwSf/H4wH2kAQVKG+BeaLnYh5Gv0lLUl+Aw/oRtqgrv9v5ccEwRjA 3rm1Z118BFDsK/kdZ/OekGPHpNThgZh/+kf3zT5s7a0gaESCJjChx5amjPSIug== 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 4Mmnzt36pczthD; Tue, 11 Oct 2022 07:51:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 29B7psG2053021; Tue, 11 Oct 2022 07:51:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 29B7pslu053020; Tue, 11 Oct 2022 07:51:54 GMT (envelope-from git) Date: Tue, 11 Oct 2022 07:51:54 GMT Message-Id: <202210110751.29B7pslu053020@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Wojciech Macek Subject: git: f3dba162bd46 - main - init: allow to start script executions with sh -o verify 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: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wma X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f3dba162bd46cd851a5491db680c1e6292c15a39 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1665474714; 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=YoNTmSoaUNDbEkLDzifFO2WEmFS2aG//W2UoUznoI0A=; b=IaD89I29aeuVrlNWyRXoyKgJNsUIeKSC9Dn640E5BpuIlwWqR7yHeZSV8Mc8MZvGOi8w47 2iKsDqdEAdC2e+9U1wz3SDJSVV6ghmnMY7aZC5L76MsoPu1k/fCOzVu+UcNb9IoNly8kGZ Kicyv7dOmvNPGEfjA2EdURYKJUwX73L5wCX6AboVpv39VhhfdckJEJ1pKqr9BjaenGYffq MEWY+2KIEgWFy51BzMIiJSo2XEhPqu5wxsGp4+ZGZongKHxfjEtqhMg4imel0CyjEC6VF9 s1nSm6Gb7mZ3eb+a3mpoWv8zaaTx808ojvoYunx7+/eQ/cezz4HcNWN8Hy9OXg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1665474714; a=rsa-sha256; cv=none; b=taGlu2ox7Fbi5oSwh4vjUCFI7qzumBoQVUt8d1DitXTTo5Jj8vZdnB7pJb6f9mJcoOlhMZ 9lDsiFLgbwhuRXt6cj3tizR+0rH58jj/Qr4FlJGE2LMydBybZyY9VpVhBhrZW6SQhARFFg 4rOxhyemLTS04AktfFYLm5jMRTpFySrxVSm6q5SrMHGHxNQ2dnTJnPpAt3FHje/xv8jx/p IihDlZOM9rPoK+MQYDI2Pf3ki5Oe6tj0Bmiph+jlI0Zd5NTTYtR9IPYa+wMqwEwtmXTeXw 2OKb9qQXnhiCCxInSf4Yyn+U3+yMFRLTNKA7JWuCem64iiI0pRt2nfnltFeiKA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by wma: URL: https://cgit.FreeBSD.org/src/commit/?id=f3dba162bd46cd851a5491db680c1e6292c15a39 commit f3dba162bd46cd851a5491db680c1e6292c15a39 Author: Sebastien Bini AuthorDate: 2022-10-11 07:48:04 +0000 Commit: Wojciech Macek CommitDate: 2022-10-11 07:48:04 +0000 init: allow to start script executions with sh -o verify On systems where mac_veriexec is enforced, init should run its scripts in verified mode. This relies on the verify shell option introduced by D30464. init will detect if the shell is /bin/sh, and in which case, add the verify option to the argument vector. The verify option propagates to all files sourced by the shell, ensuring a better protection than if the script was tested against an open(O_VERIFY) before running it. This security can be bypassed with the kenv which overloads the shell to use. However we feel confident that on systems running with mac_veriexec, this kenv will be blocked somehow. Also, the verify option has no effect on systems where mac_veriexec is not loaded nor enforced. Differential revision: https://reviews.freebsd.org/D34622 Reviewed by: sjg, wma --- sbin/init/init.c | 53 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/sbin/init/init.c b/sbin/init/init.c index cf48721faf8d..dd8800d21910 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -99,6 +99,7 @@ static const char rcsid[] = #define RESOURCE_RC "daemon" #define RESOURCE_WINDOW "default" #define RESOURCE_GETTY "default" +#define SCRIPT_ARGV_SIZE 3 /* size of argv passed to execute_script, can be increased if needed */ static void handle(sig_t, ...); static void delset(sigset_t *, ...); @@ -1044,8 +1045,9 @@ static void execute_script(char *argv[]) { struct sigaction sa; + char* sh_argv[3 + SCRIPT_ARGV_SIZE]; const char *shell, *script; - int error; + int error, sh_argv_len, i; bzero(&sa, sizeof(sa)); sigemptyset(&sa.sa_mask); @@ -1066,17 +1068,28 @@ execute_script(char *argv[]) * to sh(1). Don't complain if it fails because of * the missing execute bit. */ - script = argv[1]; + script = argv[0]; error = access(script, X_OK); if (error == 0) { - execv(script, argv + 1); + execv(script, argv); warning("can't directly exec %s: %m", script); } else if (errno != EACCES) { warning("can't access %s: %m", script); } shell = get_shell(); - execv(shell, argv); + sh_argv[0] = __DECONST(char*, shell); + sh_argv_len = 1; +#ifdef SECURE + if (strcmp(shell, _PATH_BSHELL) == 0) { + sh_argv[1] = __DECONST(char*, "-o"); + sh_argv[2] = __DECONST(char*, "verify"); + sh_argv_len = 3; + } +#endif + for (i = 0; i != SCRIPT_ARGV_SIZE; ++i) + sh_argv[i + sh_argv_len] = argv[i]; + execv(shell, sh_argv); stall("can't exec %s for %s: %m", shell, script); } @@ -1086,12 +1099,10 @@ execute_script(char *argv[]) static void replace_init(char *path) { - char *argv[3]; - char sh[] = "sh"; + char *argv[SCRIPT_ARGV_SIZE]; - argv[0] = sh; - argv[1] = path; - argv[2] = NULL; + argv[0] = path; + argv[1] = NULL; execute_script(argv); } @@ -1108,20 +1119,18 @@ run_script(const char *script) { pid_t pid, wpid; int status; - char *argv[4]; + char *argv[SCRIPT_ARGV_SIZE]; const char *shell; shell = get_shell(); if ((pid = fork()) == 0) { - char _sh[] = "sh"; - char _autoboot[] = "autoboot"; + char _autoboot[] = "autoboot"; - argv[0] = _sh; - argv[1] = __DECONST(char *, script); - argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0; - argv[3] = NULL; + argv[0] = __DECONST(char *, script); + argv[1] = runcom_mode == AUTOBOOT ? _autoboot : NULL; + argv[2] = NULL; execute_script(argv); sleep(STALL_TIMEOUT); @@ -1957,7 +1966,7 @@ runshutdown(void) int status; int shutdowntimeout; size_t len; - char *argv[4]; + char *argv[SCRIPT_ARGV_SIZE]; struct stat sb; BOOTTRACE("init(8): start rc.shutdown"); @@ -1972,16 +1981,14 @@ runshutdown(void) return 0; if ((pid = fork()) == 0) { - char _sh[] = "sh"; char _reboot[] = "reboot"; char _single[] = "single"; char _path_rundown[] = _PATH_RUNDOWN; - argv[0] = _sh; - argv[1] = _path_rundown; - argv[2] = Reboot ? _reboot : _single; - argv[3] = NULL; - + argv[0] = _path_rundown; + argv[1] = Reboot ? _reboot : _single; + argv[2] = NULL; + execute_script(argv); _exit(1); /* force single user mode */ }