Home | History | Annotate | Line # | Download | only in overlay
secmodel_overlay.c revision 1.10.12.2
      1  1.10.12.2  yamt /* $NetBSD: secmodel_overlay.c,v 1.10.12.2 2014/05/22 11:41:17 yamt Exp $ */
      2        1.1  elad /*-
      3        1.1  elad  * Copyright (c) 2006 Elad Efrat <elad (at) NetBSD.org>
      4        1.1  elad  * All rights reserved.
      5        1.1  elad  *
      6        1.1  elad  * Redistribution and use in source and binary forms, with or without
      7        1.1  elad  * modification, are permitted provided that the following conditions
      8        1.1  elad  * are met:
      9        1.1  elad  * 1. Redistributions of source code must retain the above copyright
     10        1.1  elad  *    notice, this list of conditions and the following disclaimer.
     11        1.1  elad  * 2. Redistributions in binary form must reproduce the above copyright
     12        1.1  elad  *    notice, this list of conditions and the following disclaimer in the
     13        1.1  elad  *    documentation and/or other materials provided with the distribution.
     14        1.5  elad  * 3. The name of the author may not be used to endorse or promote products
     15        1.1  elad  *    derived from this software without specific prior written permission.
     16        1.1  elad  *
     17        1.1  elad  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18        1.1  elad  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19        1.1  elad  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20        1.1  elad  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21        1.1  elad  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22        1.1  elad  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23        1.1  elad  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24        1.1  elad  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25        1.1  elad  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26        1.1  elad  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27        1.1  elad  */
     28        1.1  elad 
     29        1.2  elad #include <sys/cdefs.h>
     30  1.10.12.2  yamt __KERNEL_RCSID(0, "$NetBSD: secmodel_overlay.c,v 1.10.12.2 2014/05/22 11:41:17 yamt Exp $");
     31        1.2  elad 
     32        1.1  elad #include <sys/types.h>
     33        1.1  elad #include <sys/param.h>
     34        1.1  elad #include <sys/kauth.h>
     35       1.10  elad #include <sys/module.h>
     36        1.1  elad 
     37        1.1  elad #include <sys/sysctl.h>
     38        1.1  elad 
     39  1.10.12.1  yamt #include <secmodel/secmodel.h>
     40        1.1  elad 
     41  1.10.12.1  yamt #include <secmodel/overlay/overlay.h>
     42        1.1  elad #include <secmodel/bsd44/bsd44.h>
     43       1.10  elad #include <secmodel/suser/suser.h>
     44       1.10  elad #include <secmodel/securelevel/securelevel.h>
     45        1.9  elad 
     46       1.10  elad MODULE(MODULE_CLASS_SECMODEL, secmodel_overlay, "secmodel_bsd44");
     47        1.1  elad 
     48        1.1  elad /*
     49        1.1  elad  * Fall-back settings.
     50        1.1  elad  */
     51        1.1  elad #define	OVERLAY_ISCOPE_GENERIC	"org.netbsd.kauth.overlay.generic"
     52        1.1  elad #define	OVERLAY_ISCOPE_SYSTEM	"org.netbsd.kauth.overlay.system"
     53        1.1  elad #define	OVERLAY_ISCOPE_PROCESS	"org.netbsd.kauth.overlay.process"
     54        1.1  elad #define	OVERLAY_ISCOPE_NETWORK	"org.netbsd.kauth.overlay.network"
     55        1.1  elad #define	OVERLAY_ISCOPE_MACHDEP	"org.netbsd.kauth.overlay.machdep"
     56        1.4  elad #define	OVERLAY_ISCOPE_DEVICE	"org.netbsd.kauth.overlay.device"
     57       1.10  elad #define	OVERLAY_ISCOPE_VNODE	"org.netbsd.kauth.overlay.vnode"
     58        1.1  elad 
     59        1.1  elad static kauth_scope_t secmodel_overlay_iscope_generic;
     60        1.1  elad static kauth_scope_t secmodel_overlay_iscope_system;
     61        1.1  elad static kauth_scope_t secmodel_overlay_iscope_process;
     62        1.1  elad static kauth_scope_t secmodel_overlay_iscope_network;
     63        1.1  elad static kauth_scope_t secmodel_overlay_iscope_machdep;
     64        1.4  elad static kauth_scope_t secmodel_overlay_iscope_device;
     65       1.10  elad static kauth_scope_t secmodel_overlay_iscope_vnode;
     66        1.1  elad 
     67       1.10  elad static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
     68       1.10  elad     l_device, l_vnode;
     69       1.10  elad 
     70  1.10.12.1  yamt static secmodel_t overlay_sm;
     71       1.10  elad static struct sysctllog *sysctl_overlay_log;
     72        1.1  elad 
     73        1.1  elad /*
     74        1.1  elad  * Initialize the overlay security model.
     75        1.1  elad  */
     76        1.1  elad void
     77        1.1  elad secmodel_overlay_init(void)
     78        1.1  elad {
     79        1.1  elad 	/*
     80        1.1  elad 	 * Register internal fall-back scopes.
     81        1.1  elad 	 */
     82        1.1  elad 	secmodel_overlay_iscope_generic = kauth_register_scope(
     83        1.1  elad 	    OVERLAY_ISCOPE_GENERIC, NULL, NULL);
     84        1.1  elad 	secmodel_overlay_iscope_system = kauth_register_scope(
     85        1.1  elad 	    OVERLAY_ISCOPE_SYSTEM, NULL, NULL);
     86        1.1  elad 	secmodel_overlay_iscope_process = kauth_register_scope(
     87        1.1  elad 	    OVERLAY_ISCOPE_PROCESS, NULL, NULL);
     88        1.1  elad 	secmodel_overlay_iscope_network = kauth_register_scope(
     89        1.1  elad 	    OVERLAY_ISCOPE_NETWORK, NULL, NULL);
     90        1.1  elad 	secmodel_overlay_iscope_machdep = kauth_register_scope(
     91        1.1  elad 	    OVERLAY_ISCOPE_MACHDEP, NULL, NULL);
     92        1.4  elad 	secmodel_overlay_iscope_device = kauth_register_scope(
     93        1.4  elad 	    OVERLAY_ISCOPE_DEVICE, NULL, NULL);
     94       1.10  elad 	secmodel_overlay_iscope_vnode = kauth_register_scope(
     95       1.10  elad 	    OVERLAY_ISCOPE_VNODE, NULL, NULL);
     96        1.1  elad 
     97        1.1  elad 	/*
     98       1.10  elad 	 * Register fall-back listeners, from suser and securelevel, to each
     99       1.10  elad 	 * internal scope.
    100        1.1  elad 	 */
    101        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_GENERIC,
    102       1.10  elad 	    secmodel_suser_generic_cb, NULL);
    103        1.1  elad 
    104        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_SYSTEM,
    105       1.10  elad 	    secmodel_suser_system_cb, NULL);
    106        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_SYSTEM,
    107        1.9  elad 	    secmodel_securelevel_system_cb, NULL);
    108        1.1  elad 
    109        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_PROCESS,
    110       1.10  elad 	    secmodel_suser_process_cb, NULL);
    111        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_PROCESS,
    112        1.9  elad 	    secmodel_securelevel_process_cb, NULL);
    113        1.1  elad 
    114        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_NETWORK,
    115       1.10  elad 	    secmodel_suser_network_cb, NULL);
    116        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_NETWORK,
    117        1.9  elad 	    secmodel_securelevel_network_cb, NULL);
    118        1.1  elad 
    119        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_MACHDEP,
    120       1.10  elad 	    secmodel_suser_machdep_cb, NULL);
    121        1.1  elad 	kauth_listen_scope(OVERLAY_ISCOPE_MACHDEP,
    122        1.9  elad 	    secmodel_securelevel_machdep_cb, NULL);
    123        1.1  elad 
    124        1.4  elad 	kauth_listen_scope(OVERLAY_ISCOPE_DEVICE,
    125       1.10  elad 	    secmodel_suser_device_cb, NULL);
    126        1.4  elad 	kauth_listen_scope(OVERLAY_ISCOPE_DEVICE,
    127        1.9  elad 	    secmodel_securelevel_device_cb, NULL);
    128        1.1  elad }
    129        1.1  elad 
    130       1.10  elad void
    131       1.10  elad sysctl_security_overlay_setup(struct sysctllog **clog)
    132        1.1  elad {
    133        1.1  elad 	const struct sysctlnode *rnode;
    134        1.1  elad 
    135        1.1  elad 	sysctl_createv(clog, 0, NULL, &rnode,
    136        1.1  elad 		       CTLFLAG_PERMANENT,
    137        1.1  elad 		       CTLTYPE_NODE, "models", NULL,
    138        1.1  elad 		       NULL, 0, NULL, 0,
    139  1.10.12.2  yamt 		       CTL_SECURITY, CTL_CREATE, CTL_EOL);
    140        1.1  elad 
    141        1.1  elad 	sysctl_createv(clog, 0, &rnode, &rnode,
    142        1.1  elad 		       CTLFLAG_PERMANENT,
    143        1.1  elad 		       CTLTYPE_NODE, "overlay",
    144  1.10.12.1  yamt 		       SYSCTL_DESCR("Overlay security model on-top of bsd44"),
    145        1.1  elad 		       NULL, 0, NULL, 0,
    146        1.1  elad 		       CTL_CREATE, CTL_EOL);
    147        1.1  elad 
    148        1.1  elad 	sysctl_createv(clog, 0, &rnode, NULL,
    149        1.1  elad 		       CTLFLAG_PERMANENT,
    150        1.1  elad 		       CTLTYPE_STRING, "name", NULL,
    151  1.10.12.1  yamt 		       NULL, 0, __UNCONST(SECMODEL_OVERLAY_NAME), 0,
    152        1.1  elad 		       CTL_CREATE, CTL_EOL);
    153        1.1  elad }
    154        1.1  elad 
    155        1.1  elad /*
    156        1.1  elad  * Start the overlay security model.
    157        1.1  elad  */
    158        1.1  elad void
    159        1.7  elad secmodel_overlay_start(void)
    160        1.1  elad {
    161       1.10  elad 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
    162        1.1  elad 	    secmodel_overlay_generic_cb, NULL);
    163       1.10  elad 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
    164        1.1  elad 	    secmodel_overlay_system_cb, NULL);
    165       1.10  elad 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
    166        1.1  elad 	    secmodel_overlay_process_cb, NULL);
    167       1.10  elad 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
    168        1.1  elad 	    secmodel_overlay_network_cb, NULL);
    169       1.10  elad 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
    170        1.1  elad 	    secmodel_overlay_machdep_cb, NULL);
    171       1.10  elad 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
    172        1.4  elad 	    secmodel_overlay_device_cb, NULL);
    173       1.10  elad 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
    174       1.10  elad 	    secmodel_overlay_vnode_cb, NULL);
    175        1.1  elad }
    176        1.1  elad 
    177       1.10  elad /*
    178       1.10  elad  * Stop the overlay security model.
    179       1.10  elad  */
    180        1.7  elad void
    181       1.10  elad secmodel_overlay_stop(void)
    182        1.7  elad {
    183       1.10  elad 	kauth_unlisten_scope(l_generic);
    184       1.10  elad 	kauth_unlisten_scope(l_system);
    185       1.10  elad 	kauth_unlisten_scope(l_process);
    186       1.10  elad 	kauth_unlisten_scope(l_network);
    187       1.10  elad 	kauth_unlisten_scope(l_machdep);
    188       1.10  elad 	kauth_unlisten_scope(l_device);
    189       1.10  elad 	kauth_unlisten_scope(l_vnode);
    190       1.10  elad }
    191       1.10  elad 
    192       1.10  elad static int
    193       1.10  elad secmodel_overlay_modcmd(modcmd_t cmd, void *arg)
    194       1.10  elad {
    195       1.10  elad 	int error = 0;
    196       1.10  elad 
    197       1.10  elad 	switch (cmd) {
    198       1.10  elad 	case MODULE_CMD_INIT:
    199  1.10.12.1  yamt 		error = secmodel_register(&overlay_sm,
    200  1.10.12.1  yamt 		    SECMODEL_OVERLAY_ID, SECMODEL_OVERLAY_NAME,
    201  1.10.12.1  yamt 		    NULL, NULL, NULL);
    202  1.10.12.1  yamt 		if (error != 0)
    203  1.10.12.1  yamt 			printf("secmodel_overlay_modcmd::init: "
    204  1.10.12.1  yamt 			    "secmodel_register returned %d\n", error);
    205  1.10.12.1  yamt 
    206       1.10  elad 		secmodel_overlay_init();
    207  1.10.12.1  yamt 		secmodel_suser_stop();
    208  1.10.12.1  yamt 		secmodel_securelevel_stop();
    209       1.10  elad 		secmodel_overlay_start();
    210       1.10  elad 		sysctl_security_overlay_setup(&sysctl_overlay_log);
    211       1.10  elad 		break;
    212       1.10  elad 
    213       1.10  elad 	case MODULE_CMD_FINI:
    214       1.10  elad 		sysctl_teardown(&sysctl_overlay_log);
    215       1.10  elad 		secmodel_overlay_stop();
    216  1.10.12.1  yamt 
    217  1.10.12.1  yamt 		error = secmodel_deregister(overlay_sm);
    218  1.10.12.1  yamt 		if (error != 0)
    219  1.10.12.1  yamt 			printf("secmodel_overlay_modcmd::fini: "
    220  1.10.12.1  yamt 			    "secmodel_deregister returned %d\n", error);
    221       1.10  elad 		break;
    222       1.10  elad 
    223       1.10  elad 	case MODULE_CMD_AUTOUNLOAD:
    224       1.10  elad 		error = EPERM;
    225       1.10  elad 		break;
    226       1.10  elad 
    227       1.10  elad 	default:
    228       1.10  elad 		error = ENOTTY;
    229       1.10  elad 		break;
    230       1.10  elad 	}
    231       1.10  elad 
    232       1.10  elad 	return error;
    233        1.7  elad }
    234        1.7  elad 
    235        1.1  elad /*
    236        1.1  elad  * Overlay listener for the generic scope.
    237        1.1  elad  */
    238        1.1  elad int
    239        1.1  elad secmodel_overlay_generic_cb(kauth_cred_t cred, kauth_action_t action,
    240        1.1  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    241        1.1  elad {
    242        1.1  elad 	int result;
    243        1.1  elad 
    244        1.1  elad 	result = KAUTH_RESULT_DEFER;
    245        1.1  elad 
    246        1.1  elad 	switch (action) {
    247        1.1  elad 	default:
    248        1.1  elad 		result = KAUTH_RESULT_DEFER;
    249        1.1  elad 		break;
    250        1.1  elad 	}
    251        1.1  elad 
    252        1.1  elad 	if (result == KAUTH_RESULT_DEFER) {
    253        1.1  elad 		result = kauth_authorize_action(
    254        1.1  elad 		    secmodel_overlay_iscope_generic, cred, action,
    255        1.1  elad 		    arg0, arg1, arg2, arg3);
    256        1.1  elad 	}
    257        1.1  elad 
    258        1.1  elad 	return (result);
    259        1.1  elad }
    260        1.1  elad 
    261        1.1  elad /*
    262        1.1  elad  * Overlay listener for the system scope.
    263        1.1  elad  */
    264        1.1  elad int
    265        1.1  elad secmodel_overlay_system_cb(kauth_cred_t cred, kauth_action_t action,
    266        1.1  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    267        1.1  elad {
    268        1.1  elad 	int result;
    269        1.1  elad 
    270        1.1  elad 	result = KAUTH_RESULT_DEFER;
    271        1.1  elad 
    272        1.1  elad 	switch (action) {
    273        1.1  elad 	default:
    274        1.1  elad 		result = KAUTH_RESULT_DEFER;
    275        1.1  elad 		break;
    276        1.1  elad 	}
    277        1.1  elad 
    278        1.1  elad 	if (result == KAUTH_RESULT_DEFER) {
    279        1.1  elad 		result = kauth_authorize_action(
    280        1.1  elad 		    secmodel_overlay_iscope_system, cred, action,
    281        1.1  elad 		    arg0, arg1, arg2, arg3);
    282        1.1  elad 	}
    283        1.1  elad 
    284        1.1  elad 	return (result);
    285        1.1  elad }
    286        1.1  elad 
    287        1.1  elad /*
    288        1.1  elad  * Overlay listener for the process scope.
    289        1.1  elad  */
    290        1.1  elad int
    291        1.1  elad secmodel_overlay_process_cb(kauth_cred_t cred, kauth_action_t action,
    292        1.1  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    293        1.1  elad {
    294        1.1  elad 	int result;
    295        1.1  elad 
    296        1.1  elad 	result = KAUTH_RESULT_DEFER;
    297        1.1  elad 
    298        1.1  elad 	switch (action) {
    299        1.1  elad 	default:
    300        1.1  elad 		result = KAUTH_RESULT_DEFER;
    301        1.1  elad 		break;
    302        1.1  elad 	}
    303        1.1  elad 
    304        1.1  elad 	if (result == KAUTH_RESULT_DEFER) {
    305        1.1  elad 		result = kauth_authorize_action(
    306        1.1  elad 		    secmodel_overlay_iscope_process, cred, action,
    307        1.1  elad 		    arg0, arg1, arg2, arg3);
    308        1.1  elad 	}
    309        1.1  elad 
    310        1.1  elad 	return (result);
    311        1.1  elad }
    312        1.1  elad 
    313        1.1  elad /*
    314        1.1  elad  * Overlay listener for the network scope.
    315        1.1  elad  */
    316        1.1  elad int
    317        1.1  elad secmodel_overlay_network_cb(kauth_cred_t cred, kauth_action_t action,
    318        1.1  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    319        1.1  elad {
    320        1.1  elad 	int result;
    321        1.1  elad 
    322        1.1  elad 	result = KAUTH_RESULT_DEFER;
    323        1.1  elad 
    324        1.1  elad 	switch (action) {
    325        1.1  elad 	default:
    326        1.1  elad 		result = KAUTH_RESULT_DEFER;
    327        1.1  elad 		break;
    328        1.1  elad 	}
    329        1.1  elad 
    330        1.1  elad 	if (result == KAUTH_RESULT_DEFER) {
    331        1.1  elad 		result = kauth_authorize_action(
    332        1.1  elad 		    secmodel_overlay_iscope_network, cred, action,
    333        1.1  elad 		    arg0, arg1, arg2, arg3);
    334        1.1  elad 	}
    335        1.1  elad 
    336        1.1  elad 	return (result);
    337        1.1  elad }
    338        1.1  elad 
    339        1.1  elad /*
    340        1.1  elad  * Overlay listener for the machdep scope.
    341        1.1  elad  */
    342        1.1  elad int
    343        1.1  elad secmodel_overlay_machdep_cb(kauth_cred_t cred, kauth_action_t action,
    344        1.1  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    345        1.1  elad {
    346        1.1  elad 	int result;
    347        1.1  elad 
    348        1.1  elad 	result = KAUTH_RESULT_DEFER;
    349        1.1  elad 
    350        1.1  elad 	switch (action) {
    351        1.1  elad 	default:
    352        1.1  elad 		result = KAUTH_RESULT_DEFER;
    353        1.1  elad 		break;
    354        1.1  elad 	}
    355        1.1  elad 
    356        1.1  elad 	if (result == KAUTH_RESULT_DEFER) {
    357        1.1  elad 		result = kauth_authorize_action(
    358        1.1  elad 		    secmodel_overlay_iscope_machdep, cred, action,
    359        1.1  elad 		    arg0, arg1, arg2, arg3);
    360        1.1  elad 	}
    361        1.1  elad 
    362        1.1  elad 	return (result);
    363        1.1  elad }
    364        1.4  elad 
    365        1.4  elad /*
    366        1.4  elad  * Overlay listener for the device scope.
    367        1.4  elad  */
    368        1.4  elad int
    369        1.4  elad secmodel_overlay_device_cb(kauth_cred_t cred, kauth_action_t action,
    370        1.4  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    371        1.4  elad {
    372        1.4  elad 	int result;
    373        1.4  elad 
    374        1.4  elad 	result = KAUTH_RESULT_DEFER;
    375        1.4  elad 
    376        1.4  elad 	switch (action) {
    377        1.4  elad 	default:
    378        1.4  elad 		result = KAUTH_RESULT_DEFER;
    379        1.4  elad 		break;
    380        1.4  elad 	}
    381        1.4  elad 
    382        1.4  elad 	if (result == KAUTH_RESULT_DEFER) {
    383        1.4  elad 		result = kauth_authorize_action(
    384        1.4  elad 		    secmodel_overlay_iscope_device, cred, action,
    385        1.4  elad 		    arg0, arg1, arg2, arg3);
    386        1.4  elad 	}
    387        1.4  elad 
    388        1.4  elad 	return (result);
    389        1.4  elad }
    390       1.10  elad 
    391       1.10  elad /*
    392       1.10  elad  * Overlay listener for the vnode scope.
    393       1.10  elad  */
    394       1.10  elad int
    395       1.10  elad secmodel_overlay_vnode_cb(kauth_cred_t cred, kauth_action_t action,
    396       1.10  elad     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    397       1.10  elad {
    398       1.10  elad 	int result;
    399       1.10  elad 
    400       1.10  elad 	result = KAUTH_RESULT_DEFER;
    401       1.10  elad 
    402       1.10  elad 	switch (action) {
    403       1.10  elad 	default:
    404       1.10  elad 		result = KAUTH_RESULT_DEFER;
    405       1.10  elad 		break;
    406       1.10  elad 	}
    407       1.10  elad 
    408       1.10  elad 	if (result == KAUTH_RESULT_DEFER) {
    409       1.10  elad 		result = kauth_authorize_action(
    410       1.10  elad 		    secmodel_overlay_iscope_vnode, cred, action,
    411       1.10  elad 		    arg0, arg1, arg2, arg3);
    412       1.10  elad 	}
    413       1.10  elad 
    414       1.10  elad 	return (result);
    415       1.10  elad }
    416