1 1.14 pgoyette /* $NetBSD: secmodel_overlay.c,v 1.14 2020/03/16 21:20:12 pgoyette 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.14 pgoyette __KERNEL_RCSID(0, "$NetBSD: secmodel_overlay.c,v 1.14 2020/03/16 21:20:12 pgoyette 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.12 jym #include <secmodel/secmodel.h> 40 1.12 jym 41 1.1 elad #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.12 jym static secmodel_t overlay_sm; 71 1.1 elad 72 1.1 elad /* 73 1.1 elad * Initialize the overlay security model. 74 1.1 elad */ 75 1.1 elad void 76 1.1 elad secmodel_overlay_init(void) 77 1.1 elad { 78 1.1 elad /* 79 1.1 elad * Register internal fall-back scopes. 80 1.1 elad */ 81 1.1 elad secmodel_overlay_iscope_generic = kauth_register_scope( 82 1.1 elad OVERLAY_ISCOPE_GENERIC, NULL, NULL); 83 1.1 elad secmodel_overlay_iscope_system = kauth_register_scope( 84 1.1 elad OVERLAY_ISCOPE_SYSTEM, NULL, NULL); 85 1.1 elad secmodel_overlay_iscope_process = kauth_register_scope( 86 1.1 elad OVERLAY_ISCOPE_PROCESS, NULL, NULL); 87 1.1 elad secmodel_overlay_iscope_network = kauth_register_scope( 88 1.1 elad OVERLAY_ISCOPE_NETWORK, NULL, NULL); 89 1.1 elad secmodel_overlay_iscope_machdep = kauth_register_scope( 90 1.1 elad OVERLAY_ISCOPE_MACHDEP, NULL, NULL); 91 1.4 elad secmodel_overlay_iscope_device = kauth_register_scope( 92 1.4 elad OVERLAY_ISCOPE_DEVICE, NULL, NULL); 93 1.10 elad secmodel_overlay_iscope_vnode = kauth_register_scope( 94 1.10 elad OVERLAY_ISCOPE_VNODE, NULL, NULL); 95 1.1 elad 96 1.1 elad /* 97 1.10 elad * Register fall-back listeners, from suser and securelevel, to each 98 1.10 elad * internal scope. 99 1.1 elad */ 100 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_GENERIC, 101 1.10 elad secmodel_suser_generic_cb, NULL); 102 1.1 elad 103 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_SYSTEM, 104 1.10 elad secmodel_suser_system_cb, NULL); 105 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_SYSTEM, 106 1.9 elad secmodel_securelevel_system_cb, NULL); 107 1.1 elad 108 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_PROCESS, 109 1.10 elad secmodel_suser_process_cb, NULL); 110 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_PROCESS, 111 1.9 elad secmodel_securelevel_process_cb, NULL); 112 1.1 elad 113 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_NETWORK, 114 1.10 elad secmodel_suser_network_cb, NULL); 115 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_NETWORK, 116 1.9 elad secmodel_securelevel_network_cb, NULL); 117 1.1 elad 118 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_MACHDEP, 119 1.10 elad secmodel_suser_machdep_cb, NULL); 120 1.1 elad kauth_listen_scope(OVERLAY_ISCOPE_MACHDEP, 121 1.9 elad secmodel_securelevel_machdep_cb, NULL); 122 1.1 elad 123 1.4 elad kauth_listen_scope(OVERLAY_ISCOPE_DEVICE, 124 1.10 elad secmodel_suser_device_cb, NULL); 125 1.4 elad kauth_listen_scope(OVERLAY_ISCOPE_DEVICE, 126 1.9 elad secmodel_securelevel_device_cb, NULL); 127 1.1 elad } 128 1.1 elad 129 1.14 pgoyette SYSCTL_SETUP(sysctl_security_overlay_setup, "secmod overlay sysctl") 130 1.1 elad { 131 1.1 elad const struct sysctlnode *rnode; 132 1.1 elad 133 1.1 elad sysctl_createv(clog, 0, NULL, &rnode, 134 1.1 elad CTLFLAG_PERMANENT, 135 1.1 elad CTLTYPE_NODE, "models", NULL, 136 1.1 elad NULL, 0, NULL, 0, 137 1.13 pooka CTL_SECURITY, CTL_CREATE, CTL_EOL); 138 1.1 elad 139 1.1 elad sysctl_createv(clog, 0, &rnode, &rnode, 140 1.1 elad CTLFLAG_PERMANENT, 141 1.1 elad CTLTYPE_NODE, "overlay", 142 1.12 jym SYSCTL_DESCR("Overlay security model on-top of bsd44"), 143 1.1 elad NULL, 0, NULL, 0, 144 1.1 elad CTL_CREATE, CTL_EOL); 145 1.1 elad 146 1.1 elad sysctl_createv(clog, 0, &rnode, NULL, 147 1.1 elad CTLFLAG_PERMANENT, 148 1.1 elad CTLTYPE_STRING, "name", NULL, 149 1.12 jym NULL, 0, __UNCONST(SECMODEL_OVERLAY_NAME), 0, 150 1.1 elad CTL_CREATE, CTL_EOL); 151 1.1 elad } 152 1.1 elad 153 1.1 elad /* 154 1.1 elad * Start the overlay security model. 155 1.1 elad */ 156 1.1 elad void 157 1.7 elad secmodel_overlay_start(void) 158 1.1 elad { 159 1.10 elad l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC, 160 1.1 elad secmodel_overlay_generic_cb, NULL); 161 1.10 elad l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM, 162 1.1 elad secmodel_overlay_system_cb, NULL); 163 1.10 elad l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 164 1.1 elad secmodel_overlay_process_cb, NULL); 165 1.10 elad l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK, 166 1.1 elad secmodel_overlay_network_cb, NULL); 167 1.10 elad l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP, 168 1.1 elad secmodel_overlay_machdep_cb, NULL); 169 1.10 elad l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE, 170 1.4 elad secmodel_overlay_device_cb, NULL); 171 1.10 elad l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE, 172 1.10 elad secmodel_overlay_vnode_cb, NULL); 173 1.1 elad } 174 1.1 elad 175 1.10 elad /* 176 1.10 elad * Stop the overlay security model. 177 1.10 elad */ 178 1.7 elad void 179 1.10 elad secmodel_overlay_stop(void) 180 1.7 elad { 181 1.10 elad kauth_unlisten_scope(l_generic); 182 1.10 elad kauth_unlisten_scope(l_system); 183 1.10 elad kauth_unlisten_scope(l_process); 184 1.10 elad kauth_unlisten_scope(l_network); 185 1.10 elad kauth_unlisten_scope(l_machdep); 186 1.10 elad kauth_unlisten_scope(l_device); 187 1.10 elad kauth_unlisten_scope(l_vnode); 188 1.10 elad } 189 1.10 elad 190 1.10 elad static int 191 1.10 elad secmodel_overlay_modcmd(modcmd_t cmd, void *arg) 192 1.10 elad { 193 1.10 elad int error = 0; 194 1.10 elad 195 1.10 elad switch (cmd) { 196 1.10 elad case MODULE_CMD_INIT: 197 1.12 jym error = secmodel_register(&overlay_sm, 198 1.12 jym SECMODEL_OVERLAY_ID, SECMODEL_OVERLAY_NAME, 199 1.12 jym NULL, NULL, NULL); 200 1.12 jym if (error != 0) 201 1.12 jym printf("secmodel_overlay_modcmd::init: " 202 1.12 jym "secmodel_register returned %d\n", error); 203 1.12 jym 204 1.10 elad secmodel_overlay_init(); 205 1.11 jym secmodel_suser_stop(); 206 1.11 jym secmodel_securelevel_stop(); 207 1.10 elad secmodel_overlay_start(); 208 1.10 elad break; 209 1.10 elad 210 1.10 elad case MODULE_CMD_FINI: 211 1.10 elad secmodel_overlay_stop(); 212 1.12 jym 213 1.12 jym error = secmodel_deregister(overlay_sm); 214 1.12 jym if (error != 0) 215 1.12 jym printf("secmodel_overlay_modcmd::fini: " 216 1.12 jym "secmodel_deregister returned %d\n", error); 217 1.10 elad break; 218 1.10 elad 219 1.10 elad case MODULE_CMD_AUTOUNLOAD: 220 1.10 elad error = EPERM; 221 1.10 elad break; 222 1.10 elad 223 1.10 elad default: 224 1.10 elad error = ENOTTY; 225 1.10 elad break; 226 1.10 elad } 227 1.10 elad 228 1.10 elad return error; 229 1.7 elad } 230 1.7 elad 231 1.1 elad /* 232 1.1 elad * Overlay listener for the generic scope. 233 1.1 elad */ 234 1.1 elad int 235 1.1 elad secmodel_overlay_generic_cb(kauth_cred_t cred, kauth_action_t action, 236 1.1 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 237 1.1 elad { 238 1.1 elad int result; 239 1.1 elad 240 1.1 elad result = KAUTH_RESULT_DEFER; 241 1.1 elad 242 1.1 elad switch (action) { 243 1.1 elad default: 244 1.1 elad result = KAUTH_RESULT_DEFER; 245 1.1 elad break; 246 1.1 elad } 247 1.1 elad 248 1.1 elad if (result == KAUTH_RESULT_DEFER) { 249 1.1 elad result = kauth_authorize_action( 250 1.1 elad secmodel_overlay_iscope_generic, cred, action, 251 1.1 elad arg0, arg1, arg2, arg3); 252 1.1 elad } 253 1.1 elad 254 1.1 elad return (result); 255 1.1 elad } 256 1.1 elad 257 1.1 elad /* 258 1.1 elad * Overlay listener for the system scope. 259 1.1 elad */ 260 1.1 elad int 261 1.1 elad secmodel_overlay_system_cb(kauth_cred_t cred, kauth_action_t action, 262 1.1 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 263 1.1 elad { 264 1.1 elad int result; 265 1.1 elad 266 1.1 elad result = KAUTH_RESULT_DEFER; 267 1.1 elad 268 1.1 elad switch (action) { 269 1.1 elad default: 270 1.1 elad result = KAUTH_RESULT_DEFER; 271 1.1 elad break; 272 1.1 elad } 273 1.1 elad 274 1.1 elad if (result == KAUTH_RESULT_DEFER) { 275 1.1 elad result = kauth_authorize_action( 276 1.1 elad secmodel_overlay_iscope_system, cred, action, 277 1.1 elad arg0, arg1, arg2, arg3); 278 1.1 elad } 279 1.1 elad 280 1.1 elad return (result); 281 1.1 elad } 282 1.1 elad 283 1.1 elad /* 284 1.1 elad * Overlay listener for the process scope. 285 1.1 elad */ 286 1.1 elad int 287 1.1 elad secmodel_overlay_process_cb(kauth_cred_t cred, kauth_action_t action, 288 1.1 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 289 1.1 elad { 290 1.1 elad int result; 291 1.1 elad 292 1.1 elad result = KAUTH_RESULT_DEFER; 293 1.1 elad 294 1.1 elad switch (action) { 295 1.1 elad default: 296 1.1 elad result = KAUTH_RESULT_DEFER; 297 1.1 elad break; 298 1.1 elad } 299 1.1 elad 300 1.1 elad if (result == KAUTH_RESULT_DEFER) { 301 1.1 elad result = kauth_authorize_action( 302 1.1 elad secmodel_overlay_iscope_process, cred, action, 303 1.1 elad arg0, arg1, arg2, arg3); 304 1.1 elad } 305 1.1 elad 306 1.1 elad return (result); 307 1.1 elad } 308 1.1 elad 309 1.1 elad /* 310 1.1 elad * Overlay listener for the network scope. 311 1.1 elad */ 312 1.1 elad int 313 1.1 elad secmodel_overlay_network_cb(kauth_cred_t cred, kauth_action_t action, 314 1.1 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 315 1.1 elad { 316 1.1 elad int result; 317 1.1 elad 318 1.1 elad result = KAUTH_RESULT_DEFER; 319 1.1 elad 320 1.1 elad switch (action) { 321 1.1 elad default: 322 1.1 elad result = KAUTH_RESULT_DEFER; 323 1.1 elad break; 324 1.1 elad } 325 1.1 elad 326 1.1 elad if (result == KAUTH_RESULT_DEFER) { 327 1.1 elad result = kauth_authorize_action( 328 1.1 elad secmodel_overlay_iscope_network, cred, action, 329 1.1 elad arg0, arg1, arg2, arg3); 330 1.1 elad } 331 1.1 elad 332 1.1 elad return (result); 333 1.1 elad } 334 1.1 elad 335 1.1 elad /* 336 1.1 elad * Overlay listener for the machdep scope. 337 1.1 elad */ 338 1.1 elad int 339 1.1 elad secmodel_overlay_machdep_cb(kauth_cred_t cred, kauth_action_t action, 340 1.1 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 341 1.1 elad { 342 1.1 elad int result; 343 1.1 elad 344 1.1 elad result = KAUTH_RESULT_DEFER; 345 1.1 elad 346 1.1 elad switch (action) { 347 1.1 elad default: 348 1.1 elad result = KAUTH_RESULT_DEFER; 349 1.1 elad break; 350 1.1 elad } 351 1.1 elad 352 1.1 elad if (result == KAUTH_RESULT_DEFER) { 353 1.1 elad result = kauth_authorize_action( 354 1.1 elad secmodel_overlay_iscope_machdep, cred, action, 355 1.1 elad arg0, arg1, arg2, arg3); 356 1.1 elad } 357 1.1 elad 358 1.1 elad return (result); 359 1.1 elad } 360 1.4 elad 361 1.4 elad /* 362 1.4 elad * Overlay listener for the device scope. 363 1.4 elad */ 364 1.4 elad int 365 1.4 elad secmodel_overlay_device_cb(kauth_cred_t cred, kauth_action_t action, 366 1.4 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 367 1.4 elad { 368 1.4 elad int result; 369 1.4 elad 370 1.4 elad result = KAUTH_RESULT_DEFER; 371 1.4 elad 372 1.4 elad switch (action) { 373 1.4 elad default: 374 1.4 elad result = KAUTH_RESULT_DEFER; 375 1.4 elad break; 376 1.4 elad } 377 1.4 elad 378 1.4 elad if (result == KAUTH_RESULT_DEFER) { 379 1.4 elad result = kauth_authorize_action( 380 1.4 elad secmodel_overlay_iscope_device, cred, action, 381 1.4 elad arg0, arg1, arg2, arg3); 382 1.4 elad } 383 1.4 elad 384 1.4 elad return (result); 385 1.4 elad } 386 1.10 elad 387 1.10 elad /* 388 1.10 elad * Overlay listener for the vnode scope. 389 1.10 elad */ 390 1.10 elad int 391 1.10 elad secmodel_overlay_vnode_cb(kauth_cred_t cred, kauth_action_t action, 392 1.10 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 393 1.10 elad { 394 1.10 elad int result; 395 1.10 elad 396 1.10 elad result = KAUTH_RESULT_DEFER; 397 1.10 elad 398 1.10 elad switch (action) { 399 1.10 elad default: 400 1.10 elad result = KAUTH_RESULT_DEFER; 401 1.10 elad break; 402 1.10 elad } 403 1.10 elad 404 1.10 elad if (result == KAUTH_RESULT_DEFER) { 405 1.10 elad result = kauth_authorize_action( 406 1.10 elad secmodel_overlay_iscope_vnode, cred, action, 407 1.10 elad arg0, arg1, arg2, arg3); 408 1.10 elad } 409 1.10 elad 410 1.10 elad return (result); 411 1.10 elad } 412