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