tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Securelevel stuff



Hi,

My development "machine" runs without securelevel loaded and so every
boot I get messages about it. The attached diff does the following:

1. Adjusts /etc/rc.d/securelevel to recognize a possibility of
   securelevel not being present. If it's not present, the script
   will error out, but with a proper message as opposed to a sysctl(8)
   error.

2. Teaches /sbin/init to first query if kern.securelevel exists, and
   only if it does actually do something for {get,set}securitylevel().

Please let me know if this is okay to commit...

Thanks,

-e.
Index: etc/rc.d/securelevel
===================================================================
RCS file: /cvsroot/src/etc/rc.d/securelevel,v
retrieving revision 1.7
diff -u -p -r1.7 securelevel
--- etc/rc.d/securelevel        12 Nov 2008 12:35:52 -0000      1.7
+++ etc/rc.d/securelevel        29 Dec 2009 05:18:38 -0000
@@ -19,7 +19,12 @@ securelevel_start()
        #       it is 0, change it to 1 here, before we start daemons
        #       or login services.
        #
-       osecurelevel=$(sysctl -n kern.securelevel)
+       osecurelevel=$(sysctl -n kern.securelevel 2>&-)
+       if [ $? != 0 ]; then
+               echo "Can't set securelevel. (Knob not present.)"
+               exit 1
+       fi
+
        if [ -n "$securelevel" -a "$securelevel" != "$osecurelevel" ]; then
                if [ "$securelevel" -lt "$osecurelevel" ]; then
                        echo "Can't lower securelevel."
@@ -31,6 +36,7 @@ securelevel_start()
        else
                if [ "$osecurelevel" = 0 ]; then
                        echo -n "Setting securelevel: "
+       
                        sysctl -w kern.securelevel=1
                fi
        fi
Index: sbin/init/init.c
===================================================================
RCS file: /cvsroot/src/sbin/init/init.c,v
retrieving revision 1.99
diff -u -p -r1.99 init.c
--- sbin/init/init.c    22 Nov 2009 18:40:26 -0000      1.99
+++ sbin/init/init.c    29 Dec 2009 05:18:39 -0000
@@ -170,8 +170,10 @@ void collect_child(pid_t, int);
 pid_t start_getty(session_t *);
 void transition_handler(int);
 void alrm_handler(int);
+int has_securelevel(void);
 void setsecuritylevel(int);
 int getsecuritylevel(void);
+int securelevel_present;
 int setupargv(session_t *, struct ttyent *);
 int clang;
 
@@ -325,6 +327,13 @@ main(int argc, char **argv)
 #endif /* !LETS_GET_SMALL && CHROOT*/
 
        /*
+        * Securelevel might not be supported by the kernel. Query for it, and
+        * set a variable indicating whether we should attempt anything with it
+        * or not.
+        */
+       securelevel_present = has_securelevel();
+
+       /*
         * Start the state machine.
         */
        transition(requested_transition);
@@ -481,6 +490,30 @@ disaster(int sig)
 }
 
 /*
+ * Check if securelevel is present.
+ */
+int
+has_securelevel(void)
+{
+#ifdef KERN_SECURELVL
+       int name[2], curlevel;
+       size_t len;
+
+       name[0] = CTL_KERN;
+       name[1] = KERN_SECURELVL;
+       len = sizeof curlevel;
+       if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
+               /* If it doesn't exist, it's okay. */
+               if (errno == ENOENT) 
+                       return 0;
+       }
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+/*
  * Get the security level of the kernel.
  */
 int
@@ -490,6 +523,9 @@ getsecuritylevel(void)
        int name[2], curlevel;
        size_t len;
 
+       if (!securelevel_present)
+               return -1;
+
        name[0] = CTL_KERN;
        name[1] = KERN_SECURELVL;
        len = sizeof curlevel;
@@ -512,6 +548,9 @@ setsecuritylevel(int newlevel)
 #ifdef KERN_SECURELVL
        int name[2], curlevel;
 
+       if (!securelevel_present)
+               return;
+
        curlevel = getsecuritylevel();
        if (newlevel == curlevel)
                return;


Home | Main Index | Thread Index | Old Index