1 /* $NetBSD: subr_asan.c,v 1.26 2020/09/10 14:10:46 maxv Exp $ */ 2 3 /* 4 * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net 5 * All rights reserved. 6 * 7 * This code is part of the KASAN subsystem of the NetBSD kernel. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #define SAN_RUNTIME 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 #if 0 36 __KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.26 2020/09/10 14:10:46 maxv Exp $"); 37 #endif 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/asan.h> 42 #include <sys/kernel.h> 43 #include <sys/stack.h> 44 #include <sys/sysctl.h> 45 46 #include <machine/asan.h> 47 #include <machine/bus.h> 48 49 /* ASAN constants. Part of the compiler ABI. */ 50 #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE - 1) 51 #define KASAN_ALLOCA_SCALE_SIZE 32 52 53 /* ASAN ABI version. */ 54 #if defined(__clang__) && (__clang_major__ - 0 >= 6) 55 #define ASAN_ABI_VERSION 8 56 #elif __GNUC_PREREQ__(7, 1) && !defined(__clang__) 57 #define ASAN_ABI_VERSION 8 58 #elif __GNUC_PREREQ__(6, 1) && !defined(__clang__) 59 #define ASAN_ABI_VERSION 6 60 #else 61 #error "Unsupported compiler version" 62 #endif 63 64 #define __RET_ADDR (unsigned long)__builtin_return_address(0) 65 66 /* Global variable descriptor. Part of the compiler ABI. */ 67 struct __asan_global_source_location { 68 const char *filename; 69 int line_no; 70 int column_no; 71 }; 72 73 struct __asan_global { 74 const void *beg; /* address of the global variable */ 75 size_t size; /* size of the global variable */ 76 size_t size_with_redzone; /* size with the redzone */ 77 const void *name; /* name of the variable */ 78 const void *module_name; /* name of the module where the var is declared */ 79 unsigned long has_dynamic_init; /* the var has dyn initializer (c++) */ 80 struct __asan_global_source_location *location; 81 #if ASAN_ABI_VERSION >= 7 82 uintptr_t odr_indicator; /* the address of the ODR indicator symbol */ 83 #endif 84 }; 85 86 FEATURE(kasan, "Kernel address sanitizer"); 87 88 static SYSCTL_NODE(_debug, OID_AUTO, kasan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 89 "KASAN options"); 90 91 static int panic_on_violation = 1; 92 SYSCTL_INT(_debug_kasan, OID_AUTO, panic_on_violation, CTLFLAG_RDTUN, 93 &panic_on_violation, 0, 94 "Panic if an invalid access is detected"); 95 96 static bool kasan_enabled __read_mostly = false; 97 98 /* -------------------------------------------------------------------------- */ 99 100 void 101 kasan_shadow_map(vm_offset_t addr, size_t size) 102 { 103 size_t sz, npages, i; 104 vm_offset_t sva, eva; 105 106 KASSERT(addr % KASAN_SHADOW_SCALE == 0, 107 ("%s: invalid address %#lx", __func__, addr)); 108 109 sz = roundup(size, KASAN_SHADOW_SCALE) / KASAN_SHADOW_SCALE; 110 111 sva = kasan_md_addr_to_shad(addr); 112 eva = kasan_md_addr_to_shad(addr) + sz; 113 114 sva = rounddown(sva, PAGE_SIZE); 115 eva = roundup(eva, PAGE_SIZE); 116 117 npages = (eva - sva) / PAGE_SIZE; 118 119 KASSERT(sva >= KASAN_MIN_ADDRESS && eva < KASAN_MAX_ADDRESS, 120 ("%s: invalid address range %#lx-%#lx", __func__, sva, eva)); 121 122 for (i = 0; i < npages; i++) 123 pmap_san_enter(sva + ptoa(i)); 124 } 125 126 void 127 kasan_init(void) 128 { 129 int disabled; 130 131 disabled = 0; 132 TUNABLE_INT_FETCH("debug.kasan.disabled", &disabled); 133 if (disabled) 134 return; 135 136 /* MD initialization. */ 137 kasan_md_init(); 138 139 /* Now officially enabled. */ 140 kasan_enabled = true; 141 } 142 143 void 144 kasan_init_early(vm_offset_t stack, size_t size) 145 { 146 kasan_md_init_early(stack, size); 147 } 148 149 static inline const char * 150 kasan_code_name(uint8_t code) 151 { 152 switch (code) { 153 case KASAN_GENERIC_REDZONE: 154 return "GenericRedZone"; 155 case KASAN_MALLOC_REDZONE: 156 return "MallocRedZone"; 157 case KASAN_KMEM_REDZONE: 158 return "KmemRedZone"; 159 case KASAN_UMA_FREED: 160 return "UMAUseAfterFree"; 161 case KASAN_KSTACK_FREED: 162 return "KernelStack"; 163 case KASAN_EXEC_ARGS_FREED: 164 return "ExecKVA"; 165 case 1 ... 7: 166 return "RedZonePartial"; 167 case KASAN_STACK_LEFT: 168 return "StackLeft"; 169 case KASAN_STACK_MID: 170 return "StackMiddle"; 171 case KASAN_STACK_RIGHT: 172 return "StackRight"; 173 case KASAN_USE_AFTER_RET: 174 return "UseAfterRet"; 175 case KASAN_USE_AFTER_SCOPE: 176 return "UseAfterScope"; 177 default: 178 return "Unknown"; 179 } 180 } 181 182 #define REPORT(f, ...) do { \ 183 if (panic_on_violation) { \ 184 kasan_enabled = false; \ 185 panic(f, __VA_ARGS__); \ 186 } else { \ 187 struct stack st; \ 188 \ 189 stack_save(&st); \ 190 printf(f "\n", __VA_ARGS__); \ 191 stack_print_ddb(&st); \ 192 } \ 193 } while (0) 194 195 static void 196 kasan_report(unsigned long addr, size_t size, bool write, unsigned long pc, 197 uint8_t code) 198 { 199 REPORT("ASan: Invalid access, %zu-byte %s at %#lx, %s(%x)", 200 size, (write ? "write" : "read"), addr, kasan_code_name(code), 201 code); 202 } 203 204 static __always_inline void 205 kasan_shadow_1byte_markvalid(unsigned long addr) 206 { 207 int8_t *byte = (int8_t *)kasan_md_addr_to_shad(addr); 208 int8_t last = (addr & KASAN_SHADOW_MASK) + 1; 209 210 *byte = last; 211 } 212 213 static __always_inline void 214 kasan_shadow_Nbyte_markvalid(const void *addr, size_t size) 215 { 216 size_t i; 217 218 for (i = 0; i < size; i++) { 219 kasan_shadow_1byte_markvalid((unsigned long)addr + i); 220 } 221 } 222 223 static __always_inline void 224 kasan_shadow_Nbyte_fill(const void *addr, size_t size, uint8_t code) 225 { 226 void *shad; 227 228 if (__predict_false(size == 0)) 229 return; 230 if (__predict_false(kasan_md_unsupported((vm_offset_t)addr))) 231 return; 232 233 KASSERT((vm_offset_t)addr % KASAN_SHADOW_SCALE == 0, 234 ("%s: invalid address %p", __func__, addr)); 235 KASSERT(size % KASAN_SHADOW_SCALE == 0, 236 ("%s: invalid size %zu", __func__, size)); 237 238 shad = (void *)kasan_md_addr_to_shad((uintptr_t)addr); 239 size = size >> KASAN_SHADOW_SCALE_SHIFT; 240 241 __builtin_memset(shad, code, size); 242 } 243 244 /* 245 * In an area of size 'sz_with_redz', mark the 'size' first bytes as valid, 246 * and the rest as invalid. There are generally two use cases: 247 * 248 * o kasan_mark(addr, origsize, size, code), with origsize < size. This marks 249 * the redzone at the end of the buffer as invalid. If the entire is to be 250 * marked invalid, origsize will be 0. 251 * 252 * o kasan_mark(addr, size, size, 0). This marks the entire buffer as valid. 253 */ 254 void 255 kasan_mark(const void *addr, size_t size, size_t redzsize, uint8_t code) 256 { 257 size_t i, n, redz; 258 int8_t *shad; 259 260 if ((vm_offset_t)addr >= DMAP_MIN_ADDRESS && 261 (vm_offset_t)addr < DMAP_MAX_ADDRESS) 262 return; 263 264 KASSERT((vm_offset_t)addr >= VM_MIN_KERNEL_ADDRESS && 265 (vm_offset_t)addr < VM_MAX_KERNEL_ADDRESS, 266 ("%s: invalid address %p", __func__, addr)); 267 KASSERT((vm_offset_t)addr % KASAN_SHADOW_SCALE == 0, 268 ("%s: invalid address %p", __func__, addr)); 269 redz = redzsize - roundup(size, KASAN_SHADOW_SCALE); 270 KASSERT(redz % KASAN_SHADOW_SCALE == 0, 271 ("%s: invalid size %zu", __func__, redz)); 272 shad = (int8_t *)kasan_md_addr_to_shad((uintptr_t)addr); 273 274 /* Chunks of 8 bytes, valid. */ 275 n = size / KASAN_SHADOW_SCALE; 276 for (i = 0; i < n; i++) { 277 *shad++ = 0; 278 } 279 280 /* Possibly one chunk, mid. */ 281 if ((size & KASAN_SHADOW_MASK) != 0) { 282 *shad++ = (size & KASAN_SHADOW_MASK); 283 } 284 285 /* Chunks of 8 bytes, invalid. */ 286 n = redz / KASAN_SHADOW_SCALE; 287 for (i = 0; i < n; i++) { 288 *shad++ = code; 289 } 290 } 291 292 /* -------------------------------------------------------------------------- */ 293 294 #define ADDR_CROSSES_SCALE_BOUNDARY(addr, size) \ 295 (addr >> KASAN_SHADOW_SCALE_SHIFT) != \ 296 ((addr + size - 1) >> KASAN_SHADOW_SCALE_SHIFT) 297 298 static __always_inline bool 299 kasan_shadow_1byte_isvalid(unsigned long addr, uint8_t *code) 300 { 301 int8_t *byte = (int8_t *)kasan_md_addr_to_shad(addr); 302 int8_t last = (addr & KASAN_SHADOW_MASK) + 1; 303 304 if (__predict_true(*byte == 0 || last <= *byte)) { 305 return (true); 306 } 307 *code = *byte; 308 return (false); 309 } 310 311 static __always_inline bool 312 kasan_shadow_2byte_isvalid(unsigned long addr, uint8_t *code) 313 { 314 int8_t *byte, last; 315 316 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 2)) { 317 return (kasan_shadow_1byte_isvalid(addr, code) && 318 kasan_shadow_1byte_isvalid(addr+1, code)); 319 } 320 321 byte = (int8_t *)kasan_md_addr_to_shad(addr); 322 last = ((addr + 1) & KASAN_SHADOW_MASK) + 1; 323 324 if (__predict_true(*byte == 0 || last <= *byte)) { 325 return (true); 326 } 327 *code = *byte; 328 return (false); 329 } 330 331 static __always_inline bool 332 kasan_shadow_4byte_isvalid(unsigned long addr, uint8_t *code) 333 { 334 int8_t *byte, last; 335 336 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 4)) { 337 return (kasan_shadow_2byte_isvalid(addr, code) && 338 kasan_shadow_2byte_isvalid(addr+2, code)); 339 } 340 341 byte = (int8_t *)kasan_md_addr_to_shad(addr); 342 last = ((addr + 3) & KASAN_SHADOW_MASK) + 1; 343 344 if (__predict_true(*byte == 0 || last <= *byte)) { 345 return (true); 346 } 347 *code = *byte; 348 return (false); 349 } 350 351 static __always_inline bool 352 kasan_shadow_8byte_isvalid(unsigned long addr, uint8_t *code) 353 { 354 int8_t *byte, last; 355 356 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 8)) { 357 return (kasan_shadow_4byte_isvalid(addr, code) && 358 kasan_shadow_4byte_isvalid(addr+4, code)); 359 } 360 361 byte = (int8_t *)kasan_md_addr_to_shad(addr); 362 last = ((addr + 7) & KASAN_SHADOW_MASK) + 1; 363 364 if (__predict_true(*byte == 0 || last <= *byte)) { 365 return (true); 366 } 367 *code = *byte; 368 return (false); 369 } 370 371 static __always_inline bool 372 kasan_shadow_Nbyte_isvalid(unsigned long addr, size_t size, uint8_t *code) 373 { 374 size_t i; 375 376 for (i = 0; i < size; i++) { 377 if (!kasan_shadow_1byte_isvalid(addr+i, code)) 378 return (false); 379 } 380 381 return (true); 382 } 383 384 static __always_inline void 385 kasan_shadow_check(unsigned long addr, size_t size, bool write, 386 unsigned long retaddr) 387 { 388 uint8_t code; 389 bool valid; 390 391 if (__predict_false(!kasan_enabled)) 392 return; 393 if (__predict_false(size == 0)) 394 return; 395 if (__predict_false(kasan_md_unsupported(addr))) 396 return; 397 if (KERNEL_PANICKED()) 398 return; 399 400 if (__builtin_constant_p(size)) { 401 switch (size) { 402 case 1: 403 valid = kasan_shadow_1byte_isvalid(addr, &code); 404 break; 405 case 2: 406 valid = kasan_shadow_2byte_isvalid(addr, &code); 407 break; 408 case 4: 409 valid = kasan_shadow_4byte_isvalid(addr, &code); 410 break; 411 case 8: 412 valid = kasan_shadow_8byte_isvalid(addr, &code); 413 break; 414 default: 415 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 416 break; 417 } 418 } else { 419 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 420 } 421 422 if (__predict_false(!valid)) { 423 kasan_report(addr, size, write, retaddr, code); 424 } 425 } 426 427 /* -------------------------------------------------------------------------- */ 428 429 void * 430 kasan_memcpy(void *dst, const void *src, size_t len) 431 { 432 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 433 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 434 return (__builtin_memcpy(dst, src, len)); 435 } 436 437 int 438 kasan_memcmp(const void *b1, const void *b2, size_t len) 439 { 440 kasan_shadow_check((unsigned long)b1, len, false, __RET_ADDR); 441 kasan_shadow_check((unsigned long)b2, len, false, __RET_ADDR); 442 return (__builtin_memcmp(b1, b2, len)); 443 } 444 445 void * 446 kasan_memset(void *b, int c, size_t len) 447 { 448 kasan_shadow_check((unsigned long)b, len, true, __RET_ADDR); 449 return (__builtin_memset(b, c, len)); 450 } 451 452 void * 453 kasan_memmove(void *dst, const void *src, size_t len) 454 { 455 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 456 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 457 return (__builtin_memmove(dst, src, len)); 458 } 459 460 size_t 461 kasan_strlen(const char *str) 462 { 463 const char *s; 464 465 s = str; 466 while (1) { 467 kasan_shadow_check((unsigned long)s, 1, false, __RET_ADDR); 468 if (*s == '\0') 469 break; 470 s++; 471 } 472 473 return (s - str); 474 } 475 476 char * 477 kasan_strcpy(char *dst, const char *src) 478 { 479 char *save = dst; 480 481 while (1) { 482 kasan_shadow_check((unsigned long)src, 1, false, __RET_ADDR); 483 kasan_shadow_check((unsigned long)dst, 1, true, __RET_ADDR); 484 *dst = *src; 485 if (*src == '\0') 486 break; 487 src++, dst++; 488 } 489 490 return save; 491 } 492 493 int 494 kasan_strcmp(const char *s1, const char *s2) 495 { 496 while (1) { 497 kasan_shadow_check((unsigned long)s1, 1, false, __RET_ADDR); 498 kasan_shadow_check((unsigned long)s2, 1, false, __RET_ADDR); 499 if (*s1 != *s2) 500 break; 501 if (*s1 == '\0') 502 return 0; 503 s1++, s2++; 504 } 505 506 return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 507 } 508 509 int 510 kasan_copyin(const void *uaddr, void *kaddr, size_t len) 511 { 512 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 513 return (copyin(uaddr, kaddr, len)); 514 } 515 516 int 517 kasan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 518 { 519 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 520 return (copyinstr(uaddr, kaddr, len, done)); 521 } 522 523 int 524 kasan_copyout(const void *kaddr, void *uaddr, size_t len) 525 { 526 kasan_shadow_check((unsigned long)kaddr, len, false, __RET_ADDR); 527 return (copyout(kaddr, uaddr, len)); 528 } 529 530 /* -------------------------------------------------------------------------- */ 531 532 int 533 kasan_fubyte(volatile const void *base) 534 { 535 return (fubyte(base)); 536 } 537 538 int 539 kasan_fuword16(volatile const void *base) 540 { 541 return (fuword16(base)); 542 } 543 544 int 545 kasan_fueword(volatile const void *base, long *val) 546 { 547 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 548 return (fueword(base, val)); 549 } 550 551 int 552 kasan_fueword32(volatile const void *base, int32_t *val) 553 { 554 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 555 return (fueword32(base, val)); 556 } 557 558 int 559 kasan_fueword64(volatile const void *base, int64_t *val) 560 { 561 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 562 return (fueword64(base, val)); 563 } 564 565 int 566 kasan_subyte(volatile void *base, int byte) 567 { 568 return (subyte(base, byte)); 569 } 570 571 int 572 kasan_suword(volatile void *base, long word) 573 { 574 return (suword(base, word)); 575 } 576 577 int 578 kasan_suword16(volatile void *base, int word) 579 { 580 return (suword16(base, word)); 581 } 582 583 int 584 kasan_suword32(volatile void *base, int32_t word) 585 { 586 return (suword32(base, word)); 587 } 588 589 int 590 kasan_suword64(volatile void *base, int64_t word) 591 { 592 return (suword64(base, word)); 593 } 594 595 int 596 kasan_casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp, 597 uint32_t newval) 598 { 599 kasan_shadow_check((unsigned long)oldvalp, sizeof(*oldvalp), true, 600 __RET_ADDR); 601 return (casueword32(base, oldval, oldvalp, newval)); 602 } 603 604 int 605 kasan_casueword(volatile u_long *base, u_long oldval, u_long *oldvalp, 606 u_long newval) 607 { 608 kasan_shadow_check((unsigned long)oldvalp, sizeof(*oldvalp), true, 609 __RET_ADDR); 610 return (casueword(base, oldval, oldvalp, newval)); 611 } 612 613 /* -------------------------------------------------------------------------- */ 614 615 #include <machine/atomic.h> 616 #include <sys/atomic_san.h> 617 618 #define _ASAN_ATOMIC_FUNC_ADD(name, type) \ 619 void kasan_atomic_add_##name(volatile type *ptr, type val) \ 620 { \ 621 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 622 __RET_ADDR); \ 623 atomic_add_##name(ptr, val); \ 624 } 625 626 #define ASAN_ATOMIC_FUNC_ADD(name, type) \ 627 _ASAN_ATOMIC_FUNC_ADD(name, type) \ 628 _ASAN_ATOMIC_FUNC_ADD(acq_##name, type) \ 629 _ASAN_ATOMIC_FUNC_ADD(rel_##name, type) 630 631 #define _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 632 void kasan_atomic_subtract_##name(volatile type *ptr, type val) \ 633 { \ 634 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 635 __RET_ADDR); \ 636 atomic_subtract_##name(ptr, val); \ 637 } 638 639 #define ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 640 _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 641 _ASAN_ATOMIC_FUNC_SUBTRACT(acq_##name, type) \ 642 _ASAN_ATOMIC_FUNC_SUBTRACT(rel_##name, type) 643 644 #define _ASAN_ATOMIC_FUNC_SET(name, type) \ 645 void kasan_atomic_set_##name(volatile type *ptr, type val) \ 646 { \ 647 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 648 __RET_ADDR); \ 649 atomic_set_##name(ptr, val); \ 650 } 651 652 #define ASAN_ATOMIC_FUNC_SET(name, type) \ 653 _ASAN_ATOMIC_FUNC_SET(name, type) \ 654 _ASAN_ATOMIC_FUNC_SET(acq_##name, type) \ 655 _ASAN_ATOMIC_FUNC_SET(rel_##name, type) 656 657 #define _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 658 void kasan_atomic_clear_##name(volatile type *ptr, type val) \ 659 { \ 660 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 661 __RET_ADDR); \ 662 atomic_clear_##name(ptr, val); \ 663 } 664 665 #define ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 666 _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 667 _ASAN_ATOMIC_FUNC_CLEAR(acq_##name, type) \ 668 _ASAN_ATOMIC_FUNC_CLEAR(rel_##name, type) 669 670 #define ASAN_ATOMIC_FUNC_FETCHADD(name, type) \ 671 type kasan_atomic_fetchadd_##name(volatile type *ptr, type val) \ 672 { \ 673 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 674 __RET_ADDR); \ 675 return (atomic_fetchadd_##name(ptr, val)); \ 676 } 677 678 #define ASAN_ATOMIC_FUNC_READANDCLEAR(name, type) \ 679 type kasan_atomic_readandclear_##name(volatile type *ptr) \ 680 { \ 681 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 682 __RET_ADDR); \ 683 return (atomic_readandclear_##name(ptr)); \ 684 } 685 686 #define ASAN_ATOMIC_FUNC_TESTANDCLEAR(name, type) \ 687 int kasan_atomic_testandclear_##name(volatile type *ptr, u_int v) \ 688 { \ 689 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 690 __RET_ADDR); \ 691 return (atomic_testandclear_##name(ptr, v)); \ 692 } 693 694 #define ASAN_ATOMIC_FUNC_TESTANDSET(name, type) \ 695 int kasan_atomic_testandset_##name(volatile type *ptr, u_int v) \ 696 { \ 697 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 698 __RET_ADDR); \ 699 return (atomic_testandset_##name(ptr, v)); \ 700 } 701 702 #define ASAN_ATOMIC_FUNC_SWAP(name, type) \ 703 type kasan_atomic_swap_##name(volatile type *ptr, type val) \ 704 { \ 705 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 706 __RET_ADDR); \ 707 return (atomic_swap_##name(ptr, val)); \ 708 } 709 710 #define _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 711 int kasan_atomic_cmpset_##name(volatile type *ptr, type oval, \ 712 type nval) \ 713 { \ 714 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 715 __RET_ADDR); \ 716 return (atomic_cmpset_##name(ptr, oval, nval)); \ 717 } 718 719 #define ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 720 _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 721 _ASAN_ATOMIC_FUNC_CMPSET(acq_##name, type) \ 722 _ASAN_ATOMIC_FUNC_CMPSET(rel_##name, type) 723 724 #define _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 725 int kasan_atomic_fcmpset_##name(volatile type *ptr, type *oval, \ 726 type nval) \ 727 { \ 728 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 729 __RET_ADDR); \ 730 return (atomic_fcmpset_##name(ptr, oval, nval)); \ 731 } 732 733 #define ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 734 _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 735 _ASAN_ATOMIC_FUNC_FCMPSET(acq_##name, type) \ 736 _ASAN_ATOMIC_FUNC_FCMPSET(rel_##name, type) 737 738 #define ASAN_ATOMIC_FUNC_THREAD_FENCE(name) \ 739 void kasan_atomic_thread_fence_##name(void) \ 740 { \ 741 atomic_thread_fence_##name(); \ 742 } 743 744 #define _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 745 type kasan_atomic_load_##name(volatile type *ptr) \ 746 { \ 747 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 748 __RET_ADDR); \ 749 return (atomic_load_##name(ptr)); \ 750 } 751 752 #define ASAN_ATOMIC_FUNC_LOAD(name, type) \ 753 _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 754 _ASAN_ATOMIC_FUNC_LOAD(acq_##name, type) 755 756 #define _ASAN_ATOMIC_FUNC_STORE(name, type) \ 757 void kasan_atomic_store_##name(volatile type *ptr, type val) \ 758 { \ 759 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 760 __RET_ADDR); \ 761 atomic_store_##name(ptr, val); \ 762 } 763 764 #define ASAN_ATOMIC_FUNC_STORE(name, type) \ 765 _ASAN_ATOMIC_FUNC_STORE(name, type) \ 766 _ASAN_ATOMIC_FUNC_STORE(rel_##name, type) 767 768 ASAN_ATOMIC_FUNC_ADD(8, uint8_t); 769 ASAN_ATOMIC_FUNC_ADD(16, uint16_t); 770 ASAN_ATOMIC_FUNC_ADD(32, uint32_t); 771 ASAN_ATOMIC_FUNC_ADD(64, uint64_t); 772 ASAN_ATOMIC_FUNC_ADD(int, u_int); 773 ASAN_ATOMIC_FUNC_ADD(long, u_long); 774 ASAN_ATOMIC_FUNC_ADD(ptr, uintptr_t); 775 776 ASAN_ATOMIC_FUNC_SUBTRACT(8, uint8_t); 777 ASAN_ATOMIC_FUNC_SUBTRACT(16, uint16_t); 778 ASAN_ATOMIC_FUNC_SUBTRACT(32, uint32_t); 779 ASAN_ATOMIC_FUNC_SUBTRACT(64, uint64_t); 780 ASAN_ATOMIC_FUNC_SUBTRACT(int, u_int); 781 ASAN_ATOMIC_FUNC_SUBTRACT(long, u_long); 782 ASAN_ATOMIC_FUNC_SUBTRACT(ptr, uintptr_t); 783 784 ASAN_ATOMIC_FUNC_SET(8, uint8_t); 785 ASAN_ATOMIC_FUNC_SET(16, uint16_t); 786 ASAN_ATOMIC_FUNC_SET(32, uint32_t); 787 ASAN_ATOMIC_FUNC_SET(64, uint64_t); 788 ASAN_ATOMIC_FUNC_SET(int, u_int); 789 ASAN_ATOMIC_FUNC_SET(long, u_long); 790 ASAN_ATOMIC_FUNC_SET(ptr, uintptr_t); 791 792 ASAN_ATOMIC_FUNC_CLEAR(8, uint8_t); 793 ASAN_ATOMIC_FUNC_CLEAR(16, uint16_t); 794 ASAN_ATOMIC_FUNC_CLEAR(32, uint32_t); 795 ASAN_ATOMIC_FUNC_CLEAR(64, uint64_t); 796 ASAN_ATOMIC_FUNC_CLEAR(int, u_int); 797 ASAN_ATOMIC_FUNC_CLEAR(long, u_long); 798 ASAN_ATOMIC_FUNC_CLEAR(ptr, uintptr_t); 799 800 ASAN_ATOMIC_FUNC_FETCHADD(32, uint32_t); 801 ASAN_ATOMIC_FUNC_FETCHADD(64, uint64_t); 802 ASAN_ATOMIC_FUNC_FETCHADD(int, u_int); 803 ASAN_ATOMIC_FUNC_FETCHADD(long, u_long); 804 805 ASAN_ATOMIC_FUNC_READANDCLEAR(32, uint32_t); 806 ASAN_ATOMIC_FUNC_READANDCLEAR(64, uint64_t); 807 ASAN_ATOMIC_FUNC_READANDCLEAR(int, u_int); 808 ASAN_ATOMIC_FUNC_READANDCLEAR(long, u_long); 809 ASAN_ATOMIC_FUNC_READANDCLEAR(ptr, uintptr_t); 810 811 ASAN_ATOMIC_FUNC_TESTANDCLEAR(32, uint32_t); 812 ASAN_ATOMIC_FUNC_TESTANDCLEAR(64, uint64_t); 813 ASAN_ATOMIC_FUNC_TESTANDCLEAR(int, u_int); 814 ASAN_ATOMIC_FUNC_TESTANDCLEAR(long, u_long); 815 816 ASAN_ATOMIC_FUNC_TESTANDSET(32, uint32_t); 817 ASAN_ATOMIC_FUNC_TESTANDSET(64, uint64_t); 818 ASAN_ATOMIC_FUNC_TESTANDSET(int, u_int); 819 ASAN_ATOMIC_FUNC_TESTANDSET(long, u_long); 820 821 ASAN_ATOMIC_FUNC_SWAP(32, uint32_t); 822 ASAN_ATOMIC_FUNC_SWAP(64, uint64_t); 823 ASAN_ATOMIC_FUNC_SWAP(int, u_int); 824 ASAN_ATOMIC_FUNC_SWAP(long, u_long); 825 ASAN_ATOMIC_FUNC_SWAP(ptr, uintptr_t); 826 827 ASAN_ATOMIC_FUNC_CMPSET(8, uint8_t); 828 ASAN_ATOMIC_FUNC_CMPSET(16, uint16_t); 829 ASAN_ATOMIC_FUNC_CMPSET(32, uint32_t); 830 ASAN_ATOMIC_FUNC_CMPSET(64, uint64_t); 831 ASAN_ATOMIC_FUNC_CMPSET(int, u_int); 832 ASAN_ATOMIC_FUNC_CMPSET(long, u_long); 833 ASAN_ATOMIC_FUNC_CMPSET(ptr, uintptr_t); 834 835 ASAN_ATOMIC_FUNC_FCMPSET(8, uint8_t); 836 ASAN_ATOMIC_FUNC_FCMPSET(16, uint16_t); 837 ASAN_ATOMIC_FUNC_FCMPSET(32, uint32_t); 838 ASAN_ATOMIC_FUNC_FCMPSET(64, uint64_t); 839 ASAN_ATOMIC_FUNC_FCMPSET(int, u_int); 840 ASAN_ATOMIC_FUNC_FCMPSET(long, u_long); 841 ASAN_ATOMIC_FUNC_FCMPSET(ptr, uintptr_t); 842 843 ASAN_ATOMIC_FUNC_LOAD(8, uint8_t); 844 ASAN_ATOMIC_FUNC_LOAD(16, uint16_t); 845 ASAN_ATOMIC_FUNC_LOAD(32, uint32_t); 846 ASAN_ATOMIC_FUNC_LOAD(64, uint64_t); 847 ASAN_ATOMIC_FUNC_LOAD(char, u_char); 848 ASAN_ATOMIC_FUNC_LOAD(short, u_short); 849 ASAN_ATOMIC_FUNC_LOAD(int, u_int); 850 ASAN_ATOMIC_FUNC_LOAD(long, u_long); 851 ASAN_ATOMIC_FUNC_LOAD(ptr, uintptr_t); 852 853 ASAN_ATOMIC_FUNC_STORE(8, uint8_t); 854 ASAN_ATOMIC_FUNC_STORE(16, uint16_t); 855 ASAN_ATOMIC_FUNC_STORE(32, uint32_t); 856 ASAN_ATOMIC_FUNC_STORE(64, uint64_t); 857 ASAN_ATOMIC_FUNC_STORE(char, u_char); 858 ASAN_ATOMIC_FUNC_STORE(short, u_short); 859 ASAN_ATOMIC_FUNC_STORE(int, u_int); 860 ASAN_ATOMIC_FUNC_STORE(long, u_long); 861 ASAN_ATOMIC_FUNC_STORE(ptr, uintptr_t); 862 863 ASAN_ATOMIC_FUNC_THREAD_FENCE(acq); 864 ASAN_ATOMIC_FUNC_THREAD_FENCE(rel); 865 ASAN_ATOMIC_FUNC_THREAD_FENCE(acq_rel); 866 ASAN_ATOMIC_FUNC_THREAD_FENCE(seq_cst); 867 868 void 869 kasan_atomic_interrupt_fence(void) 870 { 871 } 872 873 /* -------------------------------------------------------------------------- */ 874 875 #include <sys/bus.h> 876 #include <machine/bus.h> 877 #include <sys/bus_san.h> 878 879 int 880 kasan_bus_space_map(bus_space_tag_t tag, bus_addr_t hnd, bus_size_t size, 881 int flags, bus_space_handle_t *handlep) 882 { 883 return (bus_space_map(tag, hnd, size, flags, handlep)); 884 } 885 886 void 887 kasan_bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t hnd, 888 bus_size_t size) 889 { 890 bus_space_unmap(tag, hnd, size); 891 } 892 893 int 894 kasan_bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t hnd, 895 bus_size_t offset, bus_size_t size, bus_space_handle_t *handlep) 896 { 897 return (bus_space_subregion(tag, hnd, offset, size, handlep)); 898 } 899 900 void 901 kasan_bus_space_free(bus_space_tag_t tag, bus_space_handle_t hnd, 902 bus_size_t size) 903 { 904 bus_space_free(tag, hnd, size); 905 } 906 907 void 908 kasan_bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t hnd, 909 bus_size_t offset, bus_size_t size, int flags) 910 { 911 bus_space_barrier(tag, hnd, offset, size, flags); 912 } 913 914 #define ASAN_BUS_READ_FUNC(func, width, type) \ 915 type kasan_bus_space_read##func##_##width(bus_space_tag_t tag, \ 916 bus_space_handle_t hnd, bus_size_t offset) \ 917 { \ 918 return (bus_space_read##func##_##width(tag, hnd, \ 919 offset)); \ 920 } \ 921 922 #define ASAN_BUS_READ_PTR_FUNC(func, width, type) \ 923 void kasan_bus_space_read_##func##_##width(bus_space_tag_t tag, \ 924 bus_space_handle_t hnd, bus_size_t size, type *buf, \ 925 bus_size_t count) \ 926 { \ 927 kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 928 false, __RET_ADDR); \ 929 bus_space_read_##func##_##width(tag, hnd, size, buf, \ 930 count); \ 931 } 932 933 ASAN_BUS_READ_FUNC(, 1, uint8_t) 934 ASAN_BUS_READ_FUNC(_stream, 1, uint8_t) 935 ASAN_BUS_READ_PTR_FUNC(multi, 1, uint8_t) 936 ASAN_BUS_READ_PTR_FUNC(multi_stream, 1, uint8_t) 937 ASAN_BUS_READ_PTR_FUNC(region, 1, uint8_t) 938 ASAN_BUS_READ_PTR_FUNC(region_stream, 1, uint8_t) 939 940 ASAN_BUS_READ_FUNC(, 2, uint16_t) 941 ASAN_BUS_READ_FUNC(_stream, 2, uint16_t) 942 ASAN_BUS_READ_PTR_FUNC(multi, 2, uint16_t) 943 ASAN_BUS_READ_PTR_FUNC(multi_stream, 2, uint16_t) 944 ASAN_BUS_READ_PTR_FUNC(region, 2, uint16_t) 945 ASAN_BUS_READ_PTR_FUNC(region_stream, 2, uint16_t) 946 947 ASAN_BUS_READ_FUNC(, 4, uint32_t) 948 ASAN_BUS_READ_FUNC(_stream, 4, uint32_t) 949 ASAN_BUS_READ_PTR_FUNC(multi, 4, uint32_t) 950 ASAN_BUS_READ_PTR_FUNC(multi_stream, 4, uint32_t) 951 ASAN_BUS_READ_PTR_FUNC(region, 4, uint32_t) 952 ASAN_BUS_READ_PTR_FUNC(region_stream, 4, uint32_t) 953 954 ASAN_BUS_READ_FUNC(, 8, uint64_t) 955 956 #define ASAN_BUS_WRITE_FUNC(func, width, type) \ 957 void kasan_bus_space_write##func##_##width(bus_space_tag_t tag, \ 958 bus_space_handle_t hnd, bus_size_t offset, type value) \ 959 { \ 960 bus_space_write##func##_##width(tag, hnd, offset, value);\ 961 } \ 962 963 #define ASAN_BUS_WRITE_PTR_FUNC(func, width, type) \ 964 void kasan_bus_space_write_##func##_##width(bus_space_tag_t tag,\ 965 bus_space_handle_t hnd, bus_size_t size, const type *buf, \ 966 bus_size_t count) \ 967 { \ 968 kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 969 true, __RET_ADDR); \ 970 bus_space_write_##func##_##width(tag, hnd, size, buf, \ 971 count); \ 972 } 973 974 ASAN_BUS_WRITE_FUNC(, 1, uint8_t) 975 ASAN_BUS_WRITE_FUNC(_stream, 1, uint8_t) 976 ASAN_BUS_WRITE_PTR_FUNC(multi, 1, uint8_t) 977 ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 1, uint8_t) 978 ASAN_BUS_WRITE_PTR_FUNC(region, 1, uint8_t) 979 ASAN_BUS_WRITE_PTR_FUNC(region_stream, 1, uint8_t) 980 981 ASAN_BUS_WRITE_FUNC(, 2, uint16_t) 982 ASAN_BUS_WRITE_FUNC(_stream, 2, uint16_t) 983 ASAN_BUS_WRITE_PTR_FUNC(multi, 2, uint16_t) 984 ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 2, uint16_t) 985 ASAN_BUS_WRITE_PTR_FUNC(region, 2, uint16_t) 986 ASAN_BUS_WRITE_PTR_FUNC(region_stream, 2, uint16_t) 987 988 ASAN_BUS_WRITE_FUNC(, 4, uint32_t) 989 ASAN_BUS_WRITE_FUNC(_stream, 4, uint32_t) 990 ASAN_BUS_WRITE_PTR_FUNC(multi, 4, uint32_t) 991 ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 4, uint32_t) 992 ASAN_BUS_WRITE_PTR_FUNC(region, 4, uint32_t) 993 ASAN_BUS_WRITE_PTR_FUNC(region_stream, 4, uint32_t) 994 995 ASAN_BUS_WRITE_FUNC(, 8, uint64_t) 996 997 #define ASAN_BUS_SET_FUNC(func, width, type) \ 998 void kasan_bus_space_set_##func##_##width(bus_space_tag_t tag, \ 999 bus_space_handle_t hnd, bus_size_t offset, type value, \ 1000 bus_size_t count) \ 1001 { \ 1002 bus_space_set_##func##_##width(tag, hnd, offset, value, \ 1003 count); \ 1004 } 1005 1006 ASAN_BUS_SET_FUNC(multi, 1, uint8_t) 1007 ASAN_BUS_SET_FUNC(region, 1, uint8_t) 1008 ASAN_BUS_SET_FUNC(multi_stream, 1, uint8_t) 1009 ASAN_BUS_SET_FUNC(region_stream, 1, uint8_t) 1010 1011 ASAN_BUS_SET_FUNC(multi, 2, uint16_t) 1012 ASAN_BUS_SET_FUNC(region, 2, uint16_t) 1013 ASAN_BUS_SET_FUNC(multi_stream, 2, uint16_t) 1014 ASAN_BUS_SET_FUNC(region_stream, 2, uint16_t) 1015 1016 ASAN_BUS_SET_FUNC(multi, 4, uint32_t) 1017 ASAN_BUS_SET_FUNC(region, 4, uint32_t) 1018 ASAN_BUS_SET_FUNC(multi_stream, 4, uint32_t) 1019 ASAN_BUS_SET_FUNC(region_stream, 4, uint32_t) 1020 1021 #define ASAN_BUS_PEEK_FUNC(width, type) \ 1022 int kasan_bus_space_peek_##width(bus_space_tag_t tag, \ 1023 bus_space_handle_t hnd, bus_size_t offset, type *valuep) \ 1024 { \ 1025 return (bus_space_peek_##width(tag, hnd, offset, \ 1026 valuep)); \ 1027 } 1028 1029 ASAN_BUS_PEEK_FUNC(1, uint8_t) 1030 ASAN_BUS_PEEK_FUNC(2, uint16_t) 1031 ASAN_BUS_PEEK_FUNC(4, uint32_t) 1032 ASAN_BUS_PEEK_FUNC(8, uint64_t) 1033 1034 #define ASAN_BUS_POKE_FUNC(width, type) \ 1035 int kasan_bus_space_poke_##width(bus_space_tag_t tag, \ 1036 bus_space_handle_t hnd, bus_size_t offset, type value) \ 1037 { \ 1038 return (bus_space_poke_##width(tag, hnd, offset, \ 1039 value)); \ 1040 } 1041 1042 ASAN_BUS_POKE_FUNC(1, uint8_t) 1043 ASAN_BUS_POKE_FUNC(2, uint16_t) 1044 ASAN_BUS_POKE_FUNC(4, uint32_t) 1045 ASAN_BUS_POKE_FUNC(8, uint64_t) 1046 1047 /* -------------------------------------------------------------------------- */ 1048 1049 void __asan_register_globals(struct __asan_global *, size_t); 1050 void __asan_unregister_globals(struct __asan_global *, size_t); 1051 1052 void 1053 __asan_register_globals(struct __asan_global *globals, size_t n) 1054 { 1055 size_t i; 1056 1057 for (i = 0; i < n; i++) { 1058 kasan_mark(globals[i].beg, globals[i].size, 1059 globals[i].size_with_redzone, KASAN_GENERIC_REDZONE); 1060 } 1061 } 1062 1063 void 1064 __asan_unregister_globals(struct __asan_global *globals, size_t n) 1065 { 1066 size_t i; 1067 1068 for (i = 0; i < n; i++) { 1069 kasan_mark(globals[i].beg, globals[i].size_with_redzone, 1070 globals[i].size_with_redzone, 0); 1071 } 1072 } 1073 1074 #define ASAN_LOAD_STORE(size) \ 1075 void __asan_load##size(unsigned long); \ 1076 void __asan_load##size(unsigned long addr) \ 1077 { \ 1078 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1079 } \ 1080 void __asan_load##size##_noabort(unsigned long); \ 1081 void __asan_load##size##_noabort(unsigned long addr) \ 1082 { \ 1083 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1084 } \ 1085 void __asan_store##size(unsigned long); \ 1086 void __asan_store##size(unsigned long addr) \ 1087 { \ 1088 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1089 } \ 1090 void __asan_store##size##_noabort(unsigned long); \ 1091 void __asan_store##size##_noabort(unsigned long addr) \ 1092 { \ 1093 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1094 } 1095 1096 ASAN_LOAD_STORE(1); 1097 ASAN_LOAD_STORE(2); 1098 ASAN_LOAD_STORE(4); 1099 ASAN_LOAD_STORE(8); 1100 ASAN_LOAD_STORE(16); 1101 1102 void __asan_loadN(unsigned long, size_t); 1103 void __asan_loadN_noabort(unsigned long, size_t); 1104 void __asan_storeN(unsigned long, size_t); 1105 void __asan_storeN_noabort(unsigned long, size_t); 1106 void __asan_handle_no_return(void); 1107 1108 void 1109 __asan_loadN(unsigned long addr, size_t size) 1110 { 1111 kasan_shadow_check(addr, size, false, __RET_ADDR); 1112 } 1113 1114 void 1115 __asan_loadN_noabort(unsigned long addr, size_t size) 1116 { 1117 kasan_shadow_check(addr, size, false, __RET_ADDR); 1118 } 1119 1120 void 1121 __asan_storeN(unsigned long addr, size_t size) 1122 { 1123 kasan_shadow_check(addr, size, true, __RET_ADDR); 1124 } 1125 1126 void 1127 __asan_storeN_noabort(unsigned long addr, size_t size) 1128 { 1129 kasan_shadow_check(addr, size, true, __RET_ADDR); 1130 } 1131 1132 void 1133 __asan_handle_no_return(void) 1134 { 1135 /* nothing */ 1136 } 1137 1138 #define ASAN_SET_SHADOW(byte) \ 1139 void __asan_set_shadow_##byte(void *, size_t); \ 1140 void __asan_set_shadow_##byte(void *addr, size_t size) \ 1141 { \ 1142 __builtin_memset((void *)addr, 0x##byte, size); \ 1143 } 1144 1145 ASAN_SET_SHADOW(00); 1146 ASAN_SET_SHADOW(f1); 1147 ASAN_SET_SHADOW(f2); 1148 ASAN_SET_SHADOW(f3); 1149 ASAN_SET_SHADOW(f5); 1150 ASAN_SET_SHADOW(f8); 1151 1152 void __asan_poison_stack_memory(const void *, size_t); 1153 void __asan_unpoison_stack_memory(const void *, size_t); 1154 1155 void 1156 __asan_poison_stack_memory(const void *addr, size_t size) 1157 { 1158 size = roundup(size, KASAN_SHADOW_SCALE); 1159 kasan_shadow_Nbyte_fill(addr, size, KASAN_USE_AFTER_SCOPE); 1160 } 1161 1162 void 1163 __asan_unpoison_stack_memory(const void *addr, size_t size) 1164 { 1165 kasan_shadow_Nbyte_markvalid(addr, size); 1166 } 1167 1168 void __asan_alloca_poison(const void *, size_t); 1169 void __asan_allocas_unpoison(const void *, const void *); 1170 1171 void 1172 __asan_alloca_poison(const void *addr, size_t size) 1173 { 1174 const void *l, *r; 1175 1176 KASSERT((vm_offset_t)addr % KASAN_ALLOCA_SCALE_SIZE == 0, 1177 ("%s: invalid address %p", __func__, addr)); 1178 1179 l = (const uint8_t *)addr - KASAN_ALLOCA_SCALE_SIZE; 1180 r = (const uint8_t *)addr + roundup(size, KASAN_ALLOCA_SCALE_SIZE); 1181 1182 kasan_shadow_Nbyte_fill(l, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_LEFT); 1183 kasan_mark(addr, size, roundup(size, KASAN_ALLOCA_SCALE_SIZE), 1184 KASAN_STACK_MID); 1185 kasan_shadow_Nbyte_fill(r, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_RIGHT); 1186 } 1187 1188 void 1189 __asan_allocas_unpoison(const void *stkbegin, const void *stkend) 1190 { 1191 size_t size; 1192 1193 if (__predict_false(!stkbegin)) 1194 return; 1195 if (__predict_false((uintptr_t)stkbegin > (uintptr_t)stkend)) 1196 return; 1197 size = (uintptr_t)stkend - (uintptr_t)stkbegin; 1198 1199 kasan_shadow_Nbyte_fill(stkbegin, size, 0); 1200 } 1201 1202 void __asan_poison_memory_region(const void *addr, size_t size); 1203 void __asan_unpoison_memory_region(const void *addr, size_t size); 1204 1205 void 1206 __asan_poison_memory_region(const void *addr, size_t size) 1207 { 1208 } 1209 1210 void 1211 __asan_unpoison_memory_region(const void *addr, size_t size) 1212 { 1213 } 1214