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