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