44 45#include "opt_mac.h" 46 47#include <sys/param.h> 48#include <sys/condvar.h> 49#include <sys/imgact.h> 50#include <sys/kernel.h> 51#include <sys/lock.h> 52#include <sys/malloc.h> 53#include <sys/mutex.h> 54#include <sys/mac.h> 55#include <sys/proc.h> 56#include <sys/sbuf.h> 57#include <sys/systm.h> 58#include <sys/vnode.h> 59#include <sys/mount.h> 60#include <sys/file.h> 61#include <sys/namei.h> 62#include <sys/sysctl.h> 63 64#include <vm/vm.h> 65#include <vm/pmap.h> 66#include <vm/vm_map.h> 67#include <vm/vm_object.h> 68 69#include <security/mac/mac_framework.h> 70#include <security/mac/mac_internal.h> 71#include <security/mac/mac_policy.h> 72 73static int mac_mmap_revocation = 1; 74SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 75 &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 76 "relabel"); 77 78static int mac_mmap_revocation_via_cow = 0; 79SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 80 &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 81 "copy-on-write semantics, or by removing all write access"); 82 83static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 84 struct ucred *cred, struct vm_map *map); 85 86struct label * 87mac_cred_label_alloc(void) 88{ 89 struct label *label; 90 91 label = mac_labelzone_alloc(M_WAITOK); 92 MAC_PERFORM(cred_init_label, label); 93 return (label); 94} 95 96void 97mac_cred_init(struct ucred *cred) 98{ 99 100 cred->cr_label = mac_cred_label_alloc(); 101} 102 103static struct label * 104mac_proc_label_alloc(void) 105{ 106 struct label *label; 107 108 label = mac_labelzone_alloc(M_WAITOK); 109 MAC_PERFORM(proc_init_label, label); 110 return (label); 111} 112 113void 114mac_proc_init(struct proc *p) 115{ 116 117 p->p_label = mac_proc_label_alloc(); 118} 119 120void 121mac_cred_label_free(struct label *label) 122{ 123 124 MAC_PERFORM(cred_destroy_label, label); 125 mac_labelzone_free(label); 126} 127 128void 129mac_cred_destroy(struct ucred *cred) 130{ 131 132 mac_cred_label_free(cred->cr_label); 133 cred->cr_label = NULL; 134} 135 136static void 137mac_proc_label_free(struct label *label) 138{ 139 140 MAC_PERFORM(proc_destroy_label, label); 141 mac_labelzone_free(label); 142} 143 144void 145mac_proc_destroy(struct proc *p) 146{ 147 148 mac_proc_label_free(p->p_label); 149 p->p_label = NULL; 150} 151 152int 153mac_cred_externalize_label(struct label *label, char *elements, 154 char *outbuf, size_t outbuflen) 155{ 156 int error; 157 158 MAC_EXTERNALIZE(cred, label, elements, outbuf, outbuflen); 159 160 return (error); 161} 162 163int 164mac_cred_internalize_label(struct label *label, char *string) 165{ 166 int error; 167 168 MAC_INTERNALIZE(cred, label, string); 169 170 return (error); 171} 172 173/* 174 * Initialize MAC label for the first kernel process, from which other kernel 175 * processes and threads are spawned. 176 */ 177void 178mac_proc_create_swapper(struct ucred *cred) 179{ 180 181 MAC_PERFORM(proc_create_swapper, cred); 182} 183 184/* 185 * Initialize MAC label for the first userland process, from which other 186 * userland processes and threads are spawned. 187 */ 188void 189mac_proc_create_init(struct ucred *cred) 190{ 191 192 MAC_PERFORM(proc_create_init, cred); 193} 194
| 44 45#include "opt_mac.h" 46 47#include <sys/param.h> 48#include <sys/condvar.h> 49#include <sys/imgact.h> 50#include <sys/kernel.h> 51#include <sys/lock.h> 52#include <sys/malloc.h> 53#include <sys/mutex.h> 54#include <sys/mac.h> 55#include <sys/proc.h> 56#include <sys/sbuf.h> 57#include <sys/systm.h> 58#include <sys/vnode.h> 59#include <sys/mount.h> 60#include <sys/file.h> 61#include <sys/namei.h> 62#include <sys/sysctl.h> 63 64#include <vm/vm.h> 65#include <vm/pmap.h> 66#include <vm/vm_map.h> 67#include <vm/vm_object.h> 68 69#include <security/mac/mac_framework.h> 70#include <security/mac/mac_internal.h> 71#include <security/mac/mac_policy.h> 72 73static int mac_mmap_revocation = 1; 74SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 75 &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 76 "relabel"); 77 78static int mac_mmap_revocation_via_cow = 0; 79SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 80 &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 81 "copy-on-write semantics, or by removing all write access"); 82 83static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 84 struct ucred *cred, struct vm_map *map); 85 86struct label * 87mac_cred_label_alloc(void) 88{ 89 struct label *label; 90 91 label = mac_labelzone_alloc(M_WAITOK); 92 MAC_PERFORM(cred_init_label, label); 93 return (label); 94} 95 96void 97mac_cred_init(struct ucred *cred) 98{ 99 100 cred->cr_label = mac_cred_label_alloc(); 101} 102 103static struct label * 104mac_proc_label_alloc(void) 105{ 106 struct label *label; 107 108 label = mac_labelzone_alloc(M_WAITOK); 109 MAC_PERFORM(proc_init_label, label); 110 return (label); 111} 112 113void 114mac_proc_init(struct proc *p) 115{ 116 117 p->p_label = mac_proc_label_alloc(); 118} 119 120void 121mac_cred_label_free(struct label *label) 122{ 123 124 MAC_PERFORM(cred_destroy_label, label); 125 mac_labelzone_free(label); 126} 127 128void 129mac_cred_destroy(struct ucred *cred) 130{ 131 132 mac_cred_label_free(cred->cr_label); 133 cred->cr_label = NULL; 134} 135 136static void 137mac_proc_label_free(struct label *label) 138{ 139 140 MAC_PERFORM(proc_destroy_label, label); 141 mac_labelzone_free(label); 142} 143 144void 145mac_proc_destroy(struct proc *p) 146{ 147 148 mac_proc_label_free(p->p_label); 149 p->p_label = NULL; 150} 151 152int 153mac_cred_externalize_label(struct label *label, char *elements, 154 char *outbuf, size_t outbuflen) 155{ 156 int error; 157 158 MAC_EXTERNALIZE(cred, label, elements, outbuf, outbuflen); 159 160 return (error); 161} 162 163int 164mac_cred_internalize_label(struct label *label, char *string) 165{ 166 int error; 167 168 MAC_INTERNALIZE(cred, label, string); 169 170 return (error); 171} 172 173/* 174 * Initialize MAC label for the first kernel process, from which other kernel 175 * processes and threads are spawned. 176 */ 177void 178mac_proc_create_swapper(struct ucred *cred) 179{ 180 181 MAC_PERFORM(proc_create_swapper, cred); 182} 183 184/* 185 * Initialize MAC label for the first userland process, from which other 186 * userland processes and threads are spawned. 187 */ 188void 189mac_proc_create_init(struct ucred *cred) 190{ 191 192 MAC_PERFORM(proc_create_init, cred); 193} 194
|
196mac_thread_userret(struct thread *td) 197{ 198 199 MAC_PERFORM(thread_userret, td); 200} 201 202/* 203 * When a new process is created, its label must be initialized. Generally, 204 * this involves inheritence from the parent process, modulo possible deltas. 205 * This function allows that processing to take place. 206 */ 207void 208mac_cred_copy(struct ucred *src, struct ucred *dest) 209{ 210 211 MAC_PERFORM(cred_copy_label, src->cr_label, dest->cr_label); 212} 213 214int 215mac_execve_enter(struct image_params *imgp, struct mac *mac_p) 216{ 217 struct label *label; 218 struct mac mac; 219 char *buffer; 220 int error; 221 222 if (mac_p == NULL) 223 return (0); 224 225 error = copyin(mac_p, &mac, sizeof(mac)); 226 if (error) 227 return (error); 228 229 error = mac_check_structmac_consistent(&mac); 230 if (error) 231 return (error); 232 233 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 234 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 235 if (error) { 236 free(buffer, M_MACTEMP); 237 return (error); 238 } 239 240 label = mac_cred_label_alloc(); 241 error = mac_cred_internalize_label(label, buffer); 242 free(buffer, M_MACTEMP); 243 if (error) { 244 mac_cred_label_free(label); 245 return (error); 246 } 247 imgp->execlabel = label; 248 return (0); 249} 250 251void 252mac_execve_exit(struct image_params *imgp) 253{ 254 if (imgp->execlabel != NULL) { 255 mac_cred_label_free(imgp->execlabel); 256 imgp->execlabel = NULL; 257 } 258} 259 260/* 261 * When relabeling a process, call out to the policies for the maximum 262 * permission allowed for each object type we know about in its memory space, 263 * and revoke access (in the least surprising ways we know) when necessary. 264 * The process lock is not held here. 265 */ 266void 267mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 268{ 269 270 /* XXX freeze all other threads */ 271 mac_cred_mmapped_drop_perms_recurse(td, cred, 272 &td->td_proc->p_vmspace->vm_map); 273 /* XXX allow other threads to continue */ 274} 275 276static __inline const char * 277prot2str(vm_prot_t prot) 278{ 279 280 switch (prot & VM_PROT_ALL) { 281 case VM_PROT_READ: 282 return ("r--"); 283 case VM_PROT_READ | VM_PROT_WRITE: 284 return ("rw-"); 285 case VM_PROT_READ | VM_PROT_EXECUTE: 286 return ("r-x"); 287 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 288 return ("rwx"); 289 case VM_PROT_WRITE: 290 return ("-w-"); 291 case VM_PROT_EXECUTE: 292 return ("--x"); 293 case VM_PROT_WRITE | VM_PROT_EXECUTE: 294 return ("-wx"); 295 default: 296 return ("---"); 297 } 298} 299 300static void 301mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 302 struct vm_map *map) 303{ 304 struct vm_map_entry *vme; 305 int vfslocked, result; 306 vm_prot_t revokeperms; 307 vm_object_t backing_object, object; 308 vm_ooffset_t offset; 309 struct vnode *vp; 310 struct mount *mp; 311 312 if (!mac_mmap_revocation) 313 return; 314 315 vm_map_lock_read(map); 316 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 317 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 318 mac_cred_mmapped_drop_perms_recurse(td, cred, 319 vme->object.sub_map); 320 continue; 321 } 322 /* 323 * Skip over entries that obviously are not shared. 324 */ 325 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 326 !vme->max_protection) 327 continue; 328 /* 329 * Drill down to the deepest backing object. 330 */ 331 offset = vme->offset; 332 object = vme->object.vm_object; 333 if (object == NULL) 334 continue; 335 VM_OBJECT_LOCK(object); 336 while ((backing_object = object->backing_object) != NULL) { 337 VM_OBJECT_LOCK(backing_object); 338 offset += object->backing_object_offset; 339 VM_OBJECT_UNLOCK(object); 340 object = backing_object; 341 } 342 VM_OBJECT_UNLOCK(object); 343 /* 344 * At the moment, vm_maps and objects aren't considered by 345 * the MAC system, so only things with backing by a normal 346 * object (read: vnodes) are checked. 347 */ 348 if (object->type != OBJT_VNODE) 349 continue; 350 vp = (struct vnode *)object->handle; 351 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 352 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 353 result = vme->max_protection; 354 mac_vnode_check_mmap_downgrade(cred, vp, &result); 355 VOP_UNLOCK(vp, 0, td); 356 /* 357 * Find out what maximum protection we may be allowing now 358 * but a policy needs to get removed. 359 */ 360 revokeperms = vme->max_protection & ~result; 361 if (!revokeperms) { 362 VFS_UNLOCK_GIANT(vfslocked); 363 continue; 364 } 365 printf("pid %ld: revoking %s perms from %#lx:%ld " 366 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 367 prot2str(revokeperms), (u_long)vme->start, 368 (long)(vme->end - vme->start), 369 prot2str(vme->max_protection), prot2str(vme->protection)); 370 vm_map_lock_upgrade(map); 371 /* 372 * This is the really simple case: if a map has more 373 * max_protection than is allowed, but it's not being 374 * actually used (that is, the current protection is still 375 * allowed), we can just wipe it out and do nothing more. 376 */ 377 if ((vme->protection & revokeperms) == 0) { 378 vme->max_protection -= revokeperms; 379 } else { 380 if (revokeperms & VM_PROT_WRITE) { 381 /* 382 * In the more complicated case, flush out all 383 * pending changes to the object then turn it 384 * copy-on-write. 385 */ 386 vm_object_reference(object); 387 (void) vn_start_write(vp, &mp, V_WAIT); 388 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 389 VM_OBJECT_LOCK(object); 390 vm_object_page_clean(object, 391 OFF_TO_IDX(offset), 392 OFF_TO_IDX(offset + vme->end - vme->start + 393 PAGE_MASK), 394 OBJPC_SYNC); 395 VM_OBJECT_UNLOCK(object); 396 VOP_UNLOCK(vp, 0, td); 397 vn_finished_write(mp); 398 vm_object_deallocate(object); 399 /* 400 * Why bother if there's no read permissions 401 * anymore? For the rest, we need to leave 402 * the write permissions on for COW, or 403 * remove them entirely if configured to. 404 */ 405 if (!mac_mmap_revocation_via_cow) { 406 vme->max_protection &= ~VM_PROT_WRITE; 407 vme->protection &= ~VM_PROT_WRITE; 408 } if ((revokeperms & VM_PROT_READ) == 0) 409 vme->eflags |= MAP_ENTRY_COW | 410 MAP_ENTRY_NEEDS_COPY; 411 } 412 if (revokeperms & VM_PROT_EXECUTE) { 413 vme->max_protection &= ~VM_PROT_EXECUTE; 414 vme->protection &= ~VM_PROT_EXECUTE; 415 } 416 if (revokeperms & VM_PROT_READ) { 417 vme->max_protection = 0; 418 vme->protection = 0; 419 } 420 pmap_protect(map->pmap, vme->start, vme->end, 421 vme->protection & ~revokeperms); 422 vm_map_simplify_entry(map, vme); 423 } 424 vm_map_lock_downgrade(map); 425 VFS_UNLOCK_GIANT(vfslocked); 426 } 427 vm_map_unlock_read(map); 428} 429 430/* 431 * When the subject's label changes, it may require revocation of privilege 432 * to mapped objects. This can't be done on-the-fly later with a unified 433 * buffer cache. 434 */ 435void 436mac_cred_relabel(struct ucred *cred, struct label *newlabel) 437{ 438 439 MAC_PERFORM(cred_relabel, cred, newlabel); 440} 441 442int 443mac_cred_check_relabel(struct ucred *cred, struct label *newlabel) 444{ 445 int error; 446 447 MAC_CHECK(cred_check_relabel, cred, newlabel); 448 449 return (error); 450} 451 452int 453mac_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 454{ 455 int error; 456 457 MAC_CHECK(cred_check_visible, cr1, cr2); 458 459 return (error); 460} 461 462int 463mac_proc_check_debug(struct ucred *cred, struct proc *p) 464{ 465 int error; 466 467 PROC_LOCK_ASSERT(p, MA_OWNED); 468 469 MAC_CHECK(proc_check_debug, cred, p); 470 471 return (error); 472} 473 474int 475mac_proc_check_sched(struct ucred *cred, struct proc *p) 476{ 477 int error; 478 479 PROC_LOCK_ASSERT(p, MA_OWNED); 480 481 MAC_CHECK(proc_check_sched, cred, p); 482 483 return (error); 484} 485 486int 487mac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 488{ 489 int error; 490 491 PROC_LOCK_ASSERT(p, MA_OWNED); 492 493 MAC_CHECK(proc_check_signal, cred, p, signum); 494 495 return (error); 496} 497 498int 499mac_proc_check_setuid(struct proc *p, struct ucred *cred, uid_t uid) 500{ 501 int error; 502 503 PROC_LOCK_ASSERT(p, MA_OWNED); 504 505 MAC_CHECK(proc_check_setuid, cred, uid); 506 return (error); 507} 508 509int 510mac_proc_check_seteuid(struct proc *p, struct ucred *cred, uid_t euid) 511{ 512 int error; 513 514 PROC_LOCK_ASSERT(p, MA_OWNED); 515 516 MAC_CHECK(proc_check_seteuid, cred, euid); 517 return (error); 518} 519 520int 521mac_proc_check_setgid(struct proc *p, struct ucred *cred, gid_t gid) 522{ 523 int error; 524 525 PROC_LOCK_ASSERT(p, MA_OWNED); 526 527 MAC_CHECK(proc_check_setgid, cred, gid); 528 529 return (error); 530} 531 532int 533mac_proc_check_setegid(struct proc *p, struct ucred *cred, gid_t egid) 534{ 535 int error; 536 537 PROC_LOCK_ASSERT(p, MA_OWNED); 538 539 MAC_CHECK(proc_check_setegid, cred, egid); 540 541 return (error); 542} 543 544int 545mac_proc_check_setgroups(struct proc *p, struct ucred *cred, int ngroups, 546 gid_t *gidset) 547{ 548 int error; 549 550 PROC_LOCK_ASSERT(p, MA_OWNED); 551 552 MAC_CHECK(proc_check_setgroups, cred, ngroups, gidset); 553 return (error); 554} 555 556int 557mac_proc_check_setreuid(struct proc *p, struct ucred *cred, uid_t ruid, 558 uid_t euid) 559{ 560 int error; 561 562 PROC_LOCK_ASSERT(p, MA_OWNED); 563 564 MAC_CHECK(proc_check_setreuid, cred, ruid, euid); 565 566 return (error); 567} 568 569int 570mac_proc_check_setregid(struct proc *proc, struct ucred *cred, gid_t rgid, 571 gid_t egid) 572{ 573 int error; 574 575 PROC_LOCK_ASSERT(proc, MA_OWNED); 576 577 MAC_CHECK(proc_check_setregid, cred, rgid, egid); 578 579 return (error); 580} 581 582int 583mac_proc_check_setresuid(struct proc *p, struct ucred *cred, uid_t ruid, 584 uid_t euid, uid_t suid) 585{ 586 int error; 587 588 PROC_LOCK_ASSERT(p, MA_OWNED); 589 590 MAC_CHECK(proc_check_setresuid, cred, ruid, euid, suid); 591 return (error); 592} 593 594int 595mac_proc_check_setresgid(struct proc *p, struct ucred *cred, gid_t rgid, 596 gid_t egid, gid_t sgid) 597{ 598 int error; 599 600 PROC_LOCK_ASSERT(p, MA_OWNED); 601 602 MAC_CHECK(proc_check_setresgid, cred, rgid, egid, sgid); 603 604 return (error); 605} 606 607int 608mac_proc_check_wait(struct ucred *cred, struct proc *p) 609{ 610 int error; 611 612 PROC_LOCK_ASSERT(p, MA_OWNED); 613 614 MAC_CHECK(proc_check_wait, cred, p); 615 616 return (error); 617}
| 212mac_thread_userret(struct thread *td) 213{ 214 215 MAC_PERFORM(thread_userret, td); 216} 217 218/* 219 * When a new process is created, its label must be initialized. Generally, 220 * this involves inheritence from the parent process, modulo possible deltas. 221 * This function allows that processing to take place. 222 */ 223void 224mac_cred_copy(struct ucred *src, struct ucred *dest) 225{ 226 227 MAC_PERFORM(cred_copy_label, src->cr_label, dest->cr_label); 228} 229 230int 231mac_execve_enter(struct image_params *imgp, struct mac *mac_p) 232{ 233 struct label *label; 234 struct mac mac; 235 char *buffer; 236 int error; 237 238 if (mac_p == NULL) 239 return (0); 240 241 error = copyin(mac_p, &mac, sizeof(mac)); 242 if (error) 243 return (error); 244 245 error = mac_check_structmac_consistent(&mac); 246 if (error) 247 return (error); 248 249 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 250 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 251 if (error) { 252 free(buffer, M_MACTEMP); 253 return (error); 254 } 255 256 label = mac_cred_label_alloc(); 257 error = mac_cred_internalize_label(label, buffer); 258 free(buffer, M_MACTEMP); 259 if (error) { 260 mac_cred_label_free(label); 261 return (error); 262 } 263 imgp->execlabel = label; 264 return (0); 265} 266 267void 268mac_execve_exit(struct image_params *imgp) 269{ 270 if (imgp->execlabel != NULL) { 271 mac_cred_label_free(imgp->execlabel); 272 imgp->execlabel = NULL; 273 } 274} 275 276/* 277 * When relabeling a process, call out to the policies for the maximum 278 * permission allowed for each object type we know about in its memory space, 279 * and revoke access (in the least surprising ways we know) when necessary. 280 * The process lock is not held here. 281 */ 282void 283mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 284{ 285 286 /* XXX freeze all other threads */ 287 mac_cred_mmapped_drop_perms_recurse(td, cred, 288 &td->td_proc->p_vmspace->vm_map); 289 /* XXX allow other threads to continue */ 290} 291 292static __inline const char * 293prot2str(vm_prot_t prot) 294{ 295 296 switch (prot & VM_PROT_ALL) { 297 case VM_PROT_READ: 298 return ("r--"); 299 case VM_PROT_READ | VM_PROT_WRITE: 300 return ("rw-"); 301 case VM_PROT_READ | VM_PROT_EXECUTE: 302 return ("r-x"); 303 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 304 return ("rwx"); 305 case VM_PROT_WRITE: 306 return ("-w-"); 307 case VM_PROT_EXECUTE: 308 return ("--x"); 309 case VM_PROT_WRITE | VM_PROT_EXECUTE: 310 return ("-wx"); 311 default: 312 return ("---"); 313 } 314} 315 316static void 317mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 318 struct vm_map *map) 319{ 320 struct vm_map_entry *vme; 321 int vfslocked, result; 322 vm_prot_t revokeperms; 323 vm_object_t backing_object, object; 324 vm_ooffset_t offset; 325 struct vnode *vp; 326 struct mount *mp; 327 328 if (!mac_mmap_revocation) 329 return; 330 331 vm_map_lock_read(map); 332 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 333 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 334 mac_cred_mmapped_drop_perms_recurse(td, cred, 335 vme->object.sub_map); 336 continue; 337 } 338 /* 339 * Skip over entries that obviously are not shared. 340 */ 341 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 342 !vme->max_protection) 343 continue; 344 /* 345 * Drill down to the deepest backing object. 346 */ 347 offset = vme->offset; 348 object = vme->object.vm_object; 349 if (object == NULL) 350 continue; 351 VM_OBJECT_LOCK(object); 352 while ((backing_object = object->backing_object) != NULL) { 353 VM_OBJECT_LOCK(backing_object); 354 offset += object->backing_object_offset; 355 VM_OBJECT_UNLOCK(object); 356 object = backing_object; 357 } 358 VM_OBJECT_UNLOCK(object); 359 /* 360 * At the moment, vm_maps and objects aren't considered by 361 * the MAC system, so only things with backing by a normal 362 * object (read: vnodes) are checked. 363 */ 364 if (object->type != OBJT_VNODE) 365 continue; 366 vp = (struct vnode *)object->handle; 367 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 368 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 369 result = vme->max_protection; 370 mac_vnode_check_mmap_downgrade(cred, vp, &result); 371 VOP_UNLOCK(vp, 0, td); 372 /* 373 * Find out what maximum protection we may be allowing now 374 * but a policy needs to get removed. 375 */ 376 revokeperms = vme->max_protection & ~result; 377 if (!revokeperms) { 378 VFS_UNLOCK_GIANT(vfslocked); 379 continue; 380 } 381 printf("pid %ld: revoking %s perms from %#lx:%ld " 382 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 383 prot2str(revokeperms), (u_long)vme->start, 384 (long)(vme->end - vme->start), 385 prot2str(vme->max_protection), prot2str(vme->protection)); 386 vm_map_lock_upgrade(map); 387 /* 388 * This is the really simple case: if a map has more 389 * max_protection than is allowed, but it's not being 390 * actually used (that is, the current protection is still 391 * allowed), we can just wipe it out and do nothing more. 392 */ 393 if ((vme->protection & revokeperms) == 0) { 394 vme->max_protection -= revokeperms; 395 } else { 396 if (revokeperms & VM_PROT_WRITE) { 397 /* 398 * In the more complicated case, flush out all 399 * pending changes to the object then turn it 400 * copy-on-write. 401 */ 402 vm_object_reference(object); 403 (void) vn_start_write(vp, &mp, V_WAIT); 404 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 405 VM_OBJECT_LOCK(object); 406 vm_object_page_clean(object, 407 OFF_TO_IDX(offset), 408 OFF_TO_IDX(offset + vme->end - vme->start + 409 PAGE_MASK), 410 OBJPC_SYNC); 411 VM_OBJECT_UNLOCK(object); 412 VOP_UNLOCK(vp, 0, td); 413 vn_finished_write(mp); 414 vm_object_deallocate(object); 415 /* 416 * Why bother if there's no read permissions 417 * anymore? For the rest, we need to leave 418 * the write permissions on for COW, or 419 * remove them entirely if configured to. 420 */ 421 if (!mac_mmap_revocation_via_cow) { 422 vme->max_protection &= ~VM_PROT_WRITE; 423 vme->protection &= ~VM_PROT_WRITE; 424 } if ((revokeperms & VM_PROT_READ) == 0) 425 vme->eflags |= MAP_ENTRY_COW | 426 MAP_ENTRY_NEEDS_COPY; 427 } 428 if (revokeperms & VM_PROT_EXECUTE) { 429 vme->max_protection &= ~VM_PROT_EXECUTE; 430 vme->protection &= ~VM_PROT_EXECUTE; 431 } 432 if (revokeperms & VM_PROT_READ) { 433 vme->max_protection = 0; 434 vme->protection = 0; 435 } 436 pmap_protect(map->pmap, vme->start, vme->end, 437 vme->protection & ~revokeperms); 438 vm_map_simplify_entry(map, vme); 439 } 440 vm_map_lock_downgrade(map); 441 VFS_UNLOCK_GIANT(vfslocked); 442 } 443 vm_map_unlock_read(map); 444} 445 446/* 447 * When the subject's label changes, it may require revocation of privilege 448 * to mapped objects. This can't be done on-the-fly later with a unified 449 * buffer cache. 450 */ 451void 452mac_cred_relabel(struct ucred *cred, struct label *newlabel) 453{ 454 455 MAC_PERFORM(cred_relabel, cred, newlabel); 456} 457 458int 459mac_cred_check_relabel(struct ucred *cred, struct label *newlabel) 460{ 461 int error; 462 463 MAC_CHECK(cred_check_relabel, cred, newlabel); 464 465 return (error); 466} 467 468int 469mac_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 470{ 471 int error; 472 473 MAC_CHECK(cred_check_visible, cr1, cr2); 474 475 return (error); 476} 477 478int 479mac_proc_check_debug(struct ucred *cred, struct proc *p) 480{ 481 int error; 482 483 PROC_LOCK_ASSERT(p, MA_OWNED); 484 485 MAC_CHECK(proc_check_debug, cred, p); 486 487 return (error); 488} 489 490int 491mac_proc_check_sched(struct ucred *cred, struct proc *p) 492{ 493 int error; 494 495 PROC_LOCK_ASSERT(p, MA_OWNED); 496 497 MAC_CHECK(proc_check_sched, cred, p); 498 499 return (error); 500} 501 502int 503mac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 504{ 505 int error; 506 507 PROC_LOCK_ASSERT(p, MA_OWNED); 508 509 MAC_CHECK(proc_check_signal, cred, p, signum); 510 511 return (error); 512} 513 514int 515mac_proc_check_setuid(struct proc *p, struct ucred *cred, uid_t uid) 516{ 517 int error; 518 519 PROC_LOCK_ASSERT(p, MA_OWNED); 520 521 MAC_CHECK(proc_check_setuid, cred, uid); 522 return (error); 523} 524 525int 526mac_proc_check_seteuid(struct proc *p, struct ucred *cred, uid_t euid) 527{ 528 int error; 529 530 PROC_LOCK_ASSERT(p, MA_OWNED); 531 532 MAC_CHECK(proc_check_seteuid, cred, euid); 533 return (error); 534} 535 536int 537mac_proc_check_setgid(struct proc *p, struct ucred *cred, gid_t gid) 538{ 539 int error; 540 541 PROC_LOCK_ASSERT(p, MA_OWNED); 542 543 MAC_CHECK(proc_check_setgid, cred, gid); 544 545 return (error); 546} 547 548int 549mac_proc_check_setegid(struct proc *p, struct ucred *cred, gid_t egid) 550{ 551 int error; 552 553 PROC_LOCK_ASSERT(p, MA_OWNED); 554 555 MAC_CHECK(proc_check_setegid, cred, egid); 556 557 return (error); 558} 559 560int 561mac_proc_check_setgroups(struct proc *p, struct ucred *cred, int ngroups, 562 gid_t *gidset) 563{ 564 int error; 565 566 PROC_LOCK_ASSERT(p, MA_OWNED); 567 568 MAC_CHECK(proc_check_setgroups, cred, ngroups, gidset); 569 return (error); 570} 571 572int 573mac_proc_check_setreuid(struct proc *p, struct ucred *cred, uid_t ruid, 574 uid_t euid) 575{ 576 int error; 577 578 PROC_LOCK_ASSERT(p, MA_OWNED); 579 580 MAC_CHECK(proc_check_setreuid, cred, ruid, euid); 581 582 return (error); 583} 584 585int 586mac_proc_check_setregid(struct proc *proc, struct ucred *cred, gid_t rgid, 587 gid_t egid) 588{ 589 int error; 590 591 PROC_LOCK_ASSERT(proc, MA_OWNED); 592 593 MAC_CHECK(proc_check_setregid, cred, rgid, egid); 594 595 return (error); 596} 597 598int 599mac_proc_check_setresuid(struct proc *p, struct ucred *cred, uid_t ruid, 600 uid_t euid, uid_t suid) 601{ 602 int error; 603 604 PROC_LOCK_ASSERT(p, MA_OWNED); 605 606 MAC_CHECK(proc_check_setresuid, cred, ruid, euid, suid); 607 return (error); 608} 609 610int 611mac_proc_check_setresgid(struct proc *p, struct ucred *cred, gid_t rgid, 612 gid_t egid, gid_t sgid) 613{ 614 int error; 615 616 PROC_LOCK_ASSERT(p, MA_OWNED); 617 618 MAC_CHECK(proc_check_setresgid, cred, rgid, egid, sgid); 619 620 return (error); 621} 622 623int 624mac_proc_check_wait(struct ucred *cred, struct proc *p) 625{ 626 int error; 627 628 PROC_LOCK_ASSERT(p, MA_OWNED); 629 630 MAC_CHECK(proc_check_wait, cred, p); 631 632 return (error); 633}
|