1 /* $NetBSD: secmodel_securelevel.c,v 1.19 2009/10/06 05:03:58 elad Exp $ */
3 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * This file contains kauth(9) listeners needed to implement the traditional
33 * The securelevel is a system-global indication on what operations are
34 * allowed or not. It affects all users, including root.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.19 2009/10/06 05:03:58 elad Exp $");
41 #include "opt_insecure.h"
42 #endif /* _KERNEL_OPT */
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/kauth.h>
49 #include <sys/mount.h>
50 #include <sys/sysctl.h>
51 #include <sys/vnode.h>
52 #include <sys/module.h>
53 #include <sys/timevar.h>
55 #include <miscfs/specfs/specdev.h>
57 #include <secmodel/securelevel/securelevel.h>
59 MODULE(MODULE_CLASS_SECMODEL
, securelevel
, NULL
);
61 static int securelevel
;
63 static kauth_listener_t l_system
, l_process
, l_network
, l_machdep
, l_device
,
66 static struct sysctllog
*securelevel_sysctl_log
;
69 * Sysctl helper routine for securelevel. Ensures that the value only rises
70 * unless the caller is init.
73 secmodel_securelevel_sysctl(SYSCTLFN_ARGS
)
75 int newsecurelevel
, error
;
76 struct sysctlnode node
;
78 newsecurelevel
= securelevel
;
80 node
.sysctl_data
= &newsecurelevel
;
81 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
82 if (error
|| newp
== NULL
)
85 if ((newsecurelevel
< securelevel
) && (l
->l_proc
!= initproc
))
88 securelevel
= newsecurelevel
;
94 sysctl_security_securelevel_setup(struct sysctllog
**clog
)
96 const struct sysctlnode
*rnode
;
98 sysctl_createv(clog
, 0, NULL
, &rnode
,
100 CTLTYPE_NODE
, "security", NULL
,
102 CTL_SECURITY
, CTL_EOL
);
104 sysctl_createv(clog
, 0, &rnode
, &rnode
,
106 CTLTYPE_NODE
, "models", NULL
,
108 CTL_CREATE
, CTL_EOL
);
110 sysctl_createv(clog
, 0, &rnode
, &rnode
,
112 CTLTYPE_NODE
, "securelevel", NULL
,
114 CTL_CREATE
, CTL_EOL
);
116 sysctl_createv(clog
, 0, &rnode
, NULL
,
118 CTLTYPE_STRING
, "name", NULL
,
119 NULL
, 0, __UNCONST("Traditional NetBSD: Securelevel"), 0,
120 CTL_CREATE
, CTL_EOL
);
122 sysctl_createv(clog
, 0, &rnode
, NULL
,
123 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
124 CTLTYPE_INT
, "securelevel",
125 SYSCTL_DESCR("System security level"),
126 secmodel_securelevel_sysctl
, 0, NULL
, 0,
127 CTL_CREATE
, CTL_EOL
);
129 /* Compatibility: kern.securelevel */
130 sysctl_createv(clog
, 0, NULL
, NULL
,
132 CTLTYPE_NODE
, "kern", NULL
,
136 sysctl_createv(clog
, 0, NULL
, NULL
,
137 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
138 CTLTYPE_INT
, "securelevel",
139 SYSCTL_DESCR("System security level"),
140 secmodel_securelevel_sysctl
, 0, NULL
, 0,
141 CTL_KERN
, KERN_SECURELVL
, CTL_EOL
);
145 secmodel_securelevel_init(void)
151 #endif /* INSECURE */
155 secmodel_securelevel_start(void)
157 l_system
= kauth_listen_scope(KAUTH_SCOPE_SYSTEM
,
158 secmodel_securelevel_system_cb
, NULL
);
159 l_process
= kauth_listen_scope(KAUTH_SCOPE_PROCESS
,
160 secmodel_securelevel_process_cb
, NULL
);
161 l_network
= kauth_listen_scope(KAUTH_SCOPE_NETWORK
,
162 secmodel_securelevel_network_cb
, NULL
);
163 l_machdep
= kauth_listen_scope(KAUTH_SCOPE_MACHDEP
,
164 secmodel_securelevel_machdep_cb
, NULL
);
165 l_device
= kauth_listen_scope(KAUTH_SCOPE_DEVICE
,
166 secmodel_securelevel_device_cb
, NULL
);
167 l_vnode
= kauth_listen_scope(KAUTH_SCOPE_VNODE
,
168 secmodel_securelevel_vnode_cb
, NULL
);
172 secmodel_securelevel_stop(void)
174 kauth_unlisten_scope(l_system
);
175 kauth_unlisten_scope(l_process
);
176 kauth_unlisten_scope(l_network
);
177 kauth_unlisten_scope(l_machdep
);
178 kauth_unlisten_scope(l_device
);
179 kauth_unlisten_scope(l_vnode
);
183 securelevel_modcmd(modcmd_t cmd
, void *arg
)
188 case MODULE_CMD_INIT
:
189 secmodel_securelevel_init();
190 secmodel_securelevel_start();
191 sysctl_security_securelevel_setup(&securelevel_sysctl_log
);
194 case MODULE_CMD_FINI
:
195 sysctl_teardown(&securelevel_sysctl_log
);
196 secmodel_securelevel_stop();
199 case MODULE_CMD_AUTOUNLOAD
:
214 * Security model: Traditional NetBSD
216 * Responsibility: Securelevel
219 secmodel_securelevel_system_cb(kauth_cred_t cred
, kauth_action_t action
,
220 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
223 enum kauth_system_req req
;
225 result
= KAUTH_RESULT_DEFER
;
226 req
= (enum kauth_system_req
)arg0
;
229 case KAUTH_SYSTEM_CHSYSFLAGS
:
231 result
= KAUTH_RESULT_DENY
;
234 case KAUTH_SYSTEM_TIME
:
236 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET
:
238 result
= KAUTH_RESULT_DENY
;
241 case KAUTH_REQ_SYSTEM_TIME_SYSTEM
: {
242 struct timespec
*ts
= arg1
;
243 struct timespec
*delta
= arg2
;
245 if (securelevel
> 1 && time_wraps(ts
, delta
))
246 result
= KAUTH_RESULT_DENY
;
256 case KAUTH_SYSTEM_MODULE
:
258 result
= KAUTH_RESULT_DENY
;
261 case KAUTH_SYSTEM_MOUNT
:
263 case KAUTH_REQ_SYSTEM_MOUNT_NEW
:
265 result
= KAUTH_RESULT_DENY
;
269 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE
:
270 if (securelevel
> 1) {
271 struct mount
*mp
= arg1
;
272 u_long flags
= (u_long
)arg2
;
274 /* Can only degrade from read/write to read-only. */
275 if (flags
!= (mp
->mnt_flag
| MNT_RDONLY
| MNT_RELOAD
|
276 MNT_FORCE
| MNT_UPDATE
))
277 result
= KAUTH_RESULT_DENY
;
288 case KAUTH_SYSTEM_SYSCTL
:
290 case KAUTH_REQ_SYSTEM_SYSCTL_ADD
:
291 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE
:
292 case KAUTH_REQ_SYSTEM_SYSCTL_DESC
:
294 result
= KAUTH_RESULT_DENY
;
302 case KAUTH_SYSTEM_SETIDCORE
:
304 result
= KAUTH_RESULT_DENY
;
307 case KAUTH_SYSTEM_DEBUG
:
309 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB
:
311 result
= KAUTH_RESULT_DENY
;
329 * Security model: Traditional NetBSD
331 * Responsibility: Securelevel
334 secmodel_securelevel_process_cb(kauth_cred_t cred
, kauth_action_t action
,
335 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
340 result
= KAUTH_RESULT_DEFER
;
344 case KAUTH_PROCESS_PROCFS
: {
345 enum kauth_process_req req
;
347 req
= (enum kauth_process_req
)arg2
;
349 case KAUTH_REQ_PROCESS_PROCFS_READ
:
352 case KAUTH_REQ_PROCESS_PROCFS_RW
:
353 case KAUTH_REQ_PROCESS_PROCFS_WRITE
:
354 if ((p
== initproc
) && (securelevel
> -1))
355 result
= KAUTH_RESULT_DENY
;
366 case KAUTH_PROCESS_PTRACE
:
367 if ((p
== initproc
) && (securelevel
> -1))
368 result
= KAUTH_RESULT_DENY
;
372 case KAUTH_PROCESS_CORENAME
:
374 result
= KAUTH_RESULT_DENY
;
387 * Security model: Traditional NetBSD
389 * Responsibility: Securelevel
392 secmodel_securelevel_network_cb(kauth_cred_t cred
, kauth_action_t action
,
393 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
396 enum kauth_network_req req
;
398 result
= KAUTH_RESULT_DEFER
;
399 req
= (enum kauth_network_req
)arg0
;
402 case KAUTH_NETWORK_FIREWALL
:
404 case KAUTH_REQ_NETWORK_FIREWALL_FW
:
405 case KAUTH_REQ_NETWORK_FIREWALL_NAT
:
407 result
= KAUTH_RESULT_DENY
;
415 case KAUTH_NETWORK_FORWSRCRT
:
417 result
= KAUTH_RESULT_DENY
;
430 * Security model: Traditional NetBSD
432 * Responsibility: Securelevel
435 secmodel_securelevel_machdep_cb(kauth_cred_t cred
, kauth_action_t action
,
436 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
440 result
= KAUTH_RESULT_DEFER
;
443 case KAUTH_MACHDEP_IOPERM_SET
:
444 case KAUTH_MACHDEP_IOPL
:
446 result
= KAUTH_RESULT_DENY
;
449 case KAUTH_MACHDEP_UNMANAGEDMEM
:
451 result
= KAUTH_RESULT_DENY
;
464 * Security model: Traditional NetBSD
466 * Responsibility: Securelevel
469 secmodel_securelevel_device_cb(kauth_cred_t cred
, kauth_action_t action
,
470 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
474 result
= KAUTH_RESULT_DEFER
;
477 case KAUTH_DEVICE_RAWIO_SPEC
: {
479 enum kauth_device_req req
;
481 req
= (enum kauth_device_req
)arg0
;
486 /* Handle /dev/mem and /dev/kmem. */
489 case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ
:
492 case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE
:
493 case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW
:
495 result
= KAUTH_RESULT_DENY
;
507 case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ
:
510 case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE
:
511 case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW
: {
514 error
= rawdev_mounted(vp
, NULL
);
520 if (error
&& securelevel
> 0)
521 result
= KAUTH_RESULT_DENY
;
524 result
= KAUTH_RESULT_DENY
;
536 case KAUTH_DEVICE_RAWIO_PASSTHRU
:
537 if (securelevel
> 0) {
543 KASSERT((bits
& ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL
) == 0);
545 if (bits
& ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF
)
546 result
= KAUTH_RESULT_DENY
;
551 case KAUTH_DEVICE_GPIO_PINSET
:
553 result
= KAUTH_RESULT_DENY
;
564 secmodel_securelevel_vnode_cb(kauth_cred_t cred
, kauth_action_t action
,
565 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
569 result
= KAUTH_RESULT_DEFER
;
571 if ((action
& KAUTH_VNODE_WRITE_SYSFLAGS
) &&
572 (action
& KAUTH_VNODE_HAS_SYSFLAGS
)) {
574 result
= KAUTH_RESULT_DENY
;