From owner-svn-src-all@freebsd.org Sat Aug 4 14:52:33 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 144AC106DBE6; Sat, 4 Aug 2018 14:52:33 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BB4647ACEA; Sat, 4 Aug 2018 14:52:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9D9DF10FB6; Sat, 4 Aug 2018 14:52:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w74EqWZ4035653; Sat, 4 Aug 2018 14:52:32 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w74EqWZB035652; Sat, 4 Aug 2018 14:52:32 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201808041452.w74EqWZB035652@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sat, 4 Aug 2018 14:52:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337321 - head/sbin/init X-SVN-Group: head X-SVN-Commit-Author: trasz X-SVN-Commit-Paths: head/sbin/init X-SVN-Commit-Revision: 337321 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Aug 2018 14:52:33 -0000 Author: trasz Date: Sat Aug 4 14:52:32 2018 New Revision: 337321 URL: https://svnweb.freebsd.org/changeset/base/337321 Log: Make it possible for init to execute any executable, not just sh(1) scripts. This means one should be able to eg rewrite their /etc/rc in Python. Reviewed by: kib MFC after: 2 weeks Relnotes: yes Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D16565 Modified: head/sbin/init/init.c Modified: head/sbin/init/init.c ============================================================================== --- head/sbin/init/init.c Sat Aug 4 14:39:45 2018 (r337320) +++ head/sbin/init/init.c Sat Aug 4 14:52:32 2018 (r337321) @@ -1057,7 +1057,7 @@ static state_func_t run_script(const char *script) { pid_t pid, wpid; - int status; + int error, status; char *argv[4]; const char *shell; struct sigaction sa; @@ -1086,6 +1086,21 @@ run_script(const char *script) #ifdef LOGIN_CAP setprocresources(RESOURCE_RC); #endif + + /* + * Try to directly execute the script first. If it + * fails, try the old method of passing the script path + * to sh(1). Don't complain if it fails because of + * the missing execute bit. + */ + error = access(script, X_OK); + if (error == 0) { + execv(script, argv + 1); + warning("can't exec %s: %m", script); + } else if (errno != EACCES) { + warning("can't access %s: %m", script); + } + execv(shell, argv); stall("can't exec %s for %s: %m", shell, script); _exit(1); /* force single user mode */ @@ -1854,7 +1869,7 @@ static int runshutdown(void) { pid_t pid, wpid; - int status; + int error, status; int shutdowntimeout; size_t len; char *argv[4]; @@ -1897,6 +1912,21 @@ runshutdown(void) #ifdef LOGIN_CAP setprocresources(RESOURCE_RC); #endif + + /* + * Try to directly execute the script first. If it + * fails, try the old method of passing the script path + * to sh(1). Don't complain if it fails because of + * the missing execute bit. + */ + error = access(_path_rundown, X_OK); + if (error == 0) { + execv(_path_rundown, argv + 1); + warning("can't exec %s: %m", _path_rundown); + } else if (errno != EACCES) { + warning("can't access %s: %m", _path_rundown); + } + execv(shell, argv); warning("can't exec %s for %s: %m", shell, _PATH_RUNDOWN); _exit(1); /* force single user mode */