Date: 20 May 2003 02:16:37 -0000 From: Joshua Oreman <oremanj@adsl-64-161-78-226.dsl.lsan03.pacbell.net> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/52454: [PATCH] let init change securelevel to -1 for single-user mode Message-ID: <20030520021637.65682.qmail@adsl-64-161-78-226.dsl.lsan03.pacbell.net> Resent-Message-ID: <200305200220.h4K2KAZQ016745@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 52454
>Category: kern
>Synopsis: [PATCH] let init change securelevel to -1 for single-user mode
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Mon May 19 19:20:09 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator: Joshua Oreman
>Release: FreeBSD 5.0-CURRENT i386
>Organization:
home
>Environment:
System: FreeBSD webserver.get-linux.org 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Wed May 7 17:32:53 PDT 2003 root@webserver.get-linux.org:/usr/obj/usr/src/sys/GENERIC i386
>Description:
Under OpenBSD, when `init' goes to single-user mode, it, and it alone,
can change the securelevel back down to -1. To see why this would be
useful, consider a firewall. It might normally run at securelevel 3
to prevent tampering with firewall rules. However, suppose a rule
change was needed. Without this functionality, the firewall would
have to restart, disrupting service. With it, the firewall could
simply drop to single-user, keeping connections, and change
the rule. The patch adds that functionality to FreeBSD.
>How-To-Repeat:
[not applicable]
>Fix:
Apply this patch to src/sys/kern/kern_mib.c:
--[snip]--
--- kern_mib.c.orig Mon May 19 18:47:47 2003
+++ kern_mib.c Mon May 19 18:54:36 2003
@@ -273,7 +273,8 @@
} else {
mtx_lock(&securelevel_mtx);
if (!regression_securelevel_nonmonotonic &&
- (level < securelevel)) {
+ (level < securelevel) &&
+ (req->td->td_proc->p_pid != 1)) {
mtx_unlock(&securelevel_mtx);
return (EPERM);
}
--[snip]--
and apply this patch to src/sbin/init/init.c:
--[snip]--
--- init.c.orig Mon May 19 18:54:56 2003
+++ init.c Mon May 19 19:09:38 2003
@@ -619,6 +619,25 @@
endpwent();
#endif /* SECURE */
+ if (getsecuritylevel() > 0) {
+ /*
+ * It's safe to set newsecuritylevel to -1 here because,
+ * even if securelevel was not originally -1, it will
+ * be reset on return to multi-user.
+ */
+ int mib[2], newsecuritylevel = -1;
+ syslog (LOG_INFO, "changing security level from %i to %i "
+ "for single-user mode", getsecuritylevel(), -1);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_SECURELVL;
+ if (sysctl (mib, 2, NULL, NULL, &newsecuritylevel,
+ sizeof newsecuritylevel) == -1) {
+ warning ("unable to set securelevel; operations "
+ "will continue at level %i", getsecuritylevel());
+ }
+ }
+
#ifdef DEBUGSHELL
{
char *cp = altshell;
--[snip]--
Recompile init and the kernel, reboot, and the securelevel
will go down for single-user mode. This is not a security
hole because only `init' (pid 1) has the authority to do
this.
>Release-Note:
>Audit-Trail:
>Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030520021637.65682.qmail>
