1 1.37 thorpej /* $NetBSD: secmodel_securelevel.c,v 1.37 2020/12/05 17:33:53 thorpej 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.1 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.1 elad /* 30 1.1 elad * This file contains kauth(9) listeners needed to implement the traditional 31 1.22 jym * NetBSD securelevel. 32 1.1 elad * 33 1.1 elad * The securelevel is a system-global indication on what operations are 34 1.1 elad * allowed or not. It affects all users, including root. 35 1.1 elad */ 36 1.1 elad 37 1.1 elad #include <sys/cdefs.h> 38 1.37 thorpej __KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.37 2020/12/05 17:33:53 thorpej Exp $"); 39 1.1 elad 40 1.1 elad #ifdef _KERNEL_OPT 41 1.1 elad #include "opt_insecure.h" 42 1.1 elad #endif /* _KERNEL_OPT */ 43 1.1 elad 44 1.1 elad #include <sys/types.h> 45 1.1 elad #include <sys/param.h> 46 1.1 elad #include <sys/kauth.h> 47 1.1 elad 48 1.1 elad #include <sys/conf.h> 49 1.1 elad #include <sys/mount.h> 50 1.1 elad #include <sys/sysctl.h> 51 1.1 elad #include <sys/vnode.h> 52 1.14 elad #include <sys/module.h> 53 1.1 elad 54 1.1 elad #include <miscfs/specfs/specdev.h> 55 1.1 elad 56 1.23 jym #include <secmodel/secmodel.h> 57 1.1 elad #include <secmodel/securelevel/securelevel.h> 58 1.1 elad 59 1.14 elad MODULE(MODULE_CLASS_SECMODEL, securelevel, NULL); 60 1.14 elad 61 1.1 elad static int securelevel; 62 1.1 elad 63 1.13 elad static kauth_listener_t l_system, l_process, l_network, l_machdep, l_device, 64 1.13 elad l_vnode; 65 1.1 elad 66 1.23 jym static secmodel_t securelevel_sm; 67 1.14 elad 68 1.1 elad /* 69 1.20 elad * Sysctl helper routine for securelevel. Ensures that the value only rises 70 1.20 elad * unless the caller is init. 71 1.1 elad */ 72 1.1 elad int 73 1.1 elad secmodel_securelevel_sysctl(SYSCTLFN_ARGS) 74 1.22 jym { 75 1.1 elad int newsecurelevel, error; 76 1.1 elad struct sysctlnode node; 77 1.1 elad 78 1.1 elad newsecurelevel = securelevel; 79 1.1 elad node = *rnode; 80 1.1 elad node.sysctl_data = &newsecurelevel; 81 1.1 elad error = sysctl_lookup(SYSCTLFN_CALL(&node)); 82 1.1 elad if (error || newp == NULL) 83 1.1 elad return (error); 84 1.22 jym 85 1.20 elad if ((newsecurelevel < securelevel) && (l->l_proc != initproc)) 86 1.1 elad return (EPERM); 87 1.1 elad 88 1.1 elad securelevel = newsecurelevel; 89 1.1 elad 90 1.1 elad return (error); 91 1.1 elad } 92 1.1 elad 93 1.34 pgoyette SYSCTL_SETUP(sysctl_security_securelevel_setup, "securelevel sysctl") 94 1.1 elad { 95 1.29 jym const struct sysctlnode *rnode, *rnode2; 96 1.14 elad 97 1.14 elad sysctl_createv(clog, 0, NULL, &rnode, 98 1.14 elad CTLFLAG_PERMANENT, 99 1.14 elad CTLTYPE_NODE, "models", NULL, 100 1.14 elad NULL, 0, NULL, 0, 101 1.30 pooka CTL_SECURITY, CTL_CREATE, CTL_EOL); 102 1.14 elad 103 1.29 jym /* Compatibility: security.models.bsd44 */ 104 1.29 jym rnode2 = rnode; 105 1.29 jym sysctl_createv(clog, 0, &rnode2, &rnode2, 106 1.29 jym CTLFLAG_PERMANENT, 107 1.29 jym CTLTYPE_NODE, "bsd44", NULL, 108 1.29 jym NULL, 0, NULL, 0, 109 1.29 jym CTL_CREATE, CTL_EOL); 110 1.29 jym 111 1.29 jym /* Compatibility: security.models.bsd44.securelevel */ 112 1.29 jym sysctl_createv(clog, 0, &rnode2, NULL, 113 1.29 jym CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 114 1.29 jym CTLTYPE_INT, "securelevel", 115 1.29 jym SYSCTL_DESCR("System security level"), 116 1.29 jym secmodel_securelevel_sysctl, 0, NULL, 0, 117 1.29 jym CTL_CREATE, CTL_EOL); 118 1.29 jym 119 1.14 elad sysctl_createv(clog, 0, &rnode, &rnode, 120 1.14 elad CTLFLAG_PERMANENT, 121 1.14 elad CTLTYPE_NODE, "securelevel", NULL, 122 1.14 elad NULL, 0, NULL, 0, 123 1.14 elad CTL_CREATE, CTL_EOL); 124 1.14 elad 125 1.14 elad sysctl_createv(clog, 0, &rnode, NULL, 126 1.14 elad CTLFLAG_PERMANENT, 127 1.14 elad CTLTYPE_STRING, "name", NULL, 128 1.23 jym NULL, 0, __UNCONST(SECMODEL_SECURELEVEL_NAME), 0, 129 1.14 elad CTL_CREATE, CTL_EOL); 130 1.1 elad 131 1.15 elad sysctl_createv(clog, 0, &rnode, NULL, 132 1.15 elad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 133 1.15 elad CTLTYPE_INT, "securelevel", 134 1.15 elad SYSCTL_DESCR("System security level"), 135 1.15 elad secmodel_securelevel_sysctl, 0, NULL, 0, 136 1.15 elad CTL_CREATE, CTL_EOL); 137 1.15 elad 138 1.14 elad /* Compatibility: kern.securelevel */ 139 1.1 elad 140 1.1 elad sysctl_createv(clog, 0, NULL, NULL, 141 1.1 elad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 142 1.1 elad CTLTYPE_INT, "securelevel", 143 1.1 elad SYSCTL_DESCR("System security level"), 144 1.1 elad secmodel_securelevel_sysctl, 0, NULL, 0, 145 1.1 elad CTL_KERN, KERN_SECURELVL, CTL_EOL); 146 1.1 elad } 147 1.1 elad 148 1.1 elad void 149 1.14 elad secmodel_securelevel_init(void) 150 1.14 elad { 151 1.14 elad #ifdef INSECURE 152 1.14 elad securelevel = -1; 153 1.14 elad #else 154 1.14 elad securelevel = 0; 155 1.14 elad #endif /* INSECURE */ 156 1.14 elad } 157 1.14 elad 158 1.14 elad void 159 1.1 elad secmodel_securelevel_start(void) 160 1.1 elad { 161 1.1 elad l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM, 162 1.1 elad secmodel_securelevel_system_cb, NULL); 163 1.1 elad l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 164 1.1 elad secmodel_securelevel_process_cb, NULL); 165 1.1 elad l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK, 166 1.1 elad secmodel_securelevel_network_cb, NULL); 167 1.1 elad l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP, 168 1.1 elad secmodel_securelevel_machdep_cb, NULL); 169 1.1 elad l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE, 170 1.1 elad secmodel_securelevel_device_cb, NULL); 171 1.13 elad l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE, 172 1.13 elad secmodel_securelevel_vnode_cb, NULL); 173 1.1 elad } 174 1.1 elad 175 1.1 elad void 176 1.1 elad secmodel_securelevel_stop(void) 177 1.1 elad { 178 1.1 elad kauth_unlisten_scope(l_system); 179 1.1 elad kauth_unlisten_scope(l_process); 180 1.1 elad kauth_unlisten_scope(l_network); 181 1.1 elad kauth_unlisten_scope(l_machdep); 182 1.1 elad kauth_unlisten_scope(l_device); 183 1.13 elad kauth_unlisten_scope(l_vnode); 184 1.1 elad } 185 1.14 elad 186 1.14 elad static int 187 1.23 jym securelevel_eval(const char *what, void *arg, void *ret) 188 1.23 jym { 189 1.23 jym int error = 0; 190 1.23 jym 191 1.23 jym if (strcasecmp(what, "is-securelevel-above") == 0) { 192 1.23 jym int level = (int)(uintptr_t)arg; 193 1.23 jym bool *bp = ret; 194 1.23 jym 195 1.23 jym *bp = (securelevel > level); 196 1.23 jym } else { 197 1.23 jym error = ENOENT; 198 1.23 jym } 199 1.23 jym 200 1.23 jym return error; 201 1.23 jym } 202 1.23 jym 203 1.23 jym static int 204 1.14 elad securelevel_modcmd(modcmd_t cmd, void *arg) 205 1.14 elad { 206 1.14 elad int error = 0; 207 1.14 elad 208 1.14 elad switch (cmd) { 209 1.14 elad case MODULE_CMD_INIT: 210 1.24 jym secmodel_securelevel_init(); 211 1.23 jym error = secmodel_register(&securelevel_sm, 212 1.23 jym SECMODEL_SECURELEVEL_ID, SECMODEL_SECURELEVEL_NAME, 213 1.23 jym NULL, securelevel_eval, NULL); 214 1.23 jym if (error != 0) 215 1.23 jym printf("securelevel_modcmd::init: secmodel_register " 216 1.23 jym "returned %d\n", error); 217 1.23 jym 218 1.14 elad secmodel_securelevel_start(); 219 1.14 elad break; 220 1.14 elad 221 1.14 elad case MODULE_CMD_FINI: 222 1.14 elad secmodel_securelevel_stop(); 223 1.23 jym 224 1.23 jym error = secmodel_deregister(securelevel_sm); 225 1.23 jym if (error != 0) 226 1.23 jym printf("securelevel_modcmd::fini: secmodel_deregister " 227 1.23 jym "returned %d\n", error); 228 1.23 jym 229 1.14 elad break; 230 1.14 elad 231 1.14 elad case MODULE_CMD_AUTOUNLOAD: 232 1.14 elad error = EPERM; 233 1.14 elad break; 234 1.14 elad 235 1.14 elad default: 236 1.14 elad error = ENOTTY; 237 1.14 elad break; 238 1.14 elad } 239 1.14 elad 240 1.14 elad return (error); 241 1.14 elad } 242 1.1 elad 243 1.1 elad /* 244 1.1 elad * kauth(9) listener 245 1.1 elad * 246 1.1 elad * Security model: Traditional NetBSD 247 1.1 elad * Scope: System 248 1.1 elad * Responsibility: Securelevel 249 1.1 elad */ 250 1.1 elad int 251 1.18 elad secmodel_securelevel_system_cb(kauth_cred_t cred, kauth_action_t action, 252 1.18 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 253 1.1 elad { 254 1.1 elad int result; 255 1.1 elad enum kauth_system_req req; 256 1.1 elad 257 1.2 elad result = KAUTH_RESULT_DEFER; 258 1.33 joerg req = (enum kauth_system_req)(uintptr_t)arg0; 259 1.1 elad 260 1.1 elad switch (action) { 261 1.1 elad case KAUTH_SYSTEM_CHSYSFLAGS: 262 1.27 elad /* Deprecated. */ 263 1.2 elad if (securelevel > 0) 264 1.2 elad result = KAUTH_RESULT_DENY; 265 1.1 elad break; 266 1.1 elad 267 1.1 elad case KAUTH_SYSTEM_TIME: 268 1.1 elad switch (req) { 269 1.1 elad case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET: 270 1.2 elad if (securelevel > 0) 271 1.2 elad result = KAUTH_RESULT_DENY; 272 1.1 elad break; 273 1.1 elad 274 1.3 elad case KAUTH_REQ_SYSTEM_TIME_SYSTEM: { 275 1.3 elad struct timespec *ts = arg1; 276 1.10 christos struct timespec *delta = arg2; 277 1.3 elad 278 1.16 elad if (securelevel > 1 && time_wraps(ts, delta)) 279 1.3 elad result = KAUTH_RESULT_DENY; 280 1.16 elad 281 1.3 elad break; 282 1.3 elad } 283 1.3 elad 284 1.1 elad default: 285 1.1 elad break; 286 1.1 elad } 287 1.1 elad break; 288 1.1 elad 289 1.27 elad case KAUTH_SYSTEM_MAP_VA_ZERO: 290 1.27 elad if (securelevel > 0) 291 1.27 elad result = KAUTH_RESULT_DENY; 292 1.27 elad break; 293 1.27 elad 294 1.7 ad case KAUTH_SYSTEM_MODULE: 295 1.2 elad if (securelevel > 0) 296 1.2 elad result = KAUTH_RESULT_DENY; 297 1.1 elad break; 298 1.1 elad 299 1.1 elad case KAUTH_SYSTEM_MOUNT: 300 1.1 elad switch (req) { 301 1.1 elad case KAUTH_REQ_SYSTEM_MOUNT_NEW: 302 1.1 elad if (securelevel > 1) 303 1.2 elad result = KAUTH_RESULT_DENY; 304 1.1 elad 305 1.1 elad break; 306 1.1 elad 307 1.1 elad case KAUTH_REQ_SYSTEM_MOUNT_UPDATE: 308 1.1 elad if (securelevel > 1) { 309 1.1 elad struct mount *mp = arg1; 310 1.1 elad u_long flags = (u_long)arg2; 311 1.1 elad 312 1.1 elad /* Can only degrade from read/write to read-only. */ 313 1.1 elad if (flags != (mp->mnt_flag | MNT_RDONLY | MNT_RELOAD | 314 1.1 elad MNT_FORCE | MNT_UPDATE)) 315 1.2 elad result = KAUTH_RESULT_DENY; 316 1.1 elad } 317 1.1 elad 318 1.1 elad break; 319 1.1 elad 320 1.1 elad default: 321 1.1 elad break; 322 1.1 elad } 323 1.1 elad 324 1.1 elad break; 325 1.1 elad 326 1.1 elad case KAUTH_SYSTEM_SYSCTL: 327 1.1 elad switch (req) { 328 1.1 elad case KAUTH_REQ_SYSTEM_SYSCTL_ADD: 329 1.1 elad case KAUTH_REQ_SYSTEM_SYSCTL_DELETE: 330 1.1 elad case KAUTH_REQ_SYSTEM_SYSCTL_DESC: 331 1.2 elad if (securelevel > 0) 332 1.2 elad result = KAUTH_RESULT_DENY; 333 1.1 elad break; 334 1.1 elad 335 1.1 elad default: 336 1.1 elad break; 337 1.1 elad } 338 1.1 elad break; 339 1.1 elad 340 1.1 elad case KAUTH_SYSTEM_SETIDCORE: 341 1.2 elad if (securelevel > 0) 342 1.2 elad result = KAUTH_RESULT_DENY; 343 1.1 elad break; 344 1.1 elad 345 1.1 elad case KAUTH_SYSTEM_DEBUG: 346 1.11 elad default: 347 1.11 elad break; 348 1.1 elad } 349 1.1 elad 350 1.1 elad return (result); 351 1.1 elad } 352 1.1 elad 353 1.1 elad /* 354 1.1 elad * kauth(9) listener 355 1.1 elad * 356 1.1 elad * Security model: Traditional NetBSD 357 1.1 elad * Scope: Process 358 1.1 elad * Responsibility: Securelevel 359 1.1 elad */ 360 1.1 elad int 361 1.18 elad secmodel_securelevel_process_cb(kauth_cred_t cred, kauth_action_t action, 362 1.18 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 363 1.1 elad { 364 1.1 elad struct proc *p; 365 1.1 elad int result; 366 1.1 elad 367 1.2 elad result = KAUTH_RESULT_DEFER; 368 1.1 elad p = arg0; 369 1.1 elad 370 1.1 elad switch (action) { 371 1.8 elad case KAUTH_PROCESS_PROCFS: { 372 1.1 elad enum kauth_process_req req; 373 1.1 elad 374 1.33 joerg req = (enum kauth_process_req)(uintptr_t)arg2; 375 1.1 elad switch (req) { 376 1.8 elad case KAUTH_REQ_PROCESS_PROCFS_READ: 377 1.1 elad break; 378 1.1 elad 379 1.8 elad case KAUTH_REQ_PROCESS_PROCFS_RW: 380 1.8 elad case KAUTH_REQ_PROCESS_PROCFS_WRITE: 381 1.1 elad if ((p == initproc) && (securelevel > -1)) 382 1.1 elad result = KAUTH_RESULT_DENY; 383 1.1 elad 384 1.1 elad break; 385 1.2 elad 386 1.1 elad default: 387 1.1 elad break; 388 1.1 elad } 389 1.1 elad 390 1.1 elad break; 391 1.1 elad } 392 1.1 elad 393 1.8 elad case KAUTH_PROCESS_PTRACE: 394 1.19 elad if ((p == initproc) && (securelevel > -1)) 395 1.1 elad result = KAUTH_RESULT_DENY; 396 1.1 elad 397 1.1 elad break; 398 1.1 elad 399 1.1 elad case KAUTH_PROCESS_CORENAME: 400 1.2 elad if (securelevel > 1) 401 1.2 elad result = KAUTH_RESULT_DENY; 402 1.1 elad break; 403 1.11 elad 404 1.11 elad default: 405 1.11 elad break; 406 1.1 elad } 407 1.1 elad 408 1.1 elad return (result); 409 1.1 elad } 410 1.1 elad 411 1.1 elad /* 412 1.1 elad * kauth(9) listener 413 1.1 elad * 414 1.1 elad * Security model: Traditional NetBSD 415 1.1 elad * Scope: Network 416 1.1 elad * Responsibility: Securelevel 417 1.1 elad */ 418 1.1 elad int 419 1.18 elad secmodel_securelevel_network_cb(kauth_cred_t cred, kauth_action_t action, 420 1.18 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 421 1.1 elad { 422 1.1 elad int result; 423 1.1 elad enum kauth_network_req req; 424 1.1 elad 425 1.2 elad result = KAUTH_RESULT_DEFER; 426 1.33 joerg req = (enum kauth_network_req)(uintptr_t)arg0; 427 1.1 elad 428 1.1 elad switch (action) { 429 1.1 elad case KAUTH_NETWORK_FIREWALL: 430 1.1 elad switch (req) { 431 1.1 elad case KAUTH_REQ_NETWORK_FIREWALL_FW: 432 1.1 elad case KAUTH_REQ_NETWORK_FIREWALL_NAT: 433 1.2 elad if (securelevel > 1) 434 1.2 elad result = KAUTH_RESULT_DENY; 435 1.1 elad break; 436 1.1 elad 437 1.1 elad default: 438 1.1 elad break; 439 1.1 elad } 440 1.1 elad break; 441 1.1 elad 442 1.1 elad case KAUTH_NETWORK_FORWSRCRT: 443 1.2 elad if (securelevel > 0) 444 1.2 elad result = KAUTH_RESULT_DENY; 445 1.1 elad break; 446 1.11 elad 447 1.11 elad default: 448 1.11 elad break; 449 1.1 elad } 450 1.1 elad 451 1.1 elad return (result); 452 1.1 elad } 453 1.1 elad 454 1.22 jym /* 455 1.1 elad * kauth(9) listener 456 1.1 elad * 457 1.1 elad * Security model: Traditional NetBSD 458 1.1 elad * Scope: Machdep 459 1.1 elad * Responsibility: Securelevel 460 1.1 elad */ 461 1.1 elad int 462 1.18 elad secmodel_securelevel_machdep_cb(kauth_cred_t cred, kauth_action_t action, 463 1.18 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 464 1.1 elad { 465 1.28 cheusov int result; 466 1.1 elad 467 1.28 cheusov result = KAUTH_RESULT_DEFER; 468 1.1 elad 469 1.28 cheusov switch (action) { 470 1.1 elad case KAUTH_MACHDEP_IOPERM_SET: 471 1.1 elad case KAUTH_MACHDEP_IOPL: 472 1.2 elad if (securelevel > 0) 473 1.2 elad result = KAUTH_RESULT_DENY; 474 1.1 elad break; 475 1.1 elad 476 1.1 elad case KAUTH_MACHDEP_UNMANAGEDMEM: 477 1.2 elad if (securelevel > 0) 478 1.2 elad result = KAUTH_RESULT_DENY; 479 1.1 elad break; 480 1.11 elad 481 1.31 alnsn case KAUTH_MACHDEP_SVS_DISABLE: 482 1.35 alnsn /* Deprecated. */ 483 1.31 alnsn if (securelevel > 0) 484 1.31 alnsn result = KAUTH_RESULT_DENY; 485 1.31 alnsn break; 486 1.31 alnsn 487 1.25 cegger case KAUTH_MACHDEP_CPU_UCODE_APPLY: 488 1.26 cegger if (securelevel > 1) 489 1.26 cegger result = KAUTH_RESULT_DENY; 490 1.25 cegger break; 491 1.25 cegger 492 1.11 elad default: 493 1.11 elad break; 494 1.1 elad } 495 1.1 elad 496 1.1 elad return (result); 497 1.1 elad } 498 1.1 elad 499 1.1 elad /* 500 1.1 elad * kauth(9) listener 501 1.1 elad * 502 1.1 elad * Security model: Traditional NetBSD 503 1.22 jym * Scope: Device 504 1.1 elad * Responsibility: Securelevel 505 1.1 elad */ 506 1.1 elad int 507 1.18 elad secmodel_securelevel_device_cb(kauth_cred_t cred, kauth_action_t action, 508 1.18 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 509 1.1 elad { 510 1.1 elad int result; 511 1.1 elad 512 1.2 elad result = KAUTH_RESULT_DEFER; 513 1.1 elad 514 1.1 elad switch (action) { 515 1.1 elad case KAUTH_DEVICE_RAWIO_SPEC: { 516 1.17 elad struct vnode *vp; 517 1.1 elad enum kauth_device_req req; 518 1.1 elad 519 1.33 joerg req = (enum kauth_device_req)(uintptr_t)arg0; 520 1.1 elad vp = arg1; 521 1.1 elad 522 1.1 elad KASSERT(vp != NULL); 523 1.1 elad 524 1.1 elad /* Handle /dev/mem and /dev/kmem. */ 525 1.17 elad if (iskmemvp(vp)) { 526 1.1 elad switch (req) { 527 1.1 elad case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ: 528 1.1 elad break; 529 1.1 elad 530 1.1 elad case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE: 531 1.1 elad case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW: 532 1.2 elad if (securelevel > 0) 533 1.2 elad result = KAUTH_RESULT_DENY; 534 1.17 elad 535 1.1 elad break; 536 1.11 elad 537 1.11 elad default: 538 1.11 elad break; 539 1.1 elad } 540 1.1 elad 541 1.1 elad break; 542 1.1 elad } 543 1.1 elad 544 1.1 elad switch (req) { 545 1.1 elad case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ: 546 1.1 elad break; 547 1.1 elad 548 1.1 elad case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE: 549 1.17 elad case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW: { 550 1.17 elad int error; 551 1.1 elad 552 1.17 elad error = rawdev_mounted(vp, NULL); 553 1.1 elad 554 1.17 elad /* Not a disk. */ 555 1.17 elad if (error == EINVAL) 556 1.1 elad break; 557 1.2 elad 558 1.17 elad if (error && securelevel > 0) 559 1.17 elad result = KAUTH_RESULT_DENY; 560 1.1 elad 561 1.2 elad if (securelevel > 1) 562 1.2 elad result = KAUTH_RESULT_DENY; 563 1.1 elad 564 1.1 elad break; 565 1.17 elad } 566 1.11 elad 567 1.11 elad default: 568 1.11 elad break; 569 1.1 elad } 570 1.1 elad 571 1.1 elad break; 572 1.1 elad } 573 1.1 elad 574 1.2 elad case KAUTH_DEVICE_RAWIO_PASSTHRU: 575 1.1 elad if (securelevel > 0) { 576 1.1 elad u_long bits; 577 1.1 elad 578 1.1 elad bits = (u_long)arg0; 579 1.1 elad 580 1.1 elad KASSERT(bits != 0); 581 1.1 elad KASSERT((bits & ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL) == 0); 582 1.1 elad 583 1.1 elad if (bits & ~KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF) 584 1.1 elad result = KAUTH_RESULT_DENY; 585 1.1 elad } 586 1.1 elad 587 1.1 elad break; 588 1.11 elad 589 1.12 mbalmer case KAUTH_DEVICE_GPIO_PINSET: 590 1.12 mbalmer if (securelevel > 0) 591 1.12 mbalmer result = KAUTH_RESULT_DENY; 592 1.12 mbalmer break; 593 1.12 mbalmer 594 1.21 tls case KAUTH_DEVICE_RND_ADDDATA_ESTIMATE: 595 1.36 riastrad if (securelevel > 1) 596 1.21 tls result = KAUTH_RESULT_DENY; 597 1.21 tls break; 598 1.21 tls 599 1.11 elad default: 600 1.11 elad break; 601 1.1 elad } 602 1.1 elad 603 1.1 elad return (result); 604 1.1 elad } 605 1.13 elad 606 1.13 elad int 607 1.13 elad secmodel_securelevel_vnode_cb(kauth_cred_t cred, kauth_action_t action, 608 1.13 elad void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 609 1.13 elad { 610 1.13 elad int result; 611 1.13 elad 612 1.13 elad result = KAUTH_RESULT_DEFER; 613 1.13 elad 614 1.13 elad if ((action & KAUTH_VNODE_WRITE_SYSFLAGS) && 615 1.13 elad (action & KAUTH_VNODE_HAS_SYSFLAGS)) { 616 1.13 elad if (securelevel > 0) 617 1.13 elad result = KAUTH_RESULT_DENY; 618 1.13 elad } 619 1.13 elad 620 1.13 elad return (result); 621 1.13 elad } 622 1.13 elad 623