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. */ 67struct __asan_global_source_location { 68 const char *filename; 69 int line_no; 70 int column_no; 71}; 72 73struct __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 86FEATURE(kasan, "Kernel address sanitizer"); 87 88static SYSCTL_NODE(_debug, OID_AUTO, kasan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 89 "KASAN options"); 90 91static int panic_on_violation = 1; 92SYSCTL_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) 97static bool kasan_disabled __read_mostly = true; 98SYSCTL_BOOL(_debug_kasan, OID_AUTO, disabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, 99 &kasan_disabled, 0, "KASAN is disabled"); 100 101/* -------------------------------------------------------------------------- */ 102 103void 104kasan_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 129void 130kasan_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 146void 147kasan_init_early(vm_offset_t stack, size_t size) 148{ 149 kasan_md_init_early(stack, size); 150} 151 152static inline const char * 153kasan_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 198static void 199kasan_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 207static __always_inline void 208kasan_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 216static __always_inline void 217kasan_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 226static __always_inline void 227kasan_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 */ 257void 258kasan_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 298void 299kasan_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 313static __always_inline bool 314kasan_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 326static __always_inline bool 327kasan_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 346static __always_inline bool 347kasan_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 366static __always_inline bool 367kasan_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 386static __always_inline bool 387kasan_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 399static __always_inline void 400kasan_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(size == 0)) 409 return; 410 if (__predict_false(kasan_md_unsupported(addr))) 411 return; 412 if (KERNEL_PANICKED()) 413 return; 414 415 if (__builtin_constant_p(size)) { 416 switch (size) { 417 case 1: 418 valid = kasan_shadow_1byte_isvalid(addr, &code); 419 break; 420 case 2: 421 valid = kasan_shadow_2byte_isvalid(addr, &code); 422 break; 423 case 4: 424 valid = kasan_shadow_4byte_isvalid(addr, &code); 425 break; 426 case 8: 427 valid = kasan_shadow_8byte_isvalid(addr, &code); 428 break; 429 default: 430 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 431 break; 432 } 433 } else { 434 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 435 } 436 437 if (__predict_false(!valid)) { 438 kasan_report(addr, size, write, retaddr, code); 439 } 440} 441 442/* -------------------------------------------------------------------------- */ 443 444void * 445kasan_memcpy(void *dst, const void *src, size_t len) 446{ 447 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 448 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 449 return (__builtin_memcpy(dst, src, len)); 450} 451 452int 453kasan_memcmp(const void *b1, const void *b2, size_t len) 454{ 455 kasan_shadow_check((unsigned long)b1, len, false, __RET_ADDR); 456 kasan_shadow_check((unsigned long)b2, len, false, __RET_ADDR); 457 return (__builtin_memcmp(b1, b2, len)); 458} 459 460void * 461kasan_memset(void *b, int c, size_t len) 462{ 463 kasan_shadow_check((unsigned long)b, len, true, __RET_ADDR); 464 return (__builtin_memset(b, c, len)); 465} 466 467void * 468kasan_memmove(void *dst, const void *src, size_t len) 469{ 470 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 471 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 472 return (__builtin_memmove(dst, src, len)); 473} 474 475size_t 476kasan_strlen(const char *str) 477{ 478 const char *s; 479 480 s = str; 481 while (1) { 482 kasan_shadow_check((unsigned long)s, 1, false, __RET_ADDR); 483 if (*s == '\0') 484 break; 485 s++; 486 } 487 488 return (s - str); 489} 490 491char * 492kasan_strcpy(char *dst, const char *src) 493{ 494 char *save = dst; 495 496 while (1) { 497 kasan_shadow_check((unsigned long)src, 1, false, __RET_ADDR); 498 kasan_shadow_check((unsigned long)dst, 1, true, __RET_ADDR); 499 *dst = *src; 500 if (*src == '\0') 501 break; 502 src++, dst++; 503 } 504 505 return save; 506} 507 508int 509kasan_strcmp(const char *s1, const char *s2) 510{ 511 while (1) { 512 kasan_shadow_check((unsigned long)s1, 1, false, __RET_ADDR); 513 kasan_shadow_check((unsigned long)s2, 1, false, __RET_ADDR); 514 if (*s1 != *s2) 515 break; 516 if (*s1 == '\0') 517 return 0; 518 s1++, s2++; 519 } 520 521 return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 522} 523 524int 525kasan_copyin(const void *uaddr, void *kaddr, size_t len) 526{ 527 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 528 return (copyin(uaddr, kaddr, len)); 529} 530 531int 532kasan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 533{ 534 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 535 return (copyinstr(uaddr, kaddr, len, done)); 536} 537 538int 539kasan_copyout(const void *kaddr, void *uaddr, size_t len) 540{ 541 kasan_shadow_check((unsigned long)kaddr, len, false, __RET_ADDR); 542 return (copyout(kaddr, uaddr, len)); 543} 544 545/* -------------------------------------------------------------------------- */ 546 547int 548kasan_fubyte(volatile const void *base) 549{ 550 return (fubyte(base)); 551} 552 553int 554kasan_fuword16(volatile const void *base) 555{ 556 return (fuword16(base)); 557} 558 559int 560kasan_fueword(volatile const void *base, long *val) 561{ 562 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 563 return (fueword(base, val)); 564} 565 566int 567kasan_fueword32(volatile const void *base, int32_t *val) 568{ 569 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 570 return (fueword32(base, val)); 571} 572 573int 574kasan_fueword64(volatile const void *base, int64_t *val) 575{ 576 kasan_shadow_check((unsigned long)val, sizeof(*val), true, __RET_ADDR); 577 return (fueword64(base, val)); 578} 579 580int 581kasan_subyte(volatile void *base, int byte) 582{ 583 return (subyte(base, byte)); 584} 585 586int 587kasan_suword(volatile void *base, long word) 588{ 589 return (suword(base, word)); 590} 591 592int 593kasan_suword16(volatile void *base, int word) 594{ 595 return (suword16(base, word)); 596} 597 598int 599kasan_suword32(volatile void *base, int32_t word) 600{ 601 return (suword32(base, word)); 602} 603 604int 605kasan_suword64(volatile void *base, int64_t word) 606{ 607 return (suword64(base, word)); 608} 609 610int 611kasan_casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp, 612 uint32_t newval) 613{ 614 kasan_shadow_check((unsigned long)oldvalp, sizeof(*oldvalp), true, 615 __RET_ADDR); 616 return (casueword32(base, oldval, oldvalp, newval)); 617} 618 619int 620kasan_casueword(volatile u_long *base, u_long oldval, u_long *oldvalp, 621 u_long newval) 622{ 623 kasan_shadow_check((unsigned long)oldvalp, sizeof(*oldvalp), true, 624 __RET_ADDR); 625 return (casueword(base, oldval, oldvalp, newval)); 626} 627 628/* -------------------------------------------------------------------------- */ 629 630#include <machine/atomic.h> 631#include <sys/atomic_san.h> 632 633#define _ASAN_ATOMIC_FUNC_ADD(name, type) \ 634 void kasan_atomic_add_##name(volatile type *ptr, type val) \ 635 { \ 636 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 637 __RET_ADDR); \ 638 atomic_add_##name(ptr, val); \ 639 } 640 641#define ASAN_ATOMIC_FUNC_ADD(name, type) \ 642 _ASAN_ATOMIC_FUNC_ADD(name, type) \ 643 _ASAN_ATOMIC_FUNC_ADD(acq_##name, type) \ 644 _ASAN_ATOMIC_FUNC_ADD(rel_##name, type) 645 646#define _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 647 void kasan_atomic_subtract_##name(volatile type *ptr, type val) \ 648 { \ 649 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 650 __RET_ADDR); \ 651 atomic_subtract_##name(ptr, val); \ 652 } 653 654#define ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 655 _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 656 _ASAN_ATOMIC_FUNC_SUBTRACT(acq_##name, type) \ 657 _ASAN_ATOMIC_FUNC_SUBTRACT(rel_##name, type) 658 659#define _ASAN_ATOMIC_FUNC_SET(name, type) \ 660 void kasan_atomic_set_##name(volatile type *ptr, type val) \ 661 { \ 662 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 663 __RET_ADDR); \ 664 atomic_set_##name(ptr, val); \ 665 } 666 667#define ASAN_ATOMIC_FUNC_SET(name, type) \ 668 _ASAN_ATOMIC_FUNC_SET(name, type) \ 669 _ASAN_ATOMIC_FUNC_SET(acq_##name, type) \ 670 _ASAN_ATOMIC_FUNC_SET(rel_##name, type) 671 672#define _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 673 void kasan_atomic_clear_##name(volatile type *ptr, type val) \ 674 { \ 675 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 676 __RET_ADDR); \ 677 atomic_clear_##name(ptr, val); \ 678 } 679 680#define ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 681 _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 682 _ASAN_ATOMIC_FUNC_CLEAR(acq_##name, type) \ 683 _ASAN_ATOMIC_FUNC_CLEAR(rel_##name, type) 684 685#define ASAN_ATOMIC_FUNC_FETCHADD(name, type) \ 686 type kasan_atomic_fetchadd_##name(volatile type *ptr, type val) \ 687 { \ 688 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 689 __RET_ADDR); \ 690 return (atomic_fetchadd_##name(ptr, val)); \ 691 } 692 693#define ASAN_ATOMIC_FUNC_READANDCLEAR(name, type) \ 694 type kasan_atomic_readandclear_##name(volatile type *ptr) \ 695 { \ 696 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 697 __RET_ADDR); \ 698 return (atomic_readandclear_##name(ptr)); \ 699 } 700 701#define ASAN_ATOMIC_FUNC_TESTANDCLEAR(name, type) \ 702 int kasan_atomic_testandclear_##name(volatile type *ptr, u_int v) \ 703 { \ 704 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 705 __RET_ADDR); \ 706 return (atomic_testandclear_##name(ptr, v)); \ 707 } 708 709#define ASAN_ATOMIC_FUNC_TESTANDSET(name, type) \ 710 int kasan_atomic_testandset_##name(volatile type *ptr, u_int v) \ 711 { \ 712 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 713 __RET_ADDR); \ 714 return (atomic_testandset_##name(ptr, v)); \ 715 } 716 717#define ASAN_ATOMIC_FUNC_SWAP(name, type) \ 718 type kasan_atomic_swap_##name(volatile type *ptr, type val) \ 719 { \ 720 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 721 __RET_ADDR); \ 722 return (atomic_swap_##name(ptr, val)); \ 723 } 724 725#define _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 726 int kasan_atomic_cmpset_##name(volatile type *ptr, type oval, \ 727 type nval) \ 728 { \ 729 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 730 __RET_ADDR); \ 731 return (atomic_cmpset_##name(ptr, oval, nval)); \ 732 } 733 734#define ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 735 _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 736 _ASAN_ATOMIC_FUNC_CMPSET(acq_##name, type) \ 737 _ASAN_ATOMIC_FUNC_CMPSET(rel_##name, type) 738 739#define _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 740 int kasan_atomic_fcmpset_##name(volatile type *ptr, type *oval, \ 741 type nval) \ 742 { \ 743 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 744 __RET_ADDR); \ 745 return (atomic_fcmpset_##name(ptr, oval, nval)); \ 746 } 747 748#define ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 749 _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 750 _ASAN_ATOMIC_FUNC_FCMPSET(acq_##name, type) \ 751 _ASAN_ATOMIC_FUNC_FCMPSET(rel_##name, type) 752 753#define ASAN_ATOMIC_FUNC_THREAD_FENCE(name) \ 754 void kasan_atomic_thread_fence_##name(void) \ 755 { \ 756 atomic_thread_fence_##name(); \ 757 } 758 759#define _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 760 type kasan_atomic_load_##name(volatile type *ptr) \ 761 { \ 762 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 763 __RET_ADDR); \ 764 return (atomic_load_##name(ptr)); \ 765 } 766 767#define ASAN_ATOMIC_FUNC_LOAD(name, type) \ 768 _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 769 _ASAN_ATOMIC_FUNC_LOAD(acq_##name, type) 770 771#define _ASAN_ATOMIC_FUNC_STORE(name, type) \ 772 void kasan_atomic_store_##name(volatile type *ptr, type val) \ 773 { \ 774 kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 775 __RET_ADDR); \ 776 atomic_store_##name(ptr, val); \ 777 } 778 779#define ASAN_ATOMIC_FUNC_STORE(name, type) \ 780 _ASAN_ATOMIC_FUNC_STORE(name, type) \ 781 _ASAN_ATOMIC_FUNC_STORE(rel_##name, type) 782 783ASAN_ATOMIC_FUNC_ADD(8, uint8_t); 784ASAN_ATOMIC_FUNC_ADD(16, uint16_t); 785ASAN_ATOMIC_FUNC_ADD(32, uint32_t); 786ASAN_ATOMIC_FUNC_ADD(64, uint64_t); 787ASAN_ATOMIC_FUNC_ADD(int, u_int); 788ASAN_ATOMIC_FUNC_ADD(long, u_long); 789ASAN_ATOMIC_FUNC_ADD(ptr, uintptr_t); 790 791ASAN_ATOMIC_FUNC_SUBTRACT(8, uint8_t); 792ASAN_ATOMIC_FUNC_SUBTRACT(16, uint16_t); 793ASAN_ATOMIC_FUNC_SUBTRACT(32, uint32_t); 794ASAN_ATOMIC_FUNC_SUBTRACT(64, uint64_t); 795ASAN_ATOMIC_FUNC_SUBTRACT(int, u_int); 796ASAN_ATOMIC_FUNC_SUBTRACT(long, u_long); 797ASAN_ATOMIC_FUNC_SUBTRACT(ptr, uintptr_t); 798 799ASAN_ATOMIC_FUNC_SET(8, uint8_t); 800ASAN_ATOMIC_FUNC_SET(16, uint16_t); 801ASAN_ATOMIC_FUNC_SET(32, uint32_t); 802ASAN_ATOMIC_FUNC_SET(64, uint64_t); 803ASAN_ATOMIC_FUNC_SET(int, u_int); 804ASAN_ATOMIC_FUNC_SET(long, u_long); 805ASAN_ATOMIC_FUNC_SET(ptr, uintptr_t); 806 807ASAN_ATOMIC_FUNC_CLEAR(8, uint8_t); 808ASAN_ATOMIC_FUNC_CLEAR(16, uint16_t); 809ASAN_ATOMIC_FUNC_CLEAR(32, uint32_t); 810ASAN_ATOMIC_FUNC_CLEAR(64, uint64_t); 811ASAN_ATOMIC_FUNC_CLEAR(int, u_int); 812ASAN_ATOMIC_FUNC_CLEAR(long, u_long); 813ASAN_ATOMIC_FUNC_CLEAR(ptr, uintptr_t); 814 815ASAN_ATOMIC_FUNC_FETCHADD(32, uint32_t); 816ASAN_ATOMIC_FUNC_FETCHADD(64, uint64_t); 817ASAN_ATOMIC_FUNC_FETCHADD(int, u_int); 818ASAN_ATOMIC_FUNC_FETCHADD(long, u_long); 819 820ASAN_ATOMIC_FUNC_READANDCLEAR(32, uint32_t); 821ASAN_ATOMIC_FUNC_READANDCLEAR(64, uint64_t); 822ASAN_ATOMIC_FUNC_READANDCLEAR(int, u_int); 823ASAN_ATOMIC_FUNC_READANDCLEAR(long, u_long); 824ASAN_ATOMIC_FUNC_READANDCLEAR(ptr, uintptr_t); 825 826ASAN_ATOMIC_FUNC_TESTANDCLEAR(32, uint32_t); 827ASAN_ATOMIC_FUNC_TESTANDCLEAR(64, uint64_t); 828ASAN_ATOMIC_FUNC_TESTANDCLEAR(int, u_int); 829ASAN_ATOMIC_FUNC_TESTANDCLEAR(long, u_long); 830 831ASAN_ATOMIC_FUNC_TESTANDSET(32, uint32_t); 832ASAN_ATOMIC_FUNC_TESTANDSET(64, uint64_t); 833ASAN_ATOMIC_FUNC_TESTANDSET(int, u_int); 834ASAN_ATOMIC_FUNC_TESTANDSET(long, u_long); 835 836ASAN_ATOMIC_FUNC_SWAP(32, uint32_t); 837ASAN_ATOMIC_FUNC_SWAP(64, uint64_t); 838ASAN_ATOMIC_FUNC_SWAP(int, u_int); 839ASAN_ATOMIC_FUNC_SWAP(long, u_long); 840ASAN_ATOMIC_FUNC_SWAP(ptr, uintptr_t); 841 842ASAN_ATOMIC_FUNC_CMPSET(8, uint8_t); 843ASAN_ATOMIC_FUNC_CMPSET(16, uint16_t); 844ASAN_ATOMIC_FUNC_CMPSET(32, uint32_t); 845ASAN_ATOMIC_FUNC_CMPSET(64, uint64_t); 846ASAN_ATOMIC_FUNC_CMPSET(int, u_int); 847ASAN_ATOMIC_FUNC_CMPSET(long, u_long); 848ASAN_ATOMIC_FUNC_CMPSET(ptr, uintptr_t); 849 850ASAN_ATOMIC_FUNC_FCMPSET(8, uint8_t); 851ASAN_ATOMIC_FUNC_FCMPSET(16, uint16_t); 852ASAN_ATOMIC_FUNC_FCMPSET(32, uint32_t); 853ASAN_ATOMIC_FUNC_FCMPSET(64, uint64_t); 854ASAN_ATOMIC_FUNC_FCMPSET(int, u_int); 855ASAN_ATOMIC_FUNC_FCMPSET(long, u_long); 856ASAN_ATOMIC_FUNC_FCMPSET(ptr, uintptr_t); 857 858_ASAN_ATOMIC_FUNC_LOAD(bool, bool); 859ASAN_ATOMIC_FUNC_LOAD(8, uint8_t); 860ASAN_ATOMIC_FUNC_LOAD(16, uint16_t); 861ASAN_ATOMIC_FUNC_LOAD(32, uint32_t); 862ASAN_ATOMIC_FUNC_LOAD(64, uint64_t); 863ASAN_ATOMIC_FUNC_LOAD(char, u_char); 864ASAN_ATOMIC_FUNC_LOAD(short, u_short); 865ASAN_ATOMIC_FUNC_LOAD(int, u_int); 866ASAN_ATOMIC_FUNC_LOAD(long, u_long); 867ASAN_ATOMIC_FUNC_LOAD(ptr, uintptr_t); 868 869_ASAN_ATOMIC_FUNC_STORE(bool, bool); 870ASAN_ATOMIC_FUNC_STORE(8, uint8_t); 871ASAN_ATOMIC_FUNC_STORE(16, uint16_t); 872ASAN_ATOMIC_FUNC_STORE(32, uint32_t); 873ASAN_ATOMIC_FUNC_STORE(64, uint64_t); 874ASAN_ATOMIC_FUNC_STORE(char, u_char); 875ASAN_ATOMIC_FUNC_STORE(short, u_short); 876ASAN_ATOMIC_FUNC_STORE(int, u_int); 877ASAN_ATOMIC_FUNC_STORE(long, u_long); 878ASAN_ATOMIC_FUNC_STORE(ptr, uintptr_t); 879 880ASAN_ATOMIC_FUNC_THREAD_FENCE(acq); 881ASAN_ATOMIC_FUNC_THREAD_FENCE(rel); 882ASAN_ATOMIC_FUNC_THREAD_FENCE(acq_rel); 883ASAN_ATOMIC_FUNC_THREAD_FENCE(seq_cst); 884 885void 886kasan_atomic_interrupt_fence(void) 887{ 888} 889 890/* -------------------------------------------------------------------------- */ 891 892#include <sys/bus.h> 893#include <machine/bus.h> 894#include <sys/bus_san.h> 895 896int 897kasan_bus_space_map(bus_space_tag_t tag, bus_addr_t hnd, bus_size_t size, 898 int flags, bus_space_handle_t *handlep) 899{ 900 return (bus_space_map(tag, hnd, size, flags, handlep)); 901} 902 903void 904kasan_bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t hnd, 905 bus_size_t size) 906{ 907 bus_space_unmap(tag, hnd, size); 908} 909 910int 911kasan_bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t hnd, 912 bus_size_t offset, bus_size_t size, bus_space_handle_t *handlep) 913{ 914 return (bus_space_subregion(tag, hnd, offset, size, handlep)); 915} 916 917void 918kasan_bus_space_free(bus_space_tag_t tag, bus_space_handle_t hnd, 919 bus_size_t size) 920{ 921 bus_space_free(tag, hnd, size); 922} 923 924void 925kasan_bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t hnd, 926 bus_size_t offset, bus_size_t size, int flags) 927{ 928 bus_space_barrier(tag, hnd, offset, size, flags); 929} 930 931#define ASAN_BUS_READ_FUNC(func, width, type) \ 932 type kasan_bus_space_read##func##_##width(bus_space_tag_t tag, \ 933 bus_space_handle_t hnd, bus_size_t offset) \ 934 { \ 935 return (bus_space_read##func##_##width(tag, hnd, \ 936 offset)); \ 937 } \ 938 939#define ASAN_BUS_READ_PTR_FUNC(func, width, type) \ 940 void kasan_bus_space_read_##func##_##width(bus_space_tag_t tag, \ 941 bus_space_handle_t hnd, bus_size_t size, type *buf, \ 942 bus_size_t count) \ 943 { \ 944 kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 945 false, __RET_ADDR); \ 946 bus_space_read_##func##_##width(tag, hnd, size, buf, \ 947 count); \ 948 } 949 950ASAN_BUS_READ_FUNC(, 1, uint8_t) 951ASAN_BUS_READ_FUNC(_stream, 1, uint8_t) 952ASAN_BUS_READ_PTR_FUNC(multi, 1, uint8_t) 953ASAN_BUS_READ_PTR_FUNC(multi_stream, 1, uint8_t) 954ASAN_BUS_READ_PTR_FUNC(region, 1, uint8_t) 955ASAN_BUS_READ_PTR_FUNC(region_stream, 1, uint8_t) 956 957ASAN_BUS_READ_FUNC(, 2, uint16_t) 958ASAN_BUS_READ_FUNC(_stream, 2, uint16_t) 959ASAN_BUS_READ_PTR_FUNC(multi, 2, uint16_t) 960ASAN_BUS_READ_PTR_FUNC(multi_stream, 2, uint16_t) 961ASAN_BUS_READ_PTR_FUNC(region, 2, uint16_t) 962ASAN_BUS_READ_PTR_FUNC(region_stream, 2, uint16_t) 963 964ASAN_BUS_READ_FUNC(, 4, uint32_t) 965ASAN_BUS_READ_FUNC(_stream, 4, uint32_t) 966ASAN_BUS_READ_PTR_FUNC(multi, 4, uint32_t) 967ASAN_BUS_READ_PTR_FUNC(multi_stream, 4, uint32_t) 968ASAN_BUS_READ_PTR_FUNC(region, 4, uint32_t) 969ASAN_BUS_READ_PTR_FUNC(region_stream, 4, uint32_t) 970 971ASAN_BUS_READ_FUNC(, 8, uint64_t) 972#if defined(__aarch64__) 973ASAN_BUS_READ_FUNC(_stream, 8, uint64_t) 974ASAN_BUS_READ_PTR_FUNC(multi, 8, uint64_t) 975ASAN_BUS_READ_PTR_FUNC(multi_stream, 8, uint64_t) 976ASAN_BUS_READ_PTR_FUNC(region, 8, uint64_t) 977ASAN_BUS_READ_PTR_FUNC(region_stream, 8, uint64_t) 978#endif 979 980#define ASAN_BUS_WRITE_FUNC(func, width, type) \ 981 void kasan_bus_space_write##func##_##width(bus_space_tag_t tag, \ 982 bus_space_handle_t hnd, bus_size_t offset, type value) \ 983 { \ 984 bus_space_write##func##_##width(tag, hnd, offset, value);\ 985 } \ 986 987#define ASAN_BUS_WRITE_PTR_FUNC(func, width, type) \ 988 void kasan_bus_space_write_##func##_##width(bus_space_tag_t tag,\ 989 bus_space_handle_t hnd, bus_size_t size, const type *buf, \ 990 bus_size_t count) \ 991 { \ 992 kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 993 true, __RET_ADDR); \ 994 bus_space_write_##func##_##width(tag, hnd, size, buf, \ 995 count); \ 996 } 997 998ASAN_BUS_WRITE_FUNC(, 1, uint8_t) 999ASAN_BUS_WRITE_FUNC(_stream, 1, uint8_t) 1000ASAN_BUS_WRITE_PTR_FUNC(multi, 1, uint8_t) 1001ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 1, uint8_t) 1002ASAN_BUS_WRITE_PTR_FUNC(region, 1, uint8_t) 1003ASAN_BUS_WRITE_PTR_FUNC(region_stream, 1, uint8_t) 1004 1005ASAN_BUS_WRITE_FUNC(, 2, uint16_t) 1006ASAN_BUS_WRITE_FUNC(_stream, 2, uint16_t) 1007ASAN_BUS_WRITE_PTR_FUNC(multi, 2, uint16_t) 1008ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 2, uint16_t) 1009ASAN_BUS_WRITE_PTR_FUNC(region, 2, uint16_t) 1010ASAN_BUS_WRITE_PTR_FUNC(region_stream, 2, uint16_t) 1011 1012ASAN_BUS_WRITE_FUNC(, 4, uint32_t) 1013ASAN_BUS_WRITE_FUNC(_stream, 4, uint32_t) 1014ASAN_BUS_WRITE_PTR_FUNC(multi, 4, uint32_t) 1015ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 4, uint32_t) 1016ASAN_BUS_WRITE_PTR_FUNC(region, 4, uint32_t) 1017ASAN_BUS_WRITE_PTR_FUNC(region_stream, 4, uint32_t) 1018 1019ASAN_BUS_WRITE_FUNC(, 8, uint64_t) 1020 1021#define ASAN_BUS_SET_FUNC(func, width, type) \ 1022 void kasan_bus_space_set_##func##_##width(bus_space_tag_t tag, \ 1023 bus_space_handle_t hnd, bus_size_t offset, type value, \ 1024 bus_size_t count) \ 1025 { \ 1026 bus_space_set_##func##_##width(tag, hnd, offset, value, \ 1027 count); \ 1028 } 1029 1030ASAN_BUS_SET_FUNC(multi, 1, uint8_t) 1031ASAN_BUS_SET_FUNC(region, 1, uint8_t) 1032ASAN_BUS_SET_FUNC(multi_stream, 1, uint8_t) 1033ASAN_BUS_SET_FUNC(region_stream, 1, uint8_t) 1034 1035ASAN_BUS_SET_FUNC(multi, 2, uint16_t) 1036ASAN_BUS_SET_FUNC(region, 2, uint16_t) 1037ASAN_BUS_SET_FUNC(multi_stream, 2, uint16_t) 1038ASAN_BUS_SET_FUNC(region_stream, 2, uint16_t) 1039 1040ASAN_BUS_SET_FUNC(multi, 4, uint32_t) 1041ASAN_BUS_SET_FUNC(region, 4, uint32_t) 1042ASAN_BUS_SET_FUNC(multi_stream, 4, uint32_t) 1043ASAN_BUS_SET_FUNC(region_stream, 4, uint32_t) 1044 1045#define ASAN_BUS_PEEK_FUNC(width, type) \ 1046 int kasan_bus_space_peek_##width(bus_space_tag_t tag, \ 1047 bus_space_handle_t hnd, bus_size_t offset, type *valuep) \ 1048 { \ 1049 return (bus_space_peek_##width(tag, hnd, offset, \ 1050 valuep)); \ 1051 } 1052 1053ASAN_BUS_PEEK_FUNC(1, uint8_t) 1054ASAN_BUS_PEEK_FUNC(2, uint16_t) 1055ASAN_BUS_PEEK_FUNC(4, uint32_t) 1056ASAN_BUS_PEEK_FUNC(8, uint64_t) 1057 1058#define ASAN_BUS_POKE_FUNC(width, type) \ 1059 int kasan_bus_space_poke_##width(bus_space_tag_t tag, \ 1060 bus_space_handle_t hnd, bus_size_t offset, type value) \ 1061 { \ 1062 return (bus_space_poke_##width(tag, hnd, offset, \ 1063 value)); \ 1064 } 1065 1066ASAN_BUS_POKE_FUNC(1, uint8_t) 1067ASAN_BUS_POKE_FUNC(2, uint16_t) 1068ASAN_BUS_POKE_FUNC(4, uint32_t) 1069ASAN_BUS_POKE_FUNC(8, uint64_t) 1070 1071/* -------------------------------------------------------------------------- */ 1072 1073void __asan_register_globals(struct __asan_global *, size_t); 1074void __asan_unregister_globals(struct __asan_global *, size_t); 1075 1076void 1077__asan_register_globals(struct __asan_global *globals, size_t n) 1078{ 1079 size_t i; 1080 1081 for (i = 0; i < n; i++) { 1082 kasan_mark(globals[i].beg, globals[i].size, 1083 globals[i].size_with_redzone, KASAN_GENERIC_REDZONE); 1084 } 1085} 1086 1087void 1088__asan_unregister_globals(struct __asan_global *globals, size_t n) 1089{ 1090 size_t i; 1091 1092 for (i = 0; i < n; i++) { 1093 kasan_mark(globals[i].beg, globals[i].size_with_redzone, 1094 globals[i].size_with_redzone, 0); 1095 } 1096} 1097 1098#define ASAN_LOAD_STORE(size) \ 1099 void __asan_load##size(unsigned long); \ 1100 void __asan_load##size(unsigned long addr) \ 1101 { \ 1102 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1103 } \ 1104 void __asan_load##size##_noabort(unsigned long); \ 1105 void __asan_load##size##_noabort(unsigned long addr) \ 1106 { \ 1107 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1108 } \ 1109 void __asan_store##size(unsigned long); \ 1110 void __asan_store##size(unsigned long addr) \ 1111 { \ 1112 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1113 } \ 1114 void __asan_store##size##_noabort(unsigned long); \ 1115 void __asan_store##size##_noabort(unsigned long addr) \ 1116 { \ 1117 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1118 } 1119 1120ASAN_LOAD_STORE(1); 1121ASAN_LOAD_STORE(2); 1122ASAN_LOAD_STORE(4); 1123ASAN_LOAD_STORE(8); 1124ASAN_LOAD_STORE(16); 1125 1126void __asan_loadN(unsigned long, size_t); 1127void __asan_loadN_noabort(unsigned long, size_t); 1128void __asan_storeN(unsigned long, size_t); 1129void __asan_storeN_noabort(unsigned long, size_t); 1130void __asan_handle_no_return(void); 1131 1132void 1133__asan_loadN(unsigned long addr, size_t size) 1134{ 1135 kasan_shadow_check(addr, size, false, __RET_ADDR); 1136} 1137 1138void 1139__asan_loadN_noabort(unsigned long addr, size_t size) 1140{ 1141 kasan_shadow_check(addr, size, false, __RET_ADDR); 1142} 1143 1144void 1145__asan_storeN(unsigned long addr, size_t size) 1146{ 1147 kasan_shadow_check(addr, size, true, __RET_ADDR); 1148} 1149 1150void 1151__asan_storeN_noabort(unsigned long addr, size_t size) 1152{ 1153 kasan_shadow_check(addr, size, true, __RET_ADDR); 1154} 1155 1156void 1157__asan_handle_no_return(void) 1158{ 1159 /* nothing */ 1160} 1161 1162#define ASAN_SET_SHADOW(byte) \ 1163 void __asan_set_shadow_##byte(void *, size_t); \ 1164 void __asan_set_shadow_##byte(void *addr, size_t size) \ 1165 { \ 1166 __builtin_memset((void *)addr, 0x##byte, size); \ 1167 } 1168 1169ASAN_SET_SHADOW(00); 1170ASAN_SET_SHADOW(f1); 1171ASAN_SET_SHADOW(f2); 1172ASAN_SET_SHADOW(f3); 1173ASAN_SET_SHADOW(f5); 1174ASAN_SET_SHADOW(f8); 1175 1176void __asan_poison_stack_memory(const void *, size_t); 1177void __asan_unpoison_stack_memory(const void *, size_t); 1178 1179void 1180__asan_poison_stack_memory(const void *addr, size_t size) 1181{ 1182 size = roundup(size, KASAN_SHADOW_SCALE); 1183 kasan_shadow_Nbyte_fill(addr, size, KASAN_USE_AFTER_SCOPE); 1184} 1185 1186void 1187__asan_unpoison_stack_memory(const void *addr, size_t size) 1188{ 1189 kasan_shadow_Nbyte_markvalid(addr, size); 1190} 1191 1192void __asan_alloca_poison(const void *, size_t); 1193void __asan_allocas_unpoison(const void *, const void *); 1194 1195void 1196__asan_alloca_poison(const void *addr, size_t size) 1197{ 1198 const void *l, *r; 1199 1200 KASSERT((vm_offset_t)addr % KASAN_ALLOCA_SCALE_SIZE == 0, 1201 ("%s: invalid address %p", __func__, addr)); 1202 1203 l = (const uint8_t *)addr - KASAN_ALLOCA_SCALE_SIZE; 1204 r = (const uint8_t *)addr + roundup(size, KASAN_ALLOCA_SCALE_SIZE); 1205 1206 kasan_shadow_Nbyte_fill(l, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_LEFT); 1207 kasan_mark(addr, size, roundup(size, KASAN_ALLOCA_SCALE_SIZE), 1208 KASAN_STACK_MID); 1209 kasan_shadow_Nbyte_fill(r, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_RIGHT); 1210} 1211 1212void 1213__asan_allocas_unpoison(const void *stkbegin, const void *stkend) 1214{ 1215 size_t size; 1216 1217 if (__predict_false(!stkbegin)) 1218 return; 1219 if (__predict_false((uintptr_t)stkbegin > (uintptr_t)stkend)) 1220 return; 1221 size = (uintptr_t)stkend - (uintptr_t)stkbegin; 1222 1223 kasan_shadow_Nbyte_fill(stkbegin, size, 0); 1224} 1225 1226void __asan_poison_memory_region(const void *addr, size_t size); 1227void __asan_unpoison_memory_region(const void *addr, size_t size); 1228 1229void 1230__asan_poison_memory_region(const void *addr, size_t size) 1231{ 1232} 1233 1234void 1235__asan_unpoison_memory_region(const void *addr, size_t size) 1236{ 1237} 1238