1 /* $NetBSD: kern_pax.c,v 1.55 2016/05/27 16:35:16 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2015 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Maxime Villard. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. The name of the author may not be used to endorse or promote products 45 * derived from this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 */ 58 59 #include <sys/cdefs.h> 60 __KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.55 2016/05/27 16:35:16 christos Exp $"); 61 62 #include "opt_pax.h" 63 64 #include <sys/param.h> 65 #include <sys/proc.h> 66 #include <sys/exec.h> 67 #include <sys/exec_elf.h> 68 #include <sys/pax.h> 69 #include <sys/sysctl.h> 70 #include <sys/kmem.h> 71 #include <sys/mman.h> 72 #include <sys/fileassoc.h> 73 #include <sys/syslog.h> 74 #include <sys/vnode.h> 75 #include <sys/queue.h> 76 #include <sys/bitops.h> 77 #include <sys/kauth.h> 78 #include <sys/cprng.h> 79 80 #ifdef PAX_ASLR_DEBUG 81 #define PAX_DPRINTF(_fmt, args...) \ 82 do if (pax_aslr_debug) uprintf("%s: " _fmt "\n", __func__, ##args); \ 83 while (/*CONSTCOND*/0) 84 #else 85 #define PAX_DPRINTF(_fmt, args...) do {} while (/*CONSTCOND*/0) 86 #endif 87 88 #ifdef PAX_ASLR 89 #include <sys/mman.h> 90 91 int pax_aslr_enabled = 1; 92 int pax_aslr_global = PAX_ASLR; 93 94 #ifndef PAX_ASLR_DELTA_MMAP_LSB 95 #define PAX_ASLR_DELTA_MMAP_LSB PGSHIFT 96 #endif 97 #ifndef PAX_ASLR_DELTA_MMAP_LEN 98 #define PAX_ASLR_DELTA_MMAP_LEN ((sizeof(void *) * NBBY) / 2) 99 #endif 100 #ifndef PAX_ASLR_DELTA_MMAP_LEN32 101 #define PAX_ASLR_DELTA_MMAP_LEN32 ((sizeof(uint32_t) * NBBY) / 2) 102 #endif 103 #ifndef PAX_ASLR_DELTA_STACK_LSB 104 #define PAX_ASLR_DELTA_STACK_LSB PGSHIFT 105 #endif 106 #ifndef PAX_ASLR_DELTA_STACK_LEN 107 #define PAX_ASLR_DELTA_STACK_LEN ((sizeof(void *) * NBBY) / 4) 108 #endif 109 #ifndef PAX_ASLR_DELTA_STACK_LEN32 110 #define PAX_ASLR_DELTA_STACK_LEN32 ((sizeof(uint32_t) * NBBY) / 4) 111 #endif 112 #define PAX_ASLR_MAX_STACK_WASTE 8 113 114 static bool pax_aslr_elf_flags_active(uint32_t); 115 #endif /* PAX_ASLR */ 116 117 #ifdef PAX_MPROTECT 118 static int pax_mprotect_enabled = 1; 119 static int pax_mprotect_global = PAX_MPROTECT; 120 static int pax_mprotect_ptrace = 1; 121 static bool pax_mprotect_elf_flags_active(uint32_t); 122 #endif /* PAX_MPROTECT */ 123 #ifdef PAX_MPROTECT_DEBUG 124 int pax_mprotect_debug; 125 #endif 126 127 #ifdef PAX_SEGVGUARD 128 #ifndef PAX_SEGVGUARD_EXPIRY 129 #define PAX_SEGVGUARD_EXPIRY (2 * 60) 130 #endif 131 #ifndef PAX_SEGVGUARD_SUSPENSION 132 #define PAX_SEGVGUARD_SUSPENSION (10 * 60) 133 #endif 134 #ifndef PAX_SEGVGUARD_MAXCRASHES 135 #define PAX_SEGVGUARD_MAXCRASHES 5 136 #endif 137 138 #ifdef PAX_ASLR_DEBUG 139 int pax_aslr_debug; 140 /* flag set means disable */ 141 int pax_aslr_flags; 142 uint32_t pax_aslr_rand; 143 #define PAX_ASLR_STACK 0x01 144 #define PAX_ASLR_STACK_GAP 0x02 145 #define PAX_ASLR_MMAP 0x04 146 #define PAX_ASLR_EXEC_OFFSET 0x08 147 #define PAX_ASLR_RTLD_OFFSET 0x10 148 #define PAX_ASLR_FIXED 0x20 149 #endif 150 151 static int pax_segvguard_enabled = 1; 152 static int pax_segvguard_global = PAX_SEGVGUARD; 153 static int pax_segvguard_expiry = PAX_SEGVGUARD_EXPIRY; 154 static int pax_segvguard_suspension = PAX_SEGVGUARD_SUSPENSION; 155 static int pax_segvguard_maxcrashes = PAX_SEGVGUARD_MAXCRASHES; 156 157 static fileassoc_t segvguard_id; 158 159 struct pax_segvguard_uid_entry { 160 uid_t sue_uid; 161 size_t sue_ncrashes; 162 time_t sue_expiry; 163 time_t sue_suspended; 164 LIST_ENTRY(pax_segvguard_uid_entry) sue_list; 165 }; 166 167 struct pax_segvguard_entry { 168 LIST_HEAD(, pax_segvguard_uid_entry) segv_uids; 169 }; 170 171 static bool pax_segvguard_elf_flags_active(uint32_t); 172 static void pax_segvguard_cleanup_cb(void *); 173 #endif /* PAX_SEGVGUARD */ 174 175 SYSCTL_SETUP(sysctl_security_pax_setup, "sysctl security.pax setup") 176 { 177 const struct sysctlnode *rnode = NULL, *cnode; 178 179 sysctl_createv(clog, 0, NULL, &rnode, 180 CTLFLAG_PERMANENT, 181 CTLTYPE_NODE, "pax", 182 SYSCTL_DESCR("PaX (exploit mitigation) features."), 183 NULL, 0, NULL, 0, 184 CTL_SECURITY, CTL_CREATE, CTL_EOL); 185 186 cnode = rnode; 187 188 #ifdef PAX_MPROTECT 189 rnode = cnode; 190 sysctl_createv(clog, 0, &rnode, &rnode, 191 CTLFLAG_PERMANENT, 192 CTLTYPE_NODE, "mprotect", 193 SYSCTL_DESCR("mprotect(2) W^X restrictions."), 194 NULL, 0, NULL, 0, 195 CTL_CREATE, CTL_EOL); 196 sysctl_createv(clog, 0, &rnode, NULL, 197 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 198 CTLTYPE_INT, "enabled", 199 SYSCTL_DESCR("Restrictions enabled."), 200 NULL, 0, &pax_mprotect_enabled, 0, 201 CTL_CREATE, CTL_EOL); 202 sysctl_createv(clog, 0, &rnode, NULL, 203 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 204 CTLTYPE_INT, "global", 205 SYSCTL_DESCR("When enabled, unless explicitly " 206 "specified, apply restrictions to " 207 "all processes."), 208 NULL, 0, &pax_mprotect_global, 0, 209 CTL_CREATE, CTL_EOL); 210 sysctl_createv(clog, 0, &rnode, NULL, 211 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 212 CTLTYPE_INT, "ptrace", 213 SYSCTL_DESCR("When enabled, allow ptrace(2) to " 214 "override mprotect permissions on traced " 215 "processes"), 216 NULL, 0, &pax_mprotect_ptrace, 0, 217 CTL_CREATE, CTL_EOL); 218 #ifdef PAX_MPROTECT_DEBUG 219 sysctl_createv(clog, 0, &rnode, NULL, 220 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 221 CTLTYPE_INT, "debug", 222 SYSCTL_DESCR("print mprotect changes."), 223 NULL, 0, &pax_mprotect_debug, 0, 224 CTL_CREATE, CTL_EOL); 225 #endif 226 #endif /* PAX_MPROTECT */ 227 228 #ifdef PAX_SEGVGUARD 229 rnode = cnode; 230 sysctl_createv(clog, 0, &rnode, &rnode, 231 CTLFLAG_PERMANENT, 232 CTLTYPE_NODE, "segvguard", 233 SYSCTL_DESCR("PaX segvguard."), 234 NULL, 0, NULL, 0, 235 CTL_CREATE, CTL_EOL); 236 sysctl_createv(clog, 0, &rnode, NULL, 237 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 238 CTLTYPE_INT, "enabled", 239 SYSCTL_DESCR("segvguard enabled."), 240 NULL, 0, &pax_segvguard_enabled, 0, 241 CTL_CREATE, CTL_EOL); 242 sysctl_createv(clog, 0, &rnode, NULL, 243 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 244 CTLTYPE_INT, "global", 245 SYSCTL_DESCR("segvguard all programs."), 246 NULL, 0, &pax_segvguard_global, 0, 247 CTL_CREATE, CTL_EOL); 248 sysctl_createv(clog, 0, &rnode, NULL, 249 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 250 CTLTYPE_INT, "expiry_timeout", 251 SYSCTL_DESCR("Entry expiry timeout (in seconds)."), 252 NULL, 0, &pax_segvguard_expiry, 0, 253 CTL_CREATE, CTL_EOL); 254 sysctl_createv(clog, 0, &rnode, NULL, 255 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 256 CTLTYPE_INT, "suspend_timeout", 257 SYSCTL_DESCR("Entry suspension timeout (in seconds)."), 258 NULL, 0, &pax_segvguard_suspension, 0, 259 CTL_CREATE, CTL_EOL); 260 sysctl_createv(clog, 0, &rnode, NULL, 261 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 262 CTLTYPE_INT, "max_crashes", 263 SYSCTL_DESCR("Max number of crashes before expiry."), 264 NULL, 0, &pax_segvguard_maxcrashes, 0, 265 CTL_CREATE, CTL_EOL); 266 #endif /* PAX_SEGVGUARD */ 267 268 #ifdef PAX_ASLR 269 rnode = cnode; 270 sysctl_createv(clog, 0, &rnode, &rnode, 271 CTLFLAG_PERMANENT, 272 CTLTYPE_NODE, "aslr", 273 SYSCTL_DESCR("Address Space Layout Randomization."), 274 NULL, 0, NULL, 0, 275 CTL_CREATE, CTL_EOL); 276 sysctl_createv(clog, 0, &rnode, NULL, 277 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 278 CTLTYPE_INT, "enabled", 279 SYSCTL_DESCR("Restrictions enabled."), 280 NULL, 0, &pax_aslr_enabled, 0, 281 CTL_CREATE, CTL_EOL); 282 sysctl_createv(clog, 0, &rnode, NULL, 283 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 284 CTLTYPE_INT, "global", 285 SYSCTL_DESCR("When enabled, unless explicitly " 286 "specified, apply to all processes."), 287 NULL, 0, &pax_aslr_global, 0, 288 CTL_CREATE, CTL_EOL); 289 #ifdef PAX_ASLR_DEBUG 290 sysctl_createv(clog, 0, &rnode, NULL, 291 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 292 CTLTYPE_INT, "debug", 293 SYSCTL_DESCR("Pring ASLR selected addresses."), 294 NULL, 0, &pax_aslr_debug, 0, 295 CTL_CREATE, CTL_EOL); 296 sysctl_createv(clog, 0, &rnode, NULL, 297 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 298 CTLTYPE_INT, "flags", 299 SYSCTL_DESCR("Disable/Enable select ASLR features."), 300 NULL, 0, &pax_aslr_flags, 0, 301 CTL_CREATE, CTL_EOL); 302 sysctl_createv(clog, 0, &rnode, NULL, 303 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 304 CTLTYPE_INT, "rand", 305 SYSCTL_DESCR("Use the given fixed random value"), 306 NULL, 0, &pax_aslr_rand, 0, 307 CTL_CREATE, CTL_EOL); 308 #endif 309 sysctl_createv(clog, 0, &rnode, NULL, 310 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 311 CTLTYPE_INT, "mmap_len", 312 SYSCTL_DESCR("Number of bits randomized for " 313 "mmap(2) calls."), 314 NULL, PAX_ASLR_DELTA_MMAP_LEN, NULL, 0, 315 CTL_CREATE, CTL_EOL); 316 sysctl_createv(clog, 0, &rnode, NULL, 317 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 318 CTLTYPE_INT, "stack_len", 319 SYSCTL_DESCR("Number of bits randomized for " 320 "the stack."), 321 NULL, PAX_ASLR_DELTA_STACK_LEN, NULL, 0, 322 CTL_CREATE, CTL_EOL); 323 sysctl_createv(clog, 0, &rnode, NULL, 324 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 325 CTLTYPE_INT, "exec_len", 326 SYSCTL_DESCR("Number of bits randomized for " 327 "the PIE exec base."), 328 NULL, PAX_ASLR_DELTA_EXEC_LEN, NULL, 0, 329 CTL_CREATE, CTL_EOL); 330 331 #endif /* PAX_ASLR */ 332 } 333 334 /* 335 * Initialize PaX. 336 */ 337 void 338 pax_init(void) 339 { 340 #ifdef PAX_SEGVGUARD 341 int error; 342 343 error = fileassoc_register("segvguard", pax_segvguard_cleanup_cb, 344 &segvguard_id); 345 if (error) { 346 panic("pax_init: segvguard_id: error=%d\n", error); 347 } 348 #endif /* PAX_SEGVGUARD */ 349 #ifdef PAX_ASLR 350 /* Adjust maximum stack by the size we can consume for ASLR */ 351 extern rlim_t maxsmap; 352 maxsmap = MAXSSIZ - (MAXSSIZ / PAX_ASLR_MAX_STACK_WASTE); 353 // XXX: compat32 is not handled. 354 #endif 355 } 356 357 void 358 pax_set_flags(struct exec_package *epp, struct proc *p) 359 { 360 p->p_pax = epp->ep_pax_flags; 361 362 #ifdef PAX_MPROTECT 363 if (pax_mprotect_ptrace == 0) 364 return; 365 /* 366 * If we are running under the debugger, turn off MPROTECT so 367 * the debugger can insert/delete breakpoints 368 */ 369 if (p->p_slflag & PSL_TRACED) 370 p->p_pax &= ~P_PAX_MPROTECT; 371 #endif 372 } 373 374 void 375 pax_setup_elf_flags(struct exec_package *epp, uint32_t elf_flags) 376 { 377 uint32_t flags = 0; 378 379 #ifdef PAX_ASLR 380 if (pax_aslr_elf_flags_active(elf_flags)) { 381 flags |= P_PAX_ASLR; 382 } 383 #endif 384 #ifdef PAX_MPROTECT 385 if (pax_mprotect_elf_flags_active(elf_flags)) { 386 flags |= P_PAX_MPROTECT; 387 } 388 #endif 389 #ifdef PAX_SEGVGUARD 390 if (pax_segvguard_elf_flags_active(elf_flags)) { 391 flags |= P_PAX_GUARD; 392 } 393 #endif 394 395 epp->ep_pax_flags = flags; 396 } 397 398 #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR) 399 static inline bool 400 pax_flags_active(uint32_t flags, uint32_t opt) 401 { 402 if (!(flags & opt)) 403 return false; 404 return true; 405 } 406 #endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */ 407 408 #ifdef PAX_MPROTECT 409 static bool 410 pax_mprotect_elf_flags_active(uint32_t flags) 411 { 412 if (!pax_mprotect_enabled) 413 return false; 414 if (pax_mprotect_global && (flags & ELF_NOTE_PAX_NOMPROTECT) != 0) { 415 /* Mprotect explicitly disabled */ 416 return false; 417 } 418 if (!pax_mprotect_global && (flags & ELF_NOTE_PAX_MPROTECT) == 0) { 419 /* Mprotect not requested */ 420 return false; 421 } 422 return true; 423 } 424 425 void 426 pax_mprotect_adjust( 427 #ifdef PAX_MPROTECT_DEBUG 428 const char *file, size_t line, 429 #endif 430 struct lwp *l, vm_prot_t *prot, vm_prot_t *maxprot) 431 { 432 uint32_t flags; 433 434 flags = l->l_proc->p_pax; 435 if (!pax_flags_active(flags, P_PAX_MPROTECT)) 436 return; 437 438 if ((*prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) != VM_PROT_EXECUTE) { 439 #ifdef PAX_MPROTECT_DEBUG 440 struct proc *p = l->l_proc; 441 if ((*prot & VM_PROT_EXECUTE) && pax_mprotect_debug) { 442 printf("%s: %s,%zu: %d.%d (%s): -x\n", 443 __func__, file, line, 444 p->p_pid, l->l_lid, p->p_comm); 445 } 446 #endif 447 *prot &= ~VM_PROT_EXECUTE; 448 *maxprot &= ~VM_PROT_EXECUTE; 449 } else { 450 #ifdef PAX_MPROTECT_DEBUG 451 struct proc *p = l->l_proc; 452 if ((*prot & VM_PROT_WRITE) && pax_mprotect_debug) { 453 printf("%s: %s,%zu: %d.%d (%s): -w\n", 454 __func__, file, line, 455 p->p_pid, l->l_lid, p->p_comm); 456 } 457 #endif 458 *prot &= ~VM_PROT_WRITE; 459 *maxprot &= ~VM_PROT_WRITE; 460 } 461 } 462 463 /* 464 * Bypass MPROTECT for traced processes 465 */ 466 int 467 pax_mprotect_prot(struct lwp *l) 468 { 469 uint32_t flags; 470 471 flags = l->l_proc->p_pax; 472 if (!pax_flags_active(flags, P_PAX_MPROTECT)) 473 return 0; 474 if (pax_mprotect_ptrace < 2) 475 return 0; 476 return UVM_EXTRACT_PROT_ALL; 477 } 478 479 480 #endif /* PAX_MPROTECT */ 481 482 #ifdef PAX_ASLR 483 static bool 484 pax_aslr_elf_flags_active(uint32_t flags) 485 { 486 if (!pax_aslr_enabled) 487 return false; 488 if (pax_aslr_global && (flags & ELF_NOTE_PAX_NOASLR) != 0) { 489 /* ASLR explicitly disabled */ 490 return false; 491 } 492 if (!pax_aslr_global && (flags & ELF_NOTE_PAX_ASLR) == 0) { 493 /* ASLR not requested */ 494 return false; 495 } 496 return true; 497 } 498 499 static bool 500 pax_aslr_epp_active(struct exec_package *epp) 501 { 502 if (__predict_false((epp->ep_flags & (EXEC_32|EXEC_TOPDOWN_VM)) == 0)) 503 return false; 504 return pax_flags_active(epp->ep_pax_flags, P_PAX_ASLR); 505 } 506 507 static bool 508 pax_aslr_active(struct lwp *l) 509 { 510 return pax_flags_active(l->l_proc->p_pax, P_PAX_ASLR); 511 } 512 513 void 514 pax_aslr_init_vm(struct lwp *l, struct vmspace *vm, struct exec_package *ep) 515 { 516 if (!pax_aslr_active(l)) 517 return; 518 519 if (__predict_false((ep->ep_flags & (EXEC_32|EXEC_TOPDOWN_VM)) == 0)) 520 return; 521 522 #ifdef PAX_ASLR_DEBUG 523 if (pax_aslr_flags & PAX_ASLR_MMAP) 524 return; 525 #endif 526 527 uint32_t len = (ep->ep_flags & EXEC_32) ? 528 PAX_ASLR_DELTA_MMAP_LEN32 : PAX_ASLR_DELTA_MMAP_LEN; 529 530 uint32_t rand = cprng_fast32(); 531 #ifdef PAX_ASLR_DEBUG 532 if (pax_aslr_flags & PAX_ASLR_FIXED) 533 rand = pax_aslr_rand; 534 #endif 535 vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(rand, 536 PAX_ASLR_DELTA_MMAP_LSB, len); 537 538 PAX_DPRINTF("delta_mmap=%#jx/%u", 539 (uintmax_t)vm->vm_aslr_delta_mmap, len); 540 } 541 542 void 543 pax_aslr_mmap(struct lwp *l, vaddr_t *addr, vaddr_t orig_addr, int f) 544 { 545 if (!pax_aslr_active(l)) 546 return; 547 #ifdef PAX_ASLR_DEBUG 548 char buf[256]; 549 550 if (pax_aslr_flags & PAX_ASLR_MMAP) 551 return; 552 553 if (pax_aslr_debug) 554 snprintb(buf, sizeof(buf), MAP_FMT, f); 555 else 556 buf[0] = '\0'; 557 #endif 558 559 if (!(f & MAP_FIXED) && ((orig_addr == 0) || !(f & MAP_ANON))) { 560 PAX_DPRINTF("applying to %#jx orig_addr=%#jx f=%s", 561 (uintmax_t)*addr, (uintmax_t)orig_addr, buf); 562 if (!(l->l_proc->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN)) 563 *addr += l->l_proc->p_vmspace->vm_aslr_delta_mmap; 564 else 565 *addr -= l->l_proc->p_vmspace->vm_aslr_delta_mmap; 566 PAX_DPRINTF("result %#jx", (uintmax_t)*addr); 567 } else { 568 PAX_DPRINTF("not applying to %#jx orig_addr=%#jx f=%s", 569 (uintmax_t)*addr, (uintmax_t)orig_addr, buf); 570 } 571 } 572 573 static vaddr_t 574 pax_aslr_offset(vaddr_t align) 575 { 576 size_t pax_align, l2, delta; 577 uint32_t rand; 578 vaddr_t offset; 579 580 pax_align = align == 0 ? PGSHIFT : align; 581 l2 = ilog2(pax_align); 582 583 rand = cprng_fast32(); 584 #ifdef PAX_ASLR_DEBUG 585 if (pax_aslr_flags & PAX_ASLR_FIXED) 586 rand = pax_aslr_rand; 587 #endif 588 589 #define PAX_TRUNC(a, b) ((a) & ~((b) - 1)) 590 591 delta = PAX_ASLR_DELTA(rand, l2, PAX_ASLR_DELTA_EXEC_LEN); 592 offset = PAX_TRUNC(delta, pax_align) + PAGE_SIZE; 593 594 PAX_DPRINTF("rand=%#x l2=%#zx pax_align=%#zx delta=%#zx offset=%#jx", 595 rand, l2, pax_align, delta, (uintmax_t)offset); 596 597 return offset; 598 } 599 600 vaddr_t 601 pax_aslr_exec_offset(struct exec_package *epp, vaddr_t align) 602 { 603 if (!pax_aslr_epp_active(epp)) 604 goto out; 605 606 #ifdef PAX_ASLR_DEBUG 607 if (pax_aslr_flags & PAX_ASLR_EXEC_OFFSET) 608 goto out; 609 #endif 610 return pax_aslr_offset(align) + PAGE_SIZE; 611 out: 612 return MAX(align, PAGE_SIZE); 613 } 614 615 voff_t 616 pax_aslr_rtld_offset(struct exec_package *epp, vaddr_t align, int use_topdown) 617 { 618 voff_t offset; 619 620 if (!pax_aslr_epp_active(epp)) 621 return 0; 622 623 #ifdef PAX_ASLR_DEBUG 624 if (pax_aslr_flags & PAX_ASLR_RTLD_OFFSET) 625 return 0; 626 #endif 627 offset = pax_aslr_offset(align); 628 if (use_topdown) 629 offset = -offset; 630 631 return offset; 632 } 633 634 void 635 pax_aslr_stack(struct exec_package *epp, u_long *max_stack_size) 636 { 637 if (!pax_aslr_epp_active(epp)) 638 return; 639 #ifdef PAX_ASLR_DEBUG 640 if (pax_aslr_flags & PAX_ASLR_STACK) 641 return; 642 #endif 643 644 uint32_t len = (epp->ep_flags & EXEC_32) ? 645 PAX_ASLR_DELTA_STACK_LEN32 : PAX_ASLR_DELTA_STACK_LEN; 646 uint32_t rand = cprng_fast32(); 647 #ifdef PAX_ASLR_DEBUG 648 if (pax_aslr_flags & PAX_ASLR_FIXED) 649 rand = pax_aslr_rand; 650 #endif 651 u_long d = PAX_ASLR_DELTA(rand, PAX_ASLR_DELTA_STACK_LSB, len); 652 d &= (*max_stack_size / PAX_ASLR_MAX_STACK_WASTE) - 1; 653 u_long newminsaddr = (u_long)STACK_GROW(epp->ep_minsaddr, d); 654 PAX_DPRINTF("old minsaddr=%#jx delta=%#lx new minsaddr=%#lx", 655 (uintmax_t)epp->ep_minsaddr, d, newminsaddr); 656 epp->ep_minsaddr = (vaddr_t)newminsaddr; 657 *max_stack_size -= d; 658 } 659 660 uint32_t 661 pax_aslr_stack_gap(struct exec_package *epp) 662 { 663 if (!pax_aslr_epp_active(epp)) 664 return 0; 665 666 #ifdef PAX_ASLR_DEBUG 667 if (pax_aslr_flags & PAX_ASLR_STACK_GAP) 668 return 0; 669 #endif 670 671 uint32_t rand = cprng_fast32(); 672 #ifdef PAX_ASLR_DEBUG 673 if (pax_aslr_flags & PAX_ASLR_FIXED) 674 rand = pax_aslr_rand; 675 #endif 676 rand %= PAGE_SIZE; 677 PAX_DPRINTF("stack gap=%#x\n", rand); 678 return rand; 679 } 680 #endif /* PAX_ASLR */ 681 682 #ifdef PAX_SEGVGUARD 683 static bool 684 pax_segvguard_elf_flags_active(uint32_t flags) 685 { 686 if (!pax_segvguard_enabled) 687 return false; 688 if (pax_segvguard_global && (flags & ELF_NOTE_PAX_NOGUARD) != 0) { 689 /* Segvguard explicitly disabled */ 690 return false; 691 } 692 if (!pax_segvguard_global && (flags & ELF_NOTE_PAX_GUARD) == 0) { 693 /* Segvguard not requested */ 694 return false; 695 } 696 return true; 697 } 698 699 static void 700 pax_segvguard_cleanup_cb(void *v) 701 { 702 struct pax_segvguard_entry *p = v; 703 struct pax_segvguard_uid_entry *up; 704 705 if (p == NULL) { 706 return; 707 } 708 while ((up = LIST_FIRST(&p->segv_uids)) != NULL) { 709 LIST_REMOVE(up, sue_list); 710 kmem_free(up, sizeof(*up)); 711 } 712 kmem_free(p, sizeof(*p)); 713 } 714 715 /* 716 * Called when a process of image vp generated a segfault. 717 */ 718 int 719 pax_segvguard(struct lwp *l, struct vnode *vp, const char *name, 720 bool crashed) 721 { 722 struct pax_segvguard_entry *p; 723 struct pax_segvguard_uid_entry *up; 724 struct timeval tv; 725 uid_t uid; 726 uint32_t flags; 727 bool have_uid; 728 729 flags = l->l_proc->p_pax; 730 if (!pax_flags_active(flags, P_PAX_GUARD)) 731 return 0; 732 733 if (vp == NULL) 734 return EFAULT; 735 736 /* Check if we already monitor the file. */ 737 p = fileassoc_lookup(vp, segvguard_id); 738 739 /* Fast-path if starting a program we don't know. */ 740 if (p == NULL && !crashed) 741 return 0; 742 743 microtime(&tv); 744 745 /* 746 * If a program we don't know crashed, we need to create a new entry 747 * for it. 748 */ 749 if (p == NULL) { 750 p = kmem_alloc(sizeof(*p), KM_SLEEP); 751 fileassoc_add(vp, segvguard_id, p); 752 LIST_INIT(&p->segv_uids); 753 754 /* 755 * Initialize a new entry with "crashes so far" of 1. 756 * The expiry time is when we purge the entry if it didn't 757 * reach the limit. 758 */ 759 up = kmem_alloc(sizeof(*up), KM_SLEEP); 760 up->sue_uid = kauth_cred_getuid(l->l_cred); 761 up->sue_ncrashes = 1; 762 up->sue_expiry = tv.tv_sec + pax_segvguard_expiry; 763 up->sue_suspended = 0; 764 LIST_INSERT_HEAD(&p->segv_uids, up, sue_list); 765 return 0; 766 } 767 768 /* 769 * A program we "know" either executed or crashed again. 770 * See if it's a culprit we're familiar with. 771 */ 772 uid = kauth_cred_getuid(l->l_cred); 773 have_uid = false; 774 LIST_FOREACH(up, &p->segv_uids, sue_list) { 775 if (up->sue_uid == uid) { 776 have_uid = true; 777 break; 778 } 779 } 780 781 /* 782 * It's someone else. Add an entry for him if we crashed. 783 */ 784 if (!have_uid) { 785 if (crashed) { 786 up = kmem_alloc(sizeof(*up), KM_SLEEP); 787 up->sue_uid = uid; 788 up->sue_ncrashes = 1; 789 up->sue_expiry = tv.tv_sec + pax_segvguard_expiry; 790 up->sue_suspended = 0; 791 LIST_INSERT_HEAD(&p->segv_uids, up, sue_list); 792 } 793 return 0; 794 } 795 796 if (crashed) { 797 /* Check if timer on previous crashes expired first. */ 798 if (up->sue_expiry < tv.tv_sec) { 799 log(LOG_INFO, "PaX Segvguard: [%s] Suspension" 800 " expired.\n", name ? name : "unknown"); 801 up->sue_ncrashes = 1; 802 up->sue_expiry = tv.tv_sec + pax_segvguard_expiry; 803 up->sue_suspended = 0; 804 return 0; 805 } 806 807 up->sue_ncrashes++; 808 809 if (up->sue_ncrashes >= pax_segvguard_maxcrashes) { 810 log(LOG_ALERT, "PaX Segvguard: [%s] Suspending " 811 "execution for %d seconds after %zu crashes.\n", 812 name ? name : "unknown", pax_segvguard_suspension, 813 up->sue_ncrashes); 814 815 /* Suspend this program for a while. */ 816 up->sue_suspended = tv.tv_sec + pax_segvguard_suspension; 817 up->sue_ncrashes = 0; 818 up->sue_expiry = 0; 819 } 820 } else { 821 /* Are we supposed to be suspended? */ 822 if (up->sue_suspended > tv.tv_sec) { 823 log(LOG_ALERT, "PaX Segvguard: [%s] Preventing " 824 "execution due to repeated segfaults.\n", name ? 825 name : "unknown"); 826 return EPERM; 827 } 828 } 829 830 return 0; 831 } 832 #endif /* PAX_SEGVGUARD */ 833