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 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 ((vm_offset_t)addr >= DMAP_MIN_ADDRESS && 260 (vm_offset_t)addr < DMAP_MAX_ADDRESS) 261 return; 262 263 KASSERT((vm_offset_t)addr >= VM_MIN_KERNEL_ADDRESS && 264 (vm_offset_t)addr < VM_MAX_KERNEL_ADDRESS, 265 ("%s: invalid address %p", __func__, addr)); 266 KASSERT((vm_offset_t)addr % KASAN_SHADOW_SCALE == 0, 267 ("%s: invalid address %p", __func__, addr)); 268 redz = redzsize - roundup(size, KASAN_SHADOW_SCALE); 269 KASSERT(redz % KASAN_SHADOW_SCALE == 0, 270 ("%s: invalid size %zu", __func__, redz)); 271 shad = (int8_t *)kasan_md_addr_to_shad((uintptr_t)addr); 272 273 /* Chunks of 8 bytes, valid. */ 274 n = size / KASAN_SHADOW_SCALE; 275 for (i = 0; i < n; i++) { 276 *shad++ = 0; 277 } 278 279 /* Possibly one chunk, mid. */ 280 if ((size & KASAN_SHADOW_MASK) != 0) { 281 *shad++ = (size & KASAN_SHADOW_MASK); 282 } 283 284 /* Chunks of 8 bytes, invalid. */ 285 n = redz / KASAN_SHADOW_SCALE; 286 for (i = 0; i < n; i++) { 287 *shad++ = code; 288 } 289 } 290 291 /* -------------------------------------------------------------------------- */ 292 293 #define ADDR_CROSSES_SCALE_BOUNDARY(addr, size) \ 294 (addr >> KASAN_SHADOW_SCALE_SHIFT) != \ 295 ((addr + size - 1) >> KASAN_SHADOW_SCALE_SHIFT) 296 297 static __always_inline bool 298 kasan_shadow_1byte_isvalid(unsigned long addr, uint8_t *code) 299 { 300 int8_t *byte = (int8_t *)kasan_md_addr_to_shad(addr); 301 int8_t last = (addr & KASAN_SHADOW_MASK) + 1; 302 303 if (__predict_true(*byte == 0 || last <= *byte)) { 304 return (true); 305 } 306 *code = *byte; 307 return (false); 308 } 309 310 static __always_inline bool 311 kasan_shadow_2byte_isvalid(unsigned long addr, uint8_t *code) 312 { 313 int8_t *byte, last; 314 315 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 2)) { 316 return (kasan_shadow_1byte_isvalid(addr, code) && 317 kasan_shadow_1byte_isvalid(addr+1, code)); 318 } 319 320 byte = (int8_t *)kasan_md_addr_to_shad(addr); 321 last = ((addr + 1) & KASAN_SHADOW_MASK) + 1; 322 323 if (__predict_true(*byte == 0 || last <= *byte)) { 324 return (true); 325 } 326 *code = *byte; 327 return (false); 328 } 329 330 static __always_inline bool 331 kasan_shadow_4byte_isvalid(unsigned long addr, uint8_t *code) 332 { 333 int8_t *byte, last; 334 335 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 4)) { 336 return (kasan_shadow_2byte_isvalid(addr, code) && 337 kasan_shadow_2byte_isvalid(addr+2, code)); 338 } 339 340 byte = (int8_t *)kasan_md_addr_to_shad(addr); 341 last = ((addr + 3) & KASAN_SHADOW_MASK) + 1; 342 343 if (__predict_true(*byte == 0 || last <= *byte)) { 344 return (true); 345 } 346 *code = *byte; 347 return (false); 348 } 349 350 static __always_inline bool 351 kasan_shadow_8byte_isvalid(unsigned long addr, uint8_t *code) 352 { 353 int8_t *byte, last; 354 355 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 8)) { 356 return (kasan_shadow_4byte_isvalid(addr, code) && 357 kasan_shadow_4byte_isvalid(addr+4, code)); 358 } 359 360 byte = (int8_t *)kasan_md_addr_to_shad(addr); 361 last = ((addr + 7) & KASAN_SHADOW_MASK) + 1; 362 363 if (__predict_true(*byte == 0 || last <= *byte)) { 364 return (true); 365 } 366 *code = *byte; 367 return (false); 368 } 369 370 static __always_inline bool 371 kasan_shadow_Nbyte_isvalid(unsigned long addr, size_t size, uint8_t *code) 372 { 373 size_t i; 374 375 for (i = 0; i < size; i++) { 376 if (!kasan_shadow_1byte_isvalid(addr+i, code)) 377 return (false); 378 } 379 380 return (true); 381 } 382 383 static __always_inline void 384 kasan_shadow_check(unsigned long addr, size_t size, bool write, 385 unsigned long retaddr) 386 { 387 uint8_t code; 388 bool valid; 389 390 if (__predict_false(!kasan_enabled)) 391 return; 392 if (__predict_false(size == 0)) 393 return; 394 if (__predict_false(kasan_md_unsupported(addr))) 395 return; 396 if (KERNEL_PANICKED()) 397 return; 398 399 if (__builtin_constant_p(size)) { 400 switch (size) { 401 case 1: 402 valid = kasan_shadow_1byte_isvalid(addr, &code); 403 break; 404 case 2: 405 valid = kasan_shadow_2byte_isvalid(addr, &code); 406 break; 407 case 4: 408 valid = kasan_shadow_4byte_isvalid(addr, &code); 409 break; 410 case 8: 411 valid = kasan_shadow_8byte_isvalid(addr, &code); 412 break; 413 default: 414 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 415 break; 416 } 417 } else { 418 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 419 } 420 421 if (__predict_false(!valid)) { 422 kasan_report(addr, size, write, retaddr, code); 423 } 424 } 425 426 /* -------------------------------------------------------------------------- */ 427 428 void * 429 kasan_memcpy(void *dst, const void *src, size_t len) 430 { 431 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 432 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 433 return (__builtin_memcpy(dst, src, len)); 434 } 435 436 int 437 kasan_memcmp(const void *b1, const void *b2, size_t len) 438 { 439 kasan_shadow_check((unsigned long)b1, len, false, __RET_ADDR); 440 kasan_shadow_check((unsigned long)b2, len, false, __RET_ADDR); 441 return (__builtin_memcmp(b1, b2, len)); 442 } 443 444 void * 445 kasan_memset(void *b, int c, size_t len) 446 { 447 kasan_shadow_check((unsigned long)b, len, true, __RET_ADDR); 448 return (__builtin_memset(b, c, len)); 449 } 450 451 void * 452 kasan_memmove(void *dst, const void *src, size_t len) 453 { 454 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 455 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 456 return (__builtin_memmove(dst, src, len)); 457 } 458 459 size_t 460 kasan_strlen(const char *str) 461 { 462 const char *s; 463 464 s = str; 465 while (1) { 466 kasan_shadow_check((unsigned long)s, 1, false, __RET_ADDR); 467 if (*s == '\0') 468 break; 469 s++; 470 } 471 472 return (s - str); 473 } 474 475 char * 476 kasan_strcpy(char *dst, const char *src) 477 { 478 char *save = dst; 479 480 while (1) { 481 kasan_shadow_check((unsigned long)src, 1, false, __RET_ADDR); 482 kasan_shadow_check((unsigned long)dst, 1, true, __RET_ADDR); 483 *dst = *src; 484 if (*src == '\0') 485 break; 486 src++, dst++; 487 } 488 489 return save; 490 } 491 492 int 493 kasan_strcmp(const char *s1, const char *s2) 494 { 495 while (1) { 496 kasan_shadow_check((unsigned long)s1, 1, false, __RET_ADDR); 497 kasan_shadow_check((unsigned long)s2, 1, false, __RET_ADDR); 498 if (*s1 != *s2) 499 break; 500 if (*s1 == '\0') 501 return 0; 502 s1++, s2++; 503 } 504 505 return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 506 } 507 508 int 509 kasan_copyin(const void *uaddr, void *kaddr, size_t len) 510 { 511 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 512 return (copyin(uaddr, kaddr, len)); 513 } 514 515 int 516 kasan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 517 { 518 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 519 return (copyinstr(uaddr, kaddr, len, done)); 520 } 521 522 int 523 kasan_copyout(const void *kaddr, void *uaddr, size_t len) 524 { 525 kasan_shadow_check((unsigned long)kaddr, len, false, __RET_ADDR); 526 return (copyout(kaddr, uaddr, len)); 527 } 528 529 /* -------------------------------------------------------------------------- */ 530 531 int 532 kasan_fubyte(volatile const void *base) 533 { 534 return (fubyte(base)); 535 } 536 537 int 538 kasan_fuword16(volatile const void *base) 539 { 540 return (fuword16(base)); 541 } 542 543 int 544 kasan_fueword(volatile const void *base, long *val) 545 { 546 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 547 return (fueword(base, val)); 548 } 549 550 int 551 kasan_fueword32(volatile const void *base, int32_t *val) 552 { 553 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 554 return (fueword32(base, val)); 555 } 556 557 int 558 kasan_fueword64(volatile const void *base, int64_t *val) 559 { 560 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 561 return (fueword64(base, val)); 562 } 563 564 int 565 kasan_subyte(volatile void *base, int byte) 566 { 567 return (subyte(base, byte)); 568 } 569 570 int 571 kasan_suword(volatile void *base, long word) 572 { 573 return (suword(base, word)); 574 } 575 576 int 577 kasan_suword16(volatile void *base, int word) 578 { 579 return (suword16(base, word)); 580 } 581 582 int 583 kasan_suword32(volatile void *base, int32_t word) 584 { 585 return (suword32(base, word)); 586 } 587 588 int 589 kasan_suword64(volatile void *base, int64_t word) 590 { 591 return (suword64(base, word)); 592 } 593 594 int 595 kasan_casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp, 596 uint32_t newval) 597 { 598 kasan_shadow_check((unsigned long)oldvalp, sizeof(*oldvalp), true, 599 __RET_ADDR); 600 return (casueword32(base, oldval, oldvalp, newval)); 601 } 602 603 int 604 kasan_casueword(volatile u_long *base, u_long oldval, u_long *oldvalp, 605 u_long newval) 606 { 607 kasan_shadow_check((unsigned long)oldvalp, sizeof(*oldvalp), true, 608 __RET_ADDR); 609 return (casueword(base, oldval, oldvalp, newval)); 610 } 611 612 /* -------------------------------------------------------------------------- */ 613 614 #include <machine/atomic.h> 615 #include <sys/atomic_san.h> 616 617 #define _ASAN_ATOMIC_FUNC_ADD(name, type) \ 618 void kasan_atomic_add_##name(volatile type *ptr, type val) \ 619 { \ 620 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 621 __RET_ADDR); \ 622 atomic_add_##name(ptr, val); \ 623 } 624 625 #define ASAN_ATOMIC_FUNC_ADD(name, type) \ 626 _ASAN_ATOMIC_FUNC_ADD(name, type) \ 627 _ASAN_ATOMIC_FUNC_ADD(acq_##name, type) \ 628 _ASAN_ATOMIC_FUNC_ADD(rel_##name, type) 629 630 #define _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 631 void kasan_atomic_subtract_##name(volatile type *ptr, type val) \ 632 { \ 633 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 634 __RET_ADDR); \ 635 atomic_subtract_##name(ptr, val); \ 636 } 637 638 #define ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 639 _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 640 _ASAN_ATOMIC_FUNC_SUBTRACT(acq_##name, type) \ 641 _ASAN_ATOMIC_FUNC_SUBTRACT(rel_##name, type) 642 643 #define _ASAN_ATOMIC_FUNC_SET(name, type) \ 644 void kasan_atomic_set_##name(volatile type *ptr, type val) \ 645 { \ 646 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 647 __RET_ADDR); \ 648 atomic_set_##name(ptr, val); \ 649 } 650 651 #define ASAN_ATOMIC_FUNC_SET(name, type) \ 652 _ASAN_ATOMIC_FUNC_SET(name, type) \ 653 _ASAN_ATOMIC_FUNC_SET(acq_##name, type) \ 654 _ASAN_ATOMIC_FUNC_SET(rel_##name, type) 655 656 #define _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 657 void kasan_atomic_clear_##name(volatile type *ptr, type val) \ 658 { \ 659 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 660 __RET_ADDR); \ 661 atomic_clear_##name(ptr, val); \ 662 } 663 664 #define ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 665 _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 666 _ASAN_ATOMIC_FUNC_CLEAR(acq_##name, type) \ 667 _ASAN_ATOMIC_FUNC_CLEAR(rel_##name, type) 668 669 #define ASAN_ATOMIC_FUNC_FETCHADD(name, type) \ 670 type kasan_atomic_fetchadd_##name(volatile type *ptr, type val) \ 671 { \ 672 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 673 __RET_ADDR); \ 674 return (atomic_fetchadd_##name(ptr, val)); \ 675 } 676 677 #define ASAN_ATOMIC_FUNC_READANDCLEAR(name, type) \ 678 type kasan_atomic_readandclear_##name(volatile type *ptr) \ 679 { \ 680 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 681 __RET_ADDR); \ 682 return (atomic_readandclear_##name(ptr)); \ 683 } 684 685 #define ASAN_ATOMIC_FUNC_TESTANDCLEAR(name, type) \ 686 int kasan_atomic_testandclear_##name(volatile type *ptr, u_int v) \ 687 { \ 688 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 689 __RET_ADDR); \ 690 return (atomic_testandclear_##name(ptr, v)); \ 691 } 692 693 #define ASAN_ATOMIC_FUNC_TESTANDSET(name, type) \ 694 int kasan_atomic_testandset_##name(volatile type *ptr, u_int v) \ 695 { \ 696 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 697 __RET_ADDR); \ 698 return (atomic_testandset_##name(ptr, v)); \ 699 } 700 701 #define ASAN_ATOMIC_FUNC_SWAP(name, type) \ 702 type kasan_atomic_swap_##name(volatile type *ptr, type val) \ 703 { \ 704 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 705 __RET_ADDR); \ 706 return (atomic_swap_##name(ptr, val)); \ 707 } 708 709 #define _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 710 int kasan_atomic_cmpset_##name(volatile type *ptr, type oval, \ 711 type nval) \ 712 { \ 713 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 714 __RET_ADDR); \ 715 return (atomic_cmpset_##name(ptr, oval, nval)); \ 716 } 717 718 #define ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 719 _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 720 _ASAN_ATOMIC_FUNC_CMPSET(acq_##name, type) \ 721 _ASAN_ATOMIC_FUNC_CMPSET(rel_##name, type) 722 723 #define _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 724 int kasan_atomic_fcmpset_##name(volatile type *ptr, type *oval, \ 725 type nval) \ 726 { \ 727 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 728 __RET_ADDR); \ 729 return (atomic_fcmpset_##name(ptr, oval, nval)); \ 730 } 731 732 #define ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 733 _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 734 _ASAN_ATOMIC_FUNC_FCMPSET(acq_##name, type) \ 735 _ASAN_ATOMIC_FUNC_FCMPSET(rel_##name, type) 736 737 #define ASAN_ATOMIC_FUNC_THREAD_FENCE(name) \ 738 void kasan_atomic_thread_fence_##name(void) \ 739 { \ 740 atomic_thread_fence_##name(); \ 741 } 742 743 #define _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 744 type kasan_atomic_load_##name(volatile type *ptr) \ 745 { \ 746 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 747 __RET_ADDR); \ 748 return (atomic_load_##name(ptr)); \ 749 } 750 751 #define ASAN_ATOMIC_FUNC_LOAD(name, type) \ 752 _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 753 _ASAN_ATOMIC_FUNC_LOAD(acq_##name, type) 754 755 #define _ASAN_ATOMIC_FUNC_STORE(name, type) \ 756 void kasan_atomic_store_##name(volatile type *ptr, type val) \ 757 { \ 758 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 759 __RET_ADDR); \ 760 atomic_store_##name(ptr, val); \ 761 } 762 763 #define ASAN_ATOMIC_FUNC_STORE(name, type) \ 764 _ASAN_ATOMIC_FUNC_STORE(name, type) \ 765 _ASAN_ATOMIC_FUNC_STORE(rel_##name, type) 766 767 ASAN_ATOMIC_FUNC_ADD(8, uint8_t); 768 ASAN_ATOMIC_FUNC_ADD(16, uint16_t); 769 ASAN_ATOMIC_FUNC_ADD(32, uint32_t); 770 ASAN_ATOMIC_FUNC_ADD(64, uint64_t); 771 ASAN_ATOMIC_FUNC_ADD(int, u_int); 772 ASAN_ATOMIC_FUNC_ADD(long, u_long); 773 ASAN_ATOMIC_FUNC_ADD(ptr, uintptr_t); 774 775 ASAN_ATOMIC_FUNC_SUBTRACT(8, uint8_t); 776 ASAN_ATOMIC_FUNC_SUBTRACT(16, uint16_t); 777 ASAN_ATOMIC_FUNC_SUBTRACT(32, uint32_t); 778 ASAN_ATOMIC_FUNC_SUBTRACT(64, uint64_t); 779 ASAN_ATOMIC_FUNC_SUBTRACT(int, u_int); 780 ASAN_ATOMIC_FUNC_SUBTRACT(long, u_long); 781 ASAN_ATOMIC_FUNC_SUBTRACT(ptr, uintptr_t); 782 783 ASAN_ATOMIC_FUNC_SET(8, uint8_t); 784 ASAN_ATOMIC_FUNC_SET(16, uint16_t); 785 ASAN_ATOMIC_FUNC_SET(32, uint32_t); 786 ASAN_ATOMIC_FUNC_SET(64, uint64_t); 787 ASAN_ATOMIC_FUNC_SET(int, u_int); 788 ASAN_ATOMIC_FUNC_SET(long, u_long); 789 ASAN_ATOMIC_FUNC_SET(ptr, uintptr_t); 790 791 ASAN_ATOMIC_FUNC_CLEAR(8, uint8_t); 792 ASAN_ATOMIC_FUNC_CLEAR(16, uint16_t); 793 ASAN_ATOMIC_FUNC_CLEAR(32, uint32_t); 794 ASAN_ATOMIC_FUNC_CLEAR(64, uint64_t); 795 ASAN_ATOMIC_FUNC_CLEAR(int, u_int); 796 ASAN_ATOMIC_FUNC_CLEAR(long, u_long); 797 ASAN_ATOMIC_FUNC_CLEAR(ptr, uintptr_t); 798 799 ASAN_ATOMIC_FUNC_FETCHADD(32, uint32_t); 800 ASAN_ATOMIC_FUNC_FETCHADD(64, uint64_t); 801 ASAN_ATOMIC_FUNC_FETCHADD(int, u_int); 802 ASAN_ATOMIC_FUNC_FETCHADD(long, u_long); 803 804 ASAN_ATOMIC_FUNC_READANDCLEAR(32, uint32_t); 805 ASAN_ATOMIC_FUNC_READANDCLEAR(64, uint64_t); 806 ASAN_ATOMIC_FUNC_READANDCLEAR(int, u_int); 807 ASAN_ATOMIC_FUNC_READANDCLEAR(long, u_long); 808 ASAN_ATOMIC_FUNC_READANDCLEAR(ptr, uintptr_t); 809 810 ASAN_ATOMIC_FUNC_TESTANDCLEAR(32, uint32_t); 811 ASAN_ATOMIC_FUNC_TESTANDCLEAR(64, uint64_t); 812 ASAN_ATOMIC_FUNC_TESTANDCLEAR(int, u_int); 813 ASAN_ATOMIC_FUNC_TESTANDCLEAR(long, u_long); 814 815 ASAN_ATOMIC_FUNC_TESTANDSET(32, uint32_t); 816 ASAN_ATOMIC_FUNC_TESTANDSET(64, uint64_t); 817 ASAN_ATOMIC_FUNC_TESTANDSET(int, u_int); 818 ASAN_ATOMIC_FUNC_TESTANDSET(long, u_long); 819 820 ASAN_ATOMIC_FUNC_SWAP(32, uint32_t); 821 ASAN_ATOMIC_FUNC_SWAP(64, uint64_t); 822 ASAN_ATOMIC_FUNC_SWAP(int, u_int); 823 ASAN_ATOMIC_FUNC_SWAP(long, u_long); 824 ASAN_ATOMIC_FUNC_SWAP(ptr, uintptr_t); 825 826 ASAN_ATOMIC_FUNC_CMPSET(8, uint8_t); 827 ASAN_ATOMIC_FUNC_CMPSET(16, uint16_t); 828 ASAN_ATOMIC_FUNC_CMPSET(32, uint32_t); 829 ASAN_ATOMIC_FUNC_CMPSET(64, uint64_t); 830 ASAN_ATOMIC_FUNC_CMPSET(int, u_int); 831 ASAN_ATOMIC_FUNC_CMPSET(long, u_long); 832 ASAN_ATOMIC_FUNC_CMPSET(ptr, uintptr_t); 833 834 ASAN_ATOMIC_FUNC_FCMPSET(8, uint8_t); 835 ASAN_ATOMIC_FUNC_FCMPSET(16, uint16_t); 836 ASAN_ATOMIC_FUNC_FCMPSET(32, uint32_t); 837 ASAN_ATOMIC_FUNC_FCMPSET(64, uint64_t); 838 ASAN_ATOMIC_FUNC_FCMPSET(int, u_int); 839 ASAN_ATOMIC_FUNC_FCMPSET(long, u_long); 840 ASAN_ATOMIC_FUNC_FCMPSET(ptr, uintptr_t); 841 842 ASAN_ATOMIC_FUNC_LOAD(8, uint8_t); 843 ASAN_ATOMIC_FUNC_LOAD(16, uint16_t); 844 ASAN_ATOMIC_FUNC_LOAD(32, uint32_t); 845 ASAN_ATOMIC_FUNC_LOAD(64, uint64_t); 846 ASAN_ATOMIC_FUNC_LOAD(char, u_char); 847 ASAN_ATOMIC_FUNC_LOAD(short, u_short); 848 ASAN_ATOMIC_FUNC_LOAD(int, u_int); 849 ASAN_ATOMIC_FUNC_LOAD(long, u_long); 850 ASAN_ATOMIC_FUNC_LOAD(ptr, uintptr_t); 851 852 ASAN_ATOMIC_FUNC_STORE(8, uint8_t); 853 ASAN_ATOMIC_FUNC_STORE(16, uint16_t); 854 ASAN_ATOMIC_FUNC_STORE(32, uint32_t); 855 ASAN_ATOMIC_FUNC_STORE(64, uint64_t); 856 ASAN_ATOMIC_FUNC_STORE(char, u_char); 857 ASAN_ATOMIC_FUNC_STORE(short, u_short); 858 ASAN_ATOMIC_FUNC_STORE(int, u_int); 859 ASAN_ATOMIC_FUNC_STORE(long, u_long); 860 ASAN_ATOMIC_FUNC_STORE(ptr, uintptr_t); 861 862 ASAN_ATOMIC_FUNC_THREAD_FENCE(acq); 863 ASAN_ATOMIC_FUNC_THREAD_FENCE(rel); 864 ASAN_ATOMIC_FUNC_THREAD_FENCE(acq_rel); 865 ASAN_ATOMIC_FUNC_THREAD_FENCE(seq_cst); 866 867 void 868 kasan_atomic_interrupt_fence(void) 869 { 870 } 871 872 /* -------------------------------------------------------------------------- */ 873 874 #include <sys/bus.h> 875 #include <machine/bus.h> 876 #include <sys/bus_san.h> 877 878 int 879 kasan_bus_space_map(bus_space_tag_t tag, bus_addr_t hnd, bus_size_t size, 880 int flags, bus_space_handle_t *handlep) 881 { 882 return (bus_space_map(tag, hnd, size, flags, handlep)); 883 } 884 885 void 886 kasan_bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t hnd, 887 bus_size_t size) 888 { 889 bus_space_unmap(tag, hnd, size); 890 } 891 892 int 893 kasan_bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t hnd, 894 bus_size_t offset, bus_size_t size, bus_space_handle_t *handlep) 895 { 896 return (bus_space_subregion(tag, hnd, offset, size, handlep)); 897 } 898 899 void 900 kasan_bus_space_free(bus_space_tag_t tag, bus_space_handle_t hnd, 901 bus_size_t size) 902 { 903 bus_space_free(tag, hnd, size); 904 } 905 906 void 907 kasan_bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t hnd, 908 bus_size_t offset, bus_size_t size, int flags) 909 { 910 bus_space_barrier(tag, hnd, offset, size, flags); 911 } 912 913 #define ASAN_BUS_READ_FUNC(func, width, type) \ 914 type kasan_bus_space_read##func##_##width(bus_space_tag_t tag, \ 915 bus_space_handle_t hnd, bus_size_t offset) \ 916 { \ 917 return (bus_space_read##func##_##width(tag, hnd, \ 918 offset)); \ 919 } \ 920 921 #define ASAN_BUS_READ_PTR_FUNC(func, width, type) \ 922 void kasan_bus_space_read_##func##_##width(bus_space_tag_t tag, \ 923 bus_space_handle_t hnd, bus_size_t size, type *buf, \ 924 bus_size_t count) \ 925 { \ 926 kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 927 false, __RET_ADDR); \ 928 bus_space_read_##func##_##width(tag, hnd, size, buf, \ 929 count); \ 930 } 931 932 ASAN_BUS_READ_FUNC(, 1, uint8_t) 933 ASAN_BUS_READ_FUNC(_stream, 1, uint8_t) 934 ASAN_BUS_READ_PTR_FUNC(multi, 1, uint8_t) 935 ASAN_BUS_READ_PTR_FUNC(multi_stream, 1, uint8_t) 936 ASAN_BUS_READ_PTR_FUNC(region, 1, uint8_t) 937 ASAN_BUS_READ_PTR_FUNC(region_stream, 1, uint8_t) 938 939 ASAN_BUS_READ_FUNC(, 2, uint16_t) 940 ASAN_BUS_READ_FUNC(_stream, 2, uint16_t) 941 ASAN_BUS_READ_PTR_FUNC(multi, 2, uint16_t) 942 ASAN_BUS_READ_PTR_FUNC(multi_stream, 2, uint16_t) 943 ASAN_BUS_READ_PTR_FUNC(region, 2, uint16_t) 944 ASAN_BUS_READ_PTR_FUNC(region_stream, 2, uint16_t) 945 946 ASAN_BUS_READ_FUNC(, 4, uint32_t) 947 ASAN_BUS_READ_FUNC(_stream, 4, uint32_t) 948 ASAN_BUS_READ_PTR_FUNC(multi, 4, uint32_t) 949 ASAN_BUS_READ_PTR_FUNC(multi_stream, 4, uint32_t) 950 ASAN_BUS_READ_PTR_FUNC(region, 4, uint32_t) 951 ASAN_BUS_READ_PTR_FUNC(region_stream, 4, uint32_t) 952 953 ASAN_BUS_READ_FUNC(, 8, uint64_t) 954 955 #define ASAN_BUS_WRITE_FUNC(func, width, type) \ 956 void kasan_bus_space_write##func##_##width(bus_space_tag_t tag, \ 957 bus_space_handle_t hnd, bus_size_t offset, type value) \ 958 { \ 959 bus_space_write##func##_##width(tag, hnd, offset, value);\ 960 } \ 961 962 #define ASAN_BUS_WRITE_PTR_FUNC(func, width, type) \ 963 void kasan_bus_space_write_##func##_##width(bus_space_tag_t tag,\ 964 bus_space_handle_t hnd, bus_size_t size, const type *buf, \ 965 bus_size_t count) \ 966 { \ 967 kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 968 true, __RET_ADDR); \ 969 bus_space_write_##func##_##width(tag, hnd, size, buf, \ 970 count); \ 971 } 972 973 ASAN_BUS_WRITE_FUNC(, 1, uint8_t) 974 ASAN_BUS_WRITE_FUNC(_stream, 1, uint8_t) 975 ASAN_BUS_WRITE_PTR_FUNC(multi, 1, uint8_t) 976 ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 1, uint8_t) 977 ASAN_BUS_WRITE_PTR_FUNC(region, 1, uint8_t) 978 ASAN_BUS_WRITE_PTR_FUNC(region_stream, 1, uint8_t) 979 980 ASAN_BUS_WRITE_FUNC(, 2, uint16_t) 981 ASAN_BUS_WRITE_FUNC(_stream, 2, uint16_t) 982 ASAN_BUS_WRITE_PTR_FUNC(multi, 2, uint16_t) 983 ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 2, uint16_t) 984 ASAN_BUS_WRITE_PTR_FUNC(region, 2, uint16_t) 985 ASAN_BUS_WRITE_PTR_FUNC(region_stream, 2, uint16_t) 986 987 ASAN_BUS_WRITE_FUNC(, 4, uint32_t) 988 ASAN_BUS_WRITE_FUNC(_stream, 4, uint32_t) 989 ASAN_BUS_WRITE_PTR_FUNC(multi, 4, uint32_t) 990 ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 4, uint32_t) 991 ASAN_BUS_WRITE_PTR_FUNC(region, 4, uint32_t) 992 ASAN_BUS_WRITE_PTR_FUNC(region_stream, 4, uint32_t) 993 994 ASAN_BUS_WRITE_FUNC(, 8, uint64_t) 995 996 #define ASAN_BUS_SET_FUNC(func, width, type) \ 997 void kasan_bus_space_set_##func##_##width(bus_space_tag_t tag, \ 998 bus_space_handle_t hnd, bus_size_t offset, type value, \ 999 bus_size_t count) \ 1000 { \ 1001 bus_space_set_##func##_##width(tag, hnd, offset, value, \ 1002 count); \ 1003 } 1004 1005 ASAN_BUS_SET_FUNC(multi, 1, uint8_t) 1006 ASAN_BUS_SET_FUNC(region, 1, uint8_t) 1007 ASAN_BUS_SET_FUNC(multi_stream, 1, uint8_t) 1008 ASAN_BUS_SET_FUNC(region_stream, 1, uint8_t) 1009 1010 ASAN_BUS_SET_FUNC(multi, 2, uint16_t) 1011 ASAN_BUS_SET_FUNC(region, 2, uint16_t) 1012 ASAN_BUS_SET_FUNC(multi_stream, 2, uint16_t) 1013 ASAN_BUS_SET_FUNC(region_stream, 2, uint16_t) 1014 1015 ASAN_BUS_SET_FUNC(multi, 4, uint32_t) 1016 ASAN_BUS_SET_FUNC(region, 4, uint32_t) 1017 ASAN_BUS_SET_FUNC(multi_stream, 4, uint32_t) 1018 ASAN_BUS_SET_FUNC(region_stream, 4, uint32_t) 1019 1020 /* -------------------------------------------------------------------------- */ 1021 1022 void __asan_register_globals(struct __asan_global *, size_t); 1023 void __asan_unregister_globals(struct __asan_global *, size_t); 1024 1025 void 1026 __asan_register_globals(struct __asan_global *globals, size_t n) 1027 { 1028 size_t i; 1029 1030 for (i = 0; i < n; i++) { 1031 kasan_mark(globals[i].beg, globals[i].size, 1032 globals[i].size_with_redzone, KASAN_GENERIC_REDZONE); 1033 } 1034 } 1035 1036 void 1037 __asan_unregister_globals(struct __asan_global *globals, size_t n) 1038 { 1039 size_t i; 1040 1041 for (i = 0; i < n; i++) { 1042 kasan_mark(globals[i].beg, globals[i].size_with_redzone, 1043 globals[i].size_with_redzone, 0); 1044 } 1045 } 1046 1047 #define ASAN_LOAD_STORE(size) \ 1048 void __asan_load##size(unsigned long); \ 1049 void __asan_load##size(unsigned long addr) \ 1050 { \ 1051 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1052 } \ 1053 void __asan_load##size##_noabort(unsigned long); \ 1054 void __asan_load##size##_noabort(unsigned long addr) \ 1055 { \ 1056 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1057 } \ 1058 void __asan_store##size(unsigned long); \ 1059 void __asan_store##size(unsigned long addr) \ 1060 { \ 1061 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1062 } \ 1063 void __asan_store##size##_noabort(unsigned long); \ 1064 void __asan_store##size##_noabort(unsigned long addr) \ 1065 { \ 1066 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1067 } 1068 1069 ASAN_LOAD_STORE(1); 1070 ASAN_LOAD_STORE(2); 1071 ASAN_LOAD_STORE(4); 1072 ASAN_LOAD_STORE(8); 1073 ASAN_LOAD_STORE(16); 1074 1075 void __asan_loadN(unsigned long, size_t); 1076 void __asan_loadN_noabort(unsigned long, size_t); 1077 void __asan_storeN(unsigned long, size_t); 1078 void __asan_storeN_noabort(unsigned long, size_t); 1079 void __asan_handle_no_return(void); 1080 1081 void 1082 __asan_loadN(unsigned long addr, size_t size) 1083 { 1084 kasan_shadow_check(addr, size, false, __RET_ADDR); 1085 } 1086 1087 void 1088 __asan_loadN_noabort(unsigned long addr, size_t size) 1089 { 1090 kasan_shadow_check(addr, size, false, __RET_ADDR); 1091 } 1092 1093 void 1094 __asan_storeN(unsigned long addr, size_t size) 1095 { 1096 kasan_shadow_check(addr, size, true, __RET_ADDR); 1097 } 1098 1099 void 1100 __asan_storeN_noabort(unsigned long addr, size_t size) 1101 { 1102 kasan_shadow_check(addr, size, true, __RET_ADDR); 1103 } 1104 1105 void 1106 __asan_handle_no_return(void) 1107 { 1108 /* nothing */ 1109 } 1110 1111 #define ASAN_SET_SHADOW(byte) \ 1112 void __asan_set_shadow_##byte(void *, size_t); \ 1113 void __asan_set_shadow_##byte(void *addr, size_t size) \ 1114 { \ 1115 __builtin_memset((void *)addr, 0x##byte, size); \ 1116 } 1117 1118 ASAN_SET_SHADOW(00); 1119 ASAN_SET_SHADOW(f1); 1120 ASAN_SET_SHADOW(f2); 1121 ASAN_SET_SHADOW(f3); 1122 ASAN_SET_SHADOW(f5); 1123 ASAN_SET_SHADOW(f8); 1124 1125 void __asan_poison_stack_memory(const void *, size_t); 1126 void __asan_unpoison_stack_memory(const void *, size_t); 1127 1128 void 1129 __asan_poison_stack_memory(const void *addr, size_t size) 1130 { 1131 size = roundup(size, KASAN_SHADOW_SCALE); 1132 kasan_shadow_Nbyte_fill(addr, size, KASAN_USE_AFTER_SCOPE); 1133 } 1134 1135 void 1136 __asan_unpoison_stack_memory(const void *addr, size_t size) 1137 { 1138 kasan_shadow_Nbyte_markvalid(addr, size); 1139 } 1140 1141 void __asan_alloca_poison(const void *, size_t); 1142 void __asan_allocas_unpoison(const void *, const void *); 1143 1144 void 1145 __asan_alloca_poison(const void *addr, size_t size) 1146 { 1147 const void *l, *r; 1148 1149 KASSERT((vm_offset_t)addr % KASAN_ALLOCA_SCALE_SIZE == 0, 1150 ("%s: invalid address %p", __func__, addr)); 1151 1152 l = (const uint8_t *)addr - KASAN_ALLOCA_SCALE_SIZE; 1153 r = (const uint8_t *)addr + roundup(size, KASAN_ALLOCA_SCALE_SIZE); 1154 1155 kasan_shadow_Nbyte_fill(l, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_LEFT); 1156 kasan_mark(addr, size, roundup(size, KASAN_ALLOCA_SCALE_SIZE), 1157 KASAN_STACK_MID); 1158 kasan_shadow_Nbyte_fill(r, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_RIGHT); 1159 } 1160 1161 void 1162 __asan_allocas_unpoison(const void *stkbegin, const void *stkend) 1163 { 1164 size_t size; 1165 1166 if (__predict_false(!stkbegin)) 1167 return; 1168 if (__predict_false((uintptr_t)stkbegin > (uintptr_t)stkend)) 1169 return; 1170 size = (uintptr_t)stkend - (uintptr_t)stkbegin; 1171 1172 kasan_shadow_Nbyte_fill(stkbegin, size, 0); 1173 } 1174 1175 void __asan_poison_memory_region(const void *addr, size_t size); 1176 void __asan_unpoison_memory_region(const void *addr, size_t size); 1177 1178 void 1179 __asan_poison_memory_region(const void *addr, size_t size) 1180 { 1181 } 1182 1183 void 1184 __asan_unpoison_memory_region(const void *addr, size_t size) 1185 { 1186 } 1187