Subject: bin/13647: Incoherence between init(8) and /etc/rc.d/securelevel about kernel security level check.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <nomos@tiscalinet.it>
List: netbsd-bugs
Date: 08/07/2001 02:25:40
>Number: 13647
>Category: bin
>Synopsis: Incoherence between init(8) and /etc/rc.d/securelevel about kernel security level check.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Aug 07 02:22:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Francesco Cristiano
>Release: 1.5
>Organization:
>Environment:
NetBSD 1.5 NetBSD 1.5 (GENERIC) #1: Sun Nov 19 21:42:11 MET 2000 fvdl@sushi:/work/trees/netbsd-1-5/sys/arch/i386/compile/GENERIC i386
>Description:
There are some incoherencies about init(8)'s kernel security level check and
/etc/rc.d/securelevel. Briefly init(8)'s kernel security level algorithmic is:
if [ current security kernel level is set to 0]
then
set it to 0
fi
Instead /etc/rc.d/securelevel's kernel security level algorithmic is:
if [ the variable $securelevel is set to any value ]
then
set current security kernel level to this value
else
set this variable to the current security kernel level
and after execute init(8)'s kernel security level algorithmic
fi
This different way of doing could create a series of contrasts.
>How-To-Repeat:
Problem 1)
This problem consists of false and redundant messages during the boot caused by
/etc/rc.d/securelevel.
False messages)
If super-user set the variable $securelevel to 0 and after reboot the system via reboot(8), and
if kernel is a "GENERIC" kernel compiled with option INSECURE enabled (that is the
default condition for 1.5 version), /etc/rc.d/securelevel will print:
"Setting securelevel: kern.securelevel -1 -> 0"
and, before to execute getty(8), init(8) will print:
"<the date> init: Kernel security level changed from 0 to 1"
So the current kernel security level is 1 not 0, in other words the first message could be avoided, or
replaced by a message as:
"Kernel security level changed from 0 to 1"
with no init(8)'s intervention.
Redundant message)
If super-user set the variable $securelevel to 1 and after reboot the system via /etc/rc.shutdown
followed by /etc/rc, if kernel is a "GENERIC" kernel compiled with option INSECURE enabled
(that is the default condition for 1.5 version), /etc/rc.d/securelevel will print:
"Setting securelevel: kern.securelevel 1 -> 1"
so kernel security level is never modified by /etc/rc.d/securelevel but it is always the same, in other
words this message is redundant and could be avoided.,
Problem 2)
This problem consists of a different behaviour, followed by init(8) and /etc/rc.d/securelevel, about
kernel security level, when it is set to 0, with a "GENERIC" kernel compiled with option
INSECURE enabled (that is the default condition for 1.5 version).
To see this difference a double method to reboot the system is considered: via reboot(8) and
via /etc/rc.shutdown followed by /etc/rc.
Step by step is:
/etc/rc's behaviour init(8)'s behaviour
1)system starts with default installation's 1)system starts with default installation's
conditions (for a 1.5 version). conditions (for a 1.5 version).
2)root log in 2)root log in
3)set in /etc/defaults/rc.conf: 3)set in /etc/defaults/rc.conf:
securelevel="0" securelevel="0"
4)reboot the system typing: 4)reboot the system typing:
#sh /etc/rc.shutdown #reboot
followed by:
#sh /etc/rc
5)at the next start up, /etc/rc.d/securelevel will print:
"Setting securelevel: kern.securelevel -1 -> 0"
6)so the system now runs with kernel 6)before to execute getty(8), init(8) will check
security level set to 0 kernel security level and will print:
"Kernel security level changed from 0 to 1"
so the system now runs with kernel security
set to 1.
Problem 3)
There are no control about the value assigned to $securelevel. This brings two sub-problems
1 sub-problem)
Every time that $securelevel is sets to a value less than the current kernel security level, for each
kind of reboot (via reboot or also via /etc/rc.shutdown followed by /etc/rc ) and with or without
a kernel with option INSECURE enabled, there is:
option INSECURE enabled option INSECURE disabled
1)system starts with default installation's 1)system starts with default installation's
conditions (for a 1.5 version). conditions (for a 1.5 version).
2)root log in 2)root log in
3)modify kernel security level typing: 3)because kernel have been compiled with
#sysctl -w kern.securelevel=1 option insecure disabled, now the current
value of kernel security level is 1.
4)set in /etc/defaults/rc.conf: 4)set in /etc/defaults/rc.conf:
securelevel="0" securelevel="0"
5)reboot the system whether typing: 5)reboot the system whether typing:
#sh /etc/rc.shutdown #sh /etc/rc.shutdown
followed by: followed by:
#sh /etc/rc #sh /etc/rc
or typing: or typing:
#reboot #reboot
6)at the next start up, /etc/rc.d/securelevel will print:
"Setting securelevel: sysctl: sysctl() for kern.securelevel failed: operation not permitted"
I think that's better something as:
"Warning you tried to lower security kernel level please check your rc.conf file"
2 sub-problem)
In rc.conf(5) man page is written:
"If a variable that /etc/rc expects to be set is not set, or the value is not of the allowed values, a
warning will be printed"
and in init(8) man page is written:
"The kernel runs with four different levels of security" (-1, 0, 1, 2)
Step by step there is:
1)system starts with default installation's
conditions (for a 1.5 version).
2)root log in
3)set in /etc/defaults/rc.conf:
securelevel="1000"
4)reboot the system whether typing
#sh /etc/rc.shutdown
followed by:
#sh /etc/rc
or typing:
#reboot
5) at the next start up, /etc/rc.d/securelevel will print out:
"Setting securelevel: kern.securelevel -1 -> 1000"
I think that's better something as:
"Warning $securelevel is set to 1000 the system set it to 2"
>Fix:
Well, because I don't know the intentions of whom has implemented /etc/rc.d/securelevel, the
question is:
"shall /etc/rc.d/securelevel be coherence with init(8) as regards the kernel security level's check?"
If the answer is positive then, to resolve all these problems, is enough to replace
/etc/rc.d/securelevel with this new version:
#!/bin/sh
#
# $NetBSD: securelevel,v 2 2001/08/06 11:00:07 modified by Francesco Cristiano
#
# PROVIDE: securelevel
# REQUIRE: aftermountlkm ipnat mountd
. /etc/rc.subr
name="securelevel"
start_cmd="securelevel_start"
stop_cmd=":"
check_securelevel()
{
case x$securelevel in
x`sysctl -n kern.securelevel`)
#if $securelevel is equal to the current security level then make
#nothing; (for example in a reboot sec. lev. could be equal to itself).
if [ x$securelevel = x0 ]
#if super-user changes the security level to 0 using sysctl(8) and
#after reboot the system using rc.shutdown followed by rc(8).
then
echo -n "Kernel security level changed from 0 to 1: 0 -> "
sysctl -n -w kern.securelevel=1
fi
;;
x0)
#it upgrades the security level to 0 and uses the variable
#xywjk to suppress some messages (e.g. -1 -> 0 ).
xywjk=`sysctl -w kern.securelevel=0`
unset xywjk
echo -n "Kernel security level changed from 0 to 1: 0 -> "
sysctl -n -w kern.securelevel=1
;;
*)
echo -n "Setting securelevel: "
sysctl -w kern.securelevel=$securelevel
;;
esac
}
check_value()
{
if [ `sysctl -n kern.securelevel` -gt 2 -o `sysctl -n kern.securelevel` -lt -1 ]; then
#if the current sec. kernel lev. is set to an abnormal value then
#print out only a warning message
echo " "
echo "Warning current security kernel level is set to `sysctl -n kern.securelevel`"
{ [ `sysctl -n kern.securelevel` -gt 2 ] && echo "the maximum value allowed is 2"; } \
|| echo "the minimum value allowed is -1"
echo " "
elif [ $securelevel -lt -1 ]; then
ex_securelevel=$securelevel
securelevel=-1
if [ $securelevel -lt `sysctl -n kern.securelevel` ]; then
if [ `sysctl -n kern.securelevel` -eq 0 ]; then
#for example $securelevel is set to -10 curr. sec. lev.
#is set to 2 and user type "kill -15 1" when system will
#come back in multi-user mode during boot curr. sec. lev. is set to 0
securelevel=0
echo "Warning you tried to lower security kernel level to $ex_securelevel"
echo "current value is `sysctl -n kern.securelevel` please check your rc.conf file"
echo " "
check_securelevel
unset ex_securelevel
else
echo "Warning you tried to lower security kernel level to $ex_securelevel"
echo "current value is `sysctl -n kern.securelevel` please check your rc.conf file"
echo " "
unset ex_securelevel
fi
else
echo "Warning \$securelevel is set to $ex_securelevel the system set it to $securelevel"
unset ex_securelevel
check_securelevel
fi
elif [ $securelevel -gt 2 ]; then
ex_securelevel=$securelevel
securelevel=2
if [ $securelevel -lt `sysctl -n kern.securelevel` ]; then
echo "Warning you tried to lower security kernel level to $ex_securelevel"
echo "current value is `sysctl -n kern.securelevel` please check your rc.conf file"
echo " "
unset ex_securelevel
else
echo "Warning \$securelevel is set to $ex_securelevel the system set it to $securelevel"
unset ex_securelevel
check_securelevel
fi
elif [ $securelevel -lt `sysctl -n kern.securelevel` ]; then
#the only way to arrive here is setting $securelevel, in rc.conf file, to a value allowed but
#less than current sec. lev. and after reboot the system (also via rc.shutdown followed by rc(8))
echo "Warning you tried to lower security kernel level to $securelevel"
echo "current value is `sysctl -n kern.securelevel` please check your rc.conf file"
echo " "
else
check_securelevel
fi
}
securelevel_start()
{
if [ -n "$securelevel" ]; then
check_value
else
securelevel=`sysctl -n kern.securelevel`
check_value
fi
}
load_rc_config $name
run_rc_command "$1"
If /etc/rc.d/securelevel has been implemented to give more flexibility to the system, as regards the
kernel security level management, and to circumvented init(8)'s limits, for example:
"to keep security kernel level always to the same value during any kind of reboot"
then I've also implemented the code for this, which works also for reboot invoked by
reboot(8) and $securelevel set to 0, but it's more long than the source code upon.
Because I'd like to contribute to NetBSD, responsible person can contact me everyday
at every time.
>Release-Note:
>Audit-Trail:
>Unformatted: