1 /* $NetBSD: secmodel_suser.c,v 1.33 2009/12/24 19:02:07 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
31 * NetBSD superuser access restrictions.
33 * There are two main resources a request can be issued to: user-owned and
34 * system owned. For the first, traditional Unix access checks are done, as
35 * well as superuser checks. If needed, the request context is examined before
36 * a decision is made. For the latter, usually only superuser checks are done
37 * as normal users are not allowed to access system resources.
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.33 2009/12/24 19:02:07 elad Exp $");
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/kauth.h>
47 #include <sys/mutex.h>
48 #include <sys/mount.h>
49 #include <sys/socketvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/vnode.h>
53 #include <sys/module.h>
55 #include <secmodel/suser/suser.h>
57 MODULE(MODULE_CLASS_SECMODEL
, suser
, NULL
);
59 static int secmodel_suser_curtain
;
60 /* static */ int dovfsusermount
;
62 static kauth_listener_t l_generic
, l_system
, l_process
, l_network
, l_machdep
,
65 static struct sysctllog
*suser_sysctl_log
;
68 sysctl_security_suser_setup(struct sysctllog
**clog
)
70 const struct sysctlnode
*rnode
;
72 sysctl_createv(clog
, 0, NULL
, &rnode
,
74 CTLTYPE_NODE
, "security", NULL
,
76 CTL_SECURITY
, CTL_EOL
);
78 sysctl_createv(clog
, 0, &rnode
, &rnode
,
80 CTLTYPE_NODE
, "models", NULL
,
84 sysctl_createv(clog
, 0, &rnode
, &rnode
,
86 CTLTYPE_NODE
, "suser", NULL
,
90 sysctl_createv(clog
, 0, &rnode
, NULL
,
92 CTLTYPE_STRING
, "name", NULL
,
93 NULL
, 0, __UNCONST("Traditional NetBSD: Superuser"), 0,
96 sysctl_createv(clog
, 0, &rnode
, NULL
,
97 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
98 CTLTYPE_INT
, "curtain",
99 SYSCTL_DESCR("Curtain information about objects to "\
100 "users not owning them."),
101 NULL
, 0, &secmodel_suser_curtain
, 0,
102 CTL_CREATE
, CTL_EOL
);
104 sysctl_createv(clog
, 0, &rnode
, NULL
,
105 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
106 CTLTYPE_INT
, "usermount",
107 SYSCTL_DESCR("Whether unprivileged users may mount "
109 NULL
, 0, &dovfsusermount
, 0,
110 CTL_CREATE
, CTL_EOL
);
112 /* Compatibility: security.curtain */
113 sysctl_createv(clog
, 0, NULL
, &rnode
,
115 CTLTYPE_NODE
, "security", NULL
,
117 CTL_SECURITY
, CTL_EOL
);
119 sysctl_createv(clog
, 0, &rnode
, NULL
,
120 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
121 CTLTYPE_INT
, "curtain",
122 SYSCTL_DESCR("Curtain information about objects to "\
123 "users not owning them."),
124 NULL
, 0, &secmodel_suser_curtain
, 0,
125 CTL_CREATE
, CTL_EOL
);
127 /* Compatibility: vfs.generic.usermount */
128 sysctl_createv(clog
, 0, NULL
, NULL
,
130 CTLTYPE_NODE
, "vfs", NULL
,
134 sysctl_createv(clog
, 0, NULL
, NULL
,
136 CTLTYPE_NODE
, "generic",
137 SYSCTL_DESCR("Non-specific vfs related information"),
139 CTL_VFS
, VFS_GENERIC
, CTL_EOL
);
141 sysctl_createv(clog
, 0, NULL
, NULL
,
142 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
143 CTLTYPE_INT
, "usermount",
144 SYSCTL_DESCR("Whether unprivileged users may mount "
146 NULL
, 0, &dovfsusermount
, 0,
147 CTL_VFS
, VFS_GENERIC
, VFS_USERMOUNT
, CTL_EOL
);
151 secmodel_suser_init(void)
153 secmodel_suser_curtain
= 0;
157 secmodel_suser_start(void)
159 l_generic
= kauth_listen_scope(KAUTH_SCOPE_GENERIC
,
160 secmodel_suser_generic_cb
, NULL
);
161 l_system
= kauth_listen_scope(KAUTH_SCOPE_SYSTEM
,
162 secmodel_suser_system_cb
, NULL
);
163 l_process
= kauth_listen_scope(KAUTH_SCOPE_PROCESS
,
164 secmodel_suser_process_cb
, NULL
);
165 l_network
= kauth_listen_scope(KAUTH_SCOPE_NETWORK
,
166 secmodel_suser_network_cb
, NULL
);
167 l_machdep
= kauth_listen_scope(KAUTH_SCOPE_MACHDEP
,
168 secmodel_suser_machdep_cb
, NULL
);
169 l_device
= kauth_listen_scope(KAUTH_SCOPE_DEVICE
,
170 secmodel_suser_device_cb
, NULL
);
171 l_vnode
= kauth_listen_scope(KAUTH_SCOPE_VNODE
,
172 secmodel_suser_vnode_cb
, NULL
);
176 secmodel_suser_stop(void)
178 kauth_unlisten_scope(l_generic
);
179 kauth_unlisten_scope(l_system
);
180 kauth_unlisten_scope(l_process
);
181 kauth_unlisten_scope(l_network
);
182 kauth_unlisten_scope(l_machdep
);
183 kauth_unlisten_scope(l_device
);
184 kauth_unlisten_scope(l_vnode
);
188 suser_modcmd(modcmd_t cmd
, void *arg
)
193 case MODULE_CMD_INIT
:
194 secmodel_suser_init();
195 secmodel_suser_start();
196 sysctl_security_suser_setup(&suser_sysctl_log
);
199 case MODULE_CMD_FINI
:
200 sysctl_teardown(&suser_sysctl_log
);
201 secmodel_suser_stop();
204 case MODULE_CMD_AUTOUNLOAD
:
219 * Security model: Traditional NetBSD
221 * Responsibility: Superuser access
224 secmodel_suser_generic_cb(kauth_cred_t cred
, kauth_action_t action
,
225 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
230 isroot
= (kauth_cred_geteuid(cred
) == 0);
231 result
= KAUTH_RESULT_DEFER
;
234 case KAUTH_GENERIC_ISSUSER
:
236 result
= KAUTH_RESULT_ALLOW
;
247 suser_usermount_policy(kauth_cred_t cred
, enum kauth_system_req req
, void *arg1
,
254 result
= KAUTH_RESULT_DEFER
;
260 case KAUTH_REQ_SYSTEM_MOUNT_NEW
:
261 mp
= ((struct vnode
*)arg1
)->v_mount
;
264 if (usermount_common_policy(mp
, flags
) != 0)
267 result
= KAUTH_RESULT_ALLOW
;
271 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT
:
274 /* Must own the mount. */
275 if (mp
->mnt_stat
.f_owner
!= kauth_cred_geteuid(cred
))
278 result
= KAUTH_RESULT_ALLOW
;
282 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE
:
284 flags
= (u_long
)arg2
;
286 /* Must own the mount. */
287 if (mp
->mnt_stat
.f_owner
!= kauth_cred_geteuid(cred
))
290 if (usermount_common_policy(mp
, flags
) != 0)
293 result
= KAUTH_RESULT_ALLOW
;
307 * Security model: Traditional NetBSD
309 * Responsibility: Superuser access
312 secmodel_suser_system_cb(kauth_cred_t cred
, kauth_action_t action
,
313 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
317 enum kauth_system_req req
;
319 isroot
= (kauth_cred_geteuid(cred
) == 0);
320 result
= KAUTH_RESULT_DEFER
;
321 req
= (enum kauth_system_req
)arg0
;
324 case KAUTH_SYSTEM_CPU
:
326 case KAUTH_REQ_SYSTEM_CPU_SETSTATE
:
328 result
= KAUTH_RESULT_ALLOW
;
338 case KAUTH_SYSTEM_FS_QUOTA
:
340 case KAUTH_REQ_SYSTEM_FS_QUOTA_GET
:
341 case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF
:
342 case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE
:
343 case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT
:
345 result
= KAUTH_RESULT_ALLOW
;
354 case KAUTH_SYSTEM_MOUNT
:
356 case KAUTH_REQ_SYSTEM_MOUNT_GET
:
358 result
= KAUTH_RESULT_ALLOW
;
364 case KAUTH_REQ_SYSTEM_MOUNT_NEW
:
365 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT
:
366 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE
:
368 result
= KAUTH_RESULT_ALLOW
;
372 result
= suser_usermount_policy(cred
, req
, arg1
, arg2
);
382 case KAUTH_SYSTEM_PSET
:
384 case KAUTH_REQ_SYSTEM_PSET_ASSIGN
:
385 case KAUTH_REQ_SYSTEM_PSET_BIND
:
386 case KAUTH_REQ_SYSTEM_PSET_CREATE
:
387 case KAUTH_REQ_SYSTEM_PSET_DESTROY
:
389 result
= KAUTH_RESULT_ALLOW
;
399 case KAUTH_SYSTEM_TIME
:
401 case KAUTH_REQ_SYSTEM_TIME_ADJTIME
:
402 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME
:
403 case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS
:
404 case KAUTH_REQ_SYSTEM_TIME_SYSTEM
:
405 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET
:
407 result
= KAUTH_RESULT_ALLOW
;
415 case KAUTH_SYSTEM_SYSCTL
:
417 case KAUTH_REQ_SYSTEM_SYSCTL_ADD
:
418 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE
:
419 case KAUTH_REQ_SYSTEM_SYSCTL_DESC
:
420 case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY
:
421 case KAUTH_REQ_SYSTEM_SYSCTL_PRVT
:
423 result
= KAUTH_RESULT_ALLOW
;
432 case KAUTH_SYSTEM_SWAPCTL
:
433 case KAUTH_SYSTEM_ACCOUNTING
:
434 case KAUTH_SYSTEM_REBOOT
:
435 case KAUTH_SYSTEM_CHROOT
:
436 case KAUTH_SYSTEM_FILEHANDLE
:
437 case KAUTH_SYSTEM_MKNOD
:
438 case KAUTH_SYSTEM_SETIDCORE
:
439 case KAUTH_SYSTEM_MODULE
:
440 case KAUTH_SYSTEM_FS_RESERVEDSPACE
:
442 result
= KAUTH_RESULT_ALLOW
;
445 case KAUTH_SYSTEM_DEBUG
:
447 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB
:
449 result
= KAUTH_RESULT_ALLOW
;
459 case KAUTH_SYSTEM_CHSYSFLAGS
:
461 * Needs to be checked in conjunction with the immutable and
462 * append-only flags (usually). Should be handled differently.
463 * Infects ufs, ext2fs, tmpfs, and rump.
466 result
= KAUTH_RESULT_ALLOW
;
480 * Security model: Traditional NetBSD
482 * Responsibility: Superuser access
485 secmodel_suser_process_cb(kauth_cred_t cred
, kauth_action_t action
,
486 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
492 isroot
= (kauth_cred_geteuid(cred
) == 0);
493 result
= KAUTH_RESULT_DEFER
;
497 case KAUTH_PROCESS_SIGNAL
:
498 case KAUTH_PROCESS_KTRACE
:
499 case KAUTH_PROCESS_PROCFS
:
500 case KAUTH_PROCESS_PTRACE
:
501 case KAUTH_PROCESS_SCHEDULER_GETPARAM
:
502 case KAUTH_PROCESS_SCHEDULER_SETPARAM
:
503 case KAUTH_PROCESS_SCHEDULER_GETAFFINITY
:
504 case KAUTH_PROCESS_SCHEDULER_SETAFFINITY
:
505 case KAUTH_PROCESS_SETID
:
506 case KAUTH_PROCESS_KEVENT_FILTER
:
507 case KAUTH_PROCESS_NICE
:
508 case KAUTH_PROCESS_FORK
:
509 case KAUTH_PROCESS_CORENAME
:
510 case KAUTH_PROCESS_STOPFLAG
:
512 result
= KAUTH_RESULT_ALLOW
;
516 case KAUTH_PROCESS_CANSEE
: {
519 req
= (unsigned long)arg1
;
522 case KAUTH_REQ_PROCESS_CANSEE_ARGS
:
523 case KAUTH_REQ_PROCESS_CANSEE_ENTRY
:
524 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES
:
526 result
= KAUTH_RESULT_ALLOW
;
530 if (secmodel_suser_curtain
) {
531 if (!kauth_cred_uidmatch(cred
, p
->p_cred
))
532 result
= KAUTH_RESULT_DENY
;
537 case KAUTH_REQ_PROCESS_CANSEE_ENV
:
539 result
= KAUTH_RESULT_ALLOW
;
550 case KAUTH_PROCESS_RLIMIT
: {
551 enum kauth_process_req req
;
553 req
= (enum kauth_process_req
)(unsigned long)arg1
;
556 case KAUTH_REQ_PROCESS_RLIMIT_SET
:
557 case KAUTH_REQ_PROCESS_RLIMIT_GET
:
559 result
= KAUTH_RESULT_ALLOW
;
580 * Security model: Traditional NetBSD
582 * Responsibility: Superuser access
585 secmodel_suser_network_cb(kauth_cred_t cred
, kauth_action_t action
,
586 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
590 enum kauth_network_req req
;
592 isroot
= (kauth_cred_geteuid(cred
) == 0);
593 result
= KAUTH_RESULT_DEFER
;
594 req
= (enum kauth_network_req
)arg0
;
597 case KAUTH_NETWORK_ALTQ
:
599 case KAUTH_REQ_NETWORK_ALTQ_AFMAP
:
600 case KAUTH_REQ_NETWORK_ALTQ_BLUE
:
601 case KAUTH_REQ_NETWORK_ALTQ_CBQ
:
602 case KAUTH_REQ_NETWORK_ALTQ_CDNR
:
603 case KAUTH_REQ_NETWORK_ALTQ_CONF
:
604 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ
:
605 case KAUTH_REQ_NETWORK_ALTQ_HFSC
:
606 case KAUTH_REQ_NETWORK_ALTQ_JOBS
:
607 case KAUTH_REQ_NETWORK_ALTQ_PRIQ
:
608 case KAUTH_REQ_NETWORK_ALTQ_RED
:
609 case KAUTH_REQ_NETWORK_ALTQ_RIO
:
610 case KAUTH_REQ_NETWORK_ALTQ_WFQ
:
612 result
= KAUTH_RESULT_ALLOW
;
621 case KAUTH_NETWORK_BIND
:
623 case KAUTH_REQ_NETWORK_BIND_PORT
:
624 case KAUTH_REQ_NETWORK_BIND_PRIVPORT
:
626 result
= KAUTH_RESULT_ALLOW
;
634 case KAUTH_NETWORK_FIREWALL
:
636 case KAUTH_REQ_NETWORK_FIREWALL_FW
:
637 case KAUTH_REQ_NETWORK_FIREWALL_NAT
:
639 result
= KAUTH_RESULT_ALLOW
;
648 case KAUTH_NETWORK_FORWSRCRT
:
649 case KAUTH_NETWORK_ROUTE
:
651 result
= KAUTH_RESULT_ALLOW
;
655 case KAUTH_NETWORK_INTERFACE
:
657 case KAUTH_REQ_NETWORK_INTERFACE_GET
:
658 case KAUTH_REQ_NETWORK_INTERFACE_SET
:
659 case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV
:
660 case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV
:
662 result
= KAUTH_RESULT_ALLOW
;
670 case KAUTH_NETWORK_INTERFACE_PPP
:
672 case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD
:
674 result
= KAUTH_RESULT_ALLOW
;
683 case KAUTH_NETWORK_INTERFACE_SLIP
:
685 case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD
:
687 result
= KAUTH_RESULT_ALLOW
;
696 case KAUTH_NETWORK_INTERFACE_STRIP
:
698 case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD
:
700 result
= KAUTH_RESULT_ALLOW
;
709 case KAUTH_NETWORK_INTERFACE_TUN
:
711 case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD
:
713 result
= KAUTH_RESULT_ALLOW
;
722 case KAUTH_NETWORK_NFS
:
724 case KAUTH_REQ_NETWORK_NFS_EXPORT
:
725 case KAUTH_REQ_NETWORK_NFS_SVC
:
727 result
= KAUTH_RESULT_ALLOW
;
736 case KAUTH_NETWORK_SOCKET
:
738 case KAUTH_REQ_NETWORK_SOCKET_DROP
:
739 case KAUTH_REQ_NETWORK_SOCKET_OPEN
:
740 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK
:
741 case KAUTH_REQ_NETWORK_SOCKET_SETPRIV
:
743 result
= KAUTH_RESULT_ALLOW
;
746 case KAUTH_REQ_NETWORK_SOCKET_CANSEE
:
748 result
= KAUTH_RESULT_ALLOW
;
752 if (secmodel_suser_curtain
) {
755 so
= (struct socket
*)arg1
;
757 if (!proc_uidmatch(cred
, so
->so_cred
))
758 result
= KAUTH_RESULT_DENY
;
780 * Security model: Traditional NetBSD
782 * Responsibility: Superuser access
785 secmodel_suser_machdep_cb(kauth_cred_t cred
, kauth_action_t action
,
786 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
791 isroot
= (kauth_cred_geteuid(cred
) == 0);
792 result
= KAUTH_RESULT_DEFER
;
795 case KAUTH_MACHDEP_IOPERM_GET
:
796 case KAUTH_MACHDEP_LDT_GET
:
797 case KAUTH_MACHDEP_LDT_SET
:
798 case KAUTH_MACHDEP_MTRR_GET
:
799 case KAUTH_MACHDEP_CACHEFLUSH
:
800 case KAUTH_MACHDEP_IOPERM_SET
:
801 case KAUTH_MACHDEP_IOPL
:
802 case KAUTH_MACHDEP_MTRR_SET
:
803 case KAUTH_MACHDEP_NVRAM
:
804 case KAUTH_MACHDEP_UNMANAGEDMEM
:
806 result
= KAUTH_RESULT_ALLOW
;
819 * Security model: Traditional NetBSD
821 * Responsibility: Superuser access
824 secmodel_suser_device_cb(kauth_cred_t cred
, kauth_action_t action
,
825 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
830 isroot
= (kauth_cred_geteuid(cred
) == 0);
831 result
= KAUTH_RESULT_DEFER
;
834 case KAUTH_DEVICE_BLUETOOTH_SETPRIV
:
835 case KAUTH_DEVICE_BLUETOOTH_SEND
:
836 case KAUTH_DEVICE_BLUETOOTH_RECV
:
837 case KAUTH_DEVICE_TTY_OPEN
:
838 case KAUTH_DEVICE_TTY_PRIVSET
:
839 case KAUTH_DEVICE_TTY_STI
:
840 case KAUTH_DEVICE_RND_ADDDATA
:
841 case KAUTH_DEVICE_RND_GETPRIV
:
842 case KAUTH_DEVICE_RND_SETPRIV
:
844 result
= KAUTH_RESULT_ALLOW
;
847 case KAUTH_DEVICE_BLUETOOTH_BCSP
:
848 case KAUTH_DEVICE_BLUETOOTH_BTUART
: {
849 enum kauth_device_req req
;
851 req
= (enum kauth_device_req
)arg0
;
853 case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD
:
854 case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD
:
856 result
= KAUTH_RESULT_ALLOW
;
866 case KAUTH_DEVICE_GPIO_PINSET
:
868 * root can access gpio pins, secmodel_securlevel can veto
872 result
= KAUTH_RESULT_ALLOW
;
883 secmodel_suser_vnode_cb(kauth_cred_t cred
, kauth_action_t action
,
884 void *cookie
, void *arg0
, void *arg1
, void *arg2
, void *arg3
)
889 isroot
= (kauth_cred_geteuid(cred
) == 0);
890 result
= KAUTH_RESULT_DEFER
;
893 result
= KAUTH_RESULT_ALLOW
;