1 /* $NetBSD: subr_asan.c,v 1.18 2020/02/08 09:05:08 maxv Exp $ */ 2 3 /* 4 * Copyright (c) 2018-2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Maxime Villard. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.18 2020/02/08 09:05:08 maxv Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/device.h> 37 #include <sys/kernel.h> 38 #include <sys/param.h> 39 #include <sys/conf.h> 40 #include <sys/systm.h> 41 #include <sys/types.h> 42 #include <sys/asan.h> 43 44 #include <uvm/uvm.h> 45 46 #ifdef KASAN_PANIC 47 #define REPORT panic 48 #else 49 #define REPORT printf 50 #endif 51 52 /* ASAN constants. Part of the compiler ABI. */ 53 #define KASAN_SHADOW_SCALE_SHIFT 3 54 #define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT) 55 #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE_SIZE - 1) 56 57 /* The MD code. */ 58 #include <machine/asan.h> 59 60 /* ASAN ABI version. */ 61 #if defined(__clang__) && (__clang_major__ - 0 >= 6) 62 #define ASAN_ABI_VERSION 8 63 #elif __GNUC_PREREQ__(7, 1) && !defined(__clang__) 64 #define ASAN_ABI_VERSION 8 65 #elif __GNUC_PREREQ__(6, 1) && !defined(__clang__) 66 #define ASAN_ABI_VERSION 6 67 #else 68 #error "Unsupported compiler version" 69 #endif 70 71 #define __RET_ADDR (unsigned long)__builtin_return_address(0) 72 73 /* Global variable descriptor. Part of the compiler ABI. */ 74 struct __asan_global_source_location { 75 const char *filename; 76 int line_no; 77 int column_no; 78 }; 79 struct __asan_global { 80 const void *beg; /* address of the global variable */ 81 size_t size; /* size of the global variable */ 82 size_t size_with_redzone; /* size with the redzone */ 83 const void *name; /* name of the variable */ 84 const void *module_name; /* name of the module where the var is declared */ 85 unsigned long has_dynamic_init; /* the var has dyn initializer (c++) */ 86 struct __asan_global_source_location *location; 87 #if ASAN_ABI_VERSION >= 7 88 uintptr_t odr_indicator; /* the address of the ODR indicator symbol */ 89 #endif 90 }; 91 92 static bool kasan_enabled __read_mostly = false; 93 94 /* -------------------------------------------------------------------------- */ 95 96 void 97 kasan_shadow_map(void *addr, size_t size) 98 { 99 size_t sz, npages, i; 100 vaddr_t sva, eva; 101 102 KASSERT((vaddr_t)addr % KASAN_SHADOW_SCALE_SIZE == 0); 103 104 sz = roundup(size, KASAN_SHADOW_SCALE_SIZE) / KASAN_SHADOW_SCALE_SIZE; 105 106 sva = (vaddr_t)kasan_md_addr_to_shad(addr); 107 eva = (vaddr_t)kasan_md_addr_to_shad(addr) + sz; 108 109 sva = rounddown(sva, PAGE_SIZE); 110 eva = roundup(eva, PAGE_SIZE); 111 112 npages = (eva - sva) / PAGE_SIZE; 113 114 KASSERT(sva >= KASAN_MD_SHADOW_START && eva < KASAN_MD_SHADOW_END); 115 116 for (i = 0; i < npages; i++) { 117 kasan_md_shadow_map_page(sva + i * PAGE_SIZE); 118 } 119 } 120 121 static void 122 kasan_ctors(void) 123 { 124 extern uint64_t __CTOR_LIST__, __CTOR_END__; 125 size_t nentries, i; 126 uint64_t *ptr; 127 128 nentries = ((size_t)&__CTOR_END__ - (size_t)&__CTOR_LIST__) / 129 sizeof(uintptr_t); 130 131 ptr = &__CTOR_LIST__; 132 for (i = 0; i < nentries; i++) { 133 void (*func)(void); 134 135 func = (void *)(*ptr); 136 (*func)(); 137 138 ptr++; 139 } 140 } 141 142 void 143 kasan_early_init(void *stack) 144 { 145 kasan_md_early_init(stack); 146 } 147 148 void 149 kasan_init(void) 150 { 151 /* MD initialization. */ 152 kasan_md_init(); 153 154 /* Now officially enabled. */ 155 kasan_enabled = true; 156 157 /* Call the ASAN constructors. */ 158 kasan_ctors(); 159 } 160 161 static inline const char * 162 kasan_code_name(uint8_t code) 163 { 164 switch (code) { 165 case KASAN_GENERIC_REDZONE: 166 return "GenericRedZone"; 167 case KASAN_MALLOC_REDZONE: 168 return "MallocRedZone"; 169 case KASAN_KMEM_REDZONE: 170 return "KmemRedZone"; 171 case KASAN_POOL_REDZONE: 172 return "PoolRedZone"; 173 case KASAN_POOL_FREED: 174 return "PoolUseAfterFree"; 175 case 1 ... 7: 176 return "RedZonePartial"; 177 case KASAN_STACK_LEFT: 178 return "StackLeft"; 179 case KASAN_STACK_MID: 180 return "StackMiddle"; 181 case KASAN_STACK_RIGHT: 182 return "StackRight"; 183 case KASAN_USE_AFTER_RET: 184 return "UseAfterRet"; 185 case KASAN_USE_AFTER_SCOPE: 186 return "UseAfterScope"; 187 default: 188 return "Unknown"; 189 } 190 } 191 192 static void 193 kasan_report(unsigned long addr, size_t size, bool write, unsigned long pc, 194 uint8_t code) 195 { 196 REPORT("ASan: Unauthorized Access In %p: Addr %p [%zu byte%s, %s," 197 " %s]\n", 198 (void *)pc, (void *)addr, size, (size > 1 ? "s" : ""), 199 (write ? "write" : "read"), kasan_code_name(code)); 200 kasan_md_unwind(); 201 } 202 203 static __always_inline void 204 kasan_shadow_1byte_markvalid(unsigned long addr) 205 { 206 int8_t *byte = kasan_md_addr_to_shad((void *)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((vaddr_t)addr))) 230 return; 231 232 KASSERT((vaddr_t)addr % KASAN_SHADOW_SCALE_SIZE == 0); 233 KASSERT(size % KASAN_SHADOW_SCALE_SIZE == 0); 234 235 shad = (void *)kasan_md_addr_to_shad(addr); 236 size = size >> KASAN_SHADOW_SCALE_SHIFT; 237 238 __builtin_memset(shad, code, size); 239 } 240 241 void 242 kasan_add_redzone(size_t *size) 243 { 244 *size = roundup(*size, KASAN_SHADOW_SCALE_SIZE); 245 *size += KASAN_SHADOW_SCALE_SIZE; 246 } 247 248 void 249 kasan_softint(struct lwp *l) 250 { 251 const void *stk = (const void *)uvm_lwp_getuarea(l); 252 253 kasan_shadow_Nbyte_fill(stk, USPACE, 0); 254 } 255 256 /* 257 * In an area of size 'sz_with_redz', mark the 'size' first bytes as valid, 258 * and the rest as invalid. There are generally two use cases: 259 * 260 * o kasan_mark(addr, origsize, size, code), with origsize < size. This marks 261 * the redzone at the end of the buffer as invalid. 262 * 263 * o kasan_mark(addr, size, size, 0). This marks the entire buffer as valid. 264 */ 265 void 266 kasan_mark(const void *addr, size_t size, size_t sz_with_redz, uint8_t code) 267 { 268 size_t i, n, redz; 269 int8_t *shad; 270 271 KASSERT((vaddr_t)addr % KASAN_SHADOW_SCALE_SIZE == 0); 272 redz = sz_with_redz - roundup(size, KASAN_SHADOW_SCALE_SIZE); 273 KASSERT(redz % KASAN_SHADOW_SCALE_SIZE == 0); 274 shad = kasan_md_addr_to_shad(addr); 275 276 /* Chunks of 8 bytes, valid. */ 277 n = size / KASAN_SHADOW_SCALE_SIZE; 278 for (i = 0; i < n; i++) { 279 *shad++ = 0; 280 } 281 282 /* Possibly one chunk, mid. */ 283 if ((size & KASAN_SHADOW_MASK) != 0) { 284 *shad++ = (size & KASAN_SHADOW_MASK); 285 } 286 287 /* Chunks of 8 bytes, invalid. */ 288 n = redz / KASAN_SHADOW_SCALE_SIZE; 289 for (i = 0; i < n; i++) { 290 *shad++ = code; 291 } 292 } 293 294 /* -------------------------------------------------------------------------- */ 295 296 #define ADDR_CROSSES_SCALE_BOUNDARY(addr, size) \ 297 (addr >> KASAN_SHADOW_SCALE_SHIFT) != \ 298 ((addr + size - 1) >> KASAN_SHADOW_SCALE_SHIFT) 299 300 static __always_inline bool 301 kasan_shadow_1byte_isvalid(unsigned long addr, uint8_t *code) 302 { 303 int8_t *byte = kasan_md_addr_to_shad((void *)addr); 304 int8_t last = (addr & KASAN_SHADOW_MASK) + 1; 305 306 if (__predict_true(*byte == 0 || last <= *byte)) { 307 return true; 308 } 309 *code = *byte; 310 return false; 311 } 312 313 static __always_inline bool 314 kasan_shadow_2byte_isvalid(unsigned long addr, uint8_t *code) 315 { 316 int8_t *byte, last; 317 318 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 2)) { 319 return (kasan_shadow_1byte_isvalid(addr, code) && 320 kasan_shadow_1byte_isvalid(addr+1, code)); 321 } 322 323 byte = kasan_md_addr_to_shad((void *)addr); 324 last = ((addr + 1) & KASAN_SHADOW_MASK) + 1; 325 326 if (__predict_true(*byte == 0 || last <= *byte)) { 327 return true; 328 } 329 *code = *byte; 330 return false; 331 } 332 333 static __always_inline bool 334 kasan_shadow_4byte_isvalid(unsigned long addr, uint8_t *code) 335 { 336 int8_t *byte, last; 337 338 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 4)) { 339 return (kasan_shadow_2byte_isvalid(addr, code) && 340 kasan_shadow_2byte_isvalid(addr+2, code)); 341 } 342 343 byte = kasan_md_addr_to_shad((void *)addr); 344 last = ((addr + 3) & KASAN_SHADOW_MASK) + 1; 345 346 if (__predict_true(*byte == 0 || last <= *byte)) { 347 return true; 348 } 349 *code = *byte; 350 return false; 351 } 352 353 static __always_inline bool 354 kasan_shadow_8byte_isvalid(unsigned long addr, uint8_t *code) 355 { 356 int8_t *byte, last; 357 358 if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 8)) { 359 return (kasan_shadow_4byte_isvalid(addr, code) && 360 kasan_shadow_4byte_isvalid(addr+4, code)); 361 } 362 363 byte = kasan_md_addr_to_shad((void *)addr); 364 last = ((addr + 7) & KASAN_SHADOW_MASK) + 1; 365 366 if (__predict_true(*byte == 0 || last <= *byte)) { 367 return true; 368 } 369 *code = *byte; 370 return false; 371 } 372 373 static __always_inline bool 374 kasan_shadow_Nbyte_isvalid(unsigned long addr, size_t size, uint8_t *code) 375 { 376 size_t i; 377 378 for (i = 0; i < size; i++) { 379 if (!kasan_shadow_1byte_isvalid(addr+i, code)) 380 return false; 381 } 382 383 return true; 384 } 385 386 static __always_inline void 387 kasan_shadow_check(unsigned long addr, size_t size, bool write, 388 unsigned long retaddr) 389 { 390 uint8_t code; 391 bool valid; 392 393 if (__predict_false(!kasan_enabled)) 394 return; 395 if (__predict_false(size == 0)) 396 return; 397 if (__predict_false(kasan_md_unsupported(addr))) 398 return; 399 400 if (__builtin_constant_p(size)) { 401 switch (size) { 402 case 1: 403 valid = kasan_shadow_1byte_isvalid(addr, &code); 404 break; 405 case 2: 406 valid = kasan_shadow_2byte_isvalid(addr, &code); 407 break; 408 case 4: 409 valid = kasan_shadow_4byte_isvalid(addr, &code); 410 break; 411 case 8: 412 valid = kasan_shadow_8byte_isvalid(addr, &code); 413 break; 414 default: 415 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 416 break; 417 } 418 } else { 419 valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 420 } 421 422 if (__predict_false(!valid)) { 423 kasan_report(addr, size, write, retaddr, code); 424 } 425 } 426 427 /* -------------------------------------------------------------------------- */ 428 429 void * 430 kasan_memcpy(void *dst, const void *src, size_t len) 431 { 432 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 433 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 434 return __builtin_memcpy(dst, src, len); 435 } 436 437 int 438 kasan_memcmp(const void *b1, const void *b2, size_t len) 439 { 440 kasan_shadow_check((unsigned long)b1, len, false, __RET_ADDR); 441 kasan_shadow_check((unsigned long)b2, len, false, __RET_ADDR); 442 return __builtin_memcmp(b1, b2, len); 443 } 444 445 void * 446 kasan_memset(void *b, int c, size_t len) 447 { 448 kasan_shadow_check((unsigned long)b, len, true, __RET_ADDR); 449 return __builtin_memset(b, c, len); 450 } 451 452 void * 453 kasan_memmove(void *dst, const void *src, size_t len) 454 { 455 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 456 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 457 return __builtin_memmove(dst, src, len); 458 } 459 460 char * 461 kasan_strcpy(char *dst, const char *src) 462 { 463 char *save = dst; 464 465 while (1) { 466 kasan_shadow_check((unsigned long)src, 1, false, __RET_ADDR); 467 kasan_shadow_check((unsigned long)dst, 1, true, __RET_ADDR); 468 *dst = *src; 469 if (*src == '\0') 470 break; 471 src++, dst++; 472 } 473 474 return save; 475 } 476 477 int 478 kasan_strcmp(const char *s1, const char *s2) 479 { 480 while (1) { 481 kasan_shadow_check((unsigned long)s1, 1, false, __RET_ADDR); 482 kasan_shadow_check((unsigned long)s2, 1, false, __RET_ADDR); 483 if (*s1 != *s2) 484 break; 485 if (*s1 == '\0') 486 return 0; 487 s1++, s2++; 488 } 489 490 return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 491 } 492 493 size_t 494 kasan_strlen(const char *str) 495 { 496 const char *s; 497 498 s = str; 499 while (1) { 500 kasan_shadow_check((unsigned long)s, 1, false, __RET_ADDR); 501 if (*s == '\0') 502 break; 503 s++; 504 } 505 506 return (s - str); 507 } 508 509 #undef kcopy 510 #undef copystr 511 #undef copyinstr 512 #undef copyoutstr 513 #undef copyin 514 515 int kasan_kcopy(const void *, void *, size_t); 516 int kasan_copystr(const void *, void *, size_t, size_t *); 517 int kasan_copyinstr(const void *, void *, size_t, size_t *); 518 int kasan_copyoutstr(const void *, void *, size_t, size_t *); 519 int kasan_copyin(const void *, void *, size_t); 520 int kcopy(const void *, void *, size_t); 521 int copystr(const void *, void *, size_t, size_t *); 522 int copyinstr(const void *, void *, size_t, size_t *); 523 int copyoutstr(const void *, void *, size_t, size_t *); 524 int copyin(const void *, void *, size_t); 525 526 int 527 kasan_kcopy(const void *src, void *dst, size_t len) 528 { 529 kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 530 kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 531 return kcopy(src, dst, len); 532 } 533 534 int 535 kasan_copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done) 536 { 537 kasan_shadow_check((unsigned long)kdaddr, len, true, __RET_ADDR); 538 return copystr(kfaddr, kdaddr, len, done); 539 } 540 541 int 542 kasan_copyin(const void *uaddr, void *kaddr, size_t len) 543 { 544 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 545 return copyin(uaddr, kaddr, len); 546 } 547 548 int 549 kasan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 550 { 551 kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 552 return copyinstr(uaddr, kaddr, len, done); 553 } 554 555 int 556 kasan_copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done) 557 { 558 kasan_shadow_check((unsigned long)kaddr, len, false, __RET_ADDR); 559 return copyoutstr(kaddr, uaddr, len, done); 560 } 561 562 /* -------------------------------------------------------------------------- */ 563 564 #undef _ucas_32 565 #undef _ucas_32_mp 566 #undef _ucas_64 567 #undef _ucas_64_mp 568 #undef _ufetch_8 569 #undef _ufetch_16 570 #undef _ufetch_32 571 #undef _ufetch_64 572 573 int _ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *); 574 int kasan__ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *); 575 int 576 kasan__ucas_32(volatile uint32_t *uaddr, uint32_t old, uint32_t new, 577 uint32_t *ret) 578 { 579 kasan_shadow_check((unsigned long)ret, sizeof(*ret), true, 580 __RET_ADDR); 581 return _ucas_32(uaddr, old, new, ret); 582 } 583 584 #ifdef __HAVE_UCAS_MP 585 int _ucas_32_mp(volatile uint32_t *, uint32_t, uint32_t, uint32_t *); 586 int kasan__ucas_32_mp(volatile uint32_t *, uint32_t, uint32_t, uint32_t *); 587 int 588 kasan__ucas_32_mp(volatile uint32_t *uaddr, uint32_t old, uint32_t new, 589 uint32_t *ret) 590 { 591 kasan_shadow_check((unsigned long)ret, sizeof(*ret), true, 592 __RET_ADDR); 593 return _ucas_32_mp(uaddr, old, new, ret); 594 } 595 #endif 596 597 #ifdef _LP64 598 int _ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *); 599 int kasan__ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *); 600 int 601 kasan__ucas_64(volatile uint64_t *uaddr, uint64_t old, uint64_t new, 602 uint64_t *ret) 603 { 604 kasan_shadow_check((unsigned long)ret, sizeof(*ret), true, 605 __RET_ADDR); 606 return _ucas_64(uaddr, old, new, ret); 607 } 608 609 #ifdef __HAVE_UCAS_MP 610 int _ucas_64_mp(volatile uint64_t *, uint64_t, uint64_t, uint64_t *); 611 int kasan__ucas_64_mp(volatile uint64_t *, uint64_t, uint64_t, uint64_t *); 612 int 613 kasan__ucas_64_mp(volatile uint64_t *uaddr, uint64_t old, uint64_t new, 614 uint64_t *ret) 615 { 616 kasan_shadow_check((unsigned long)ret, sizeof(*ret), true, 617 __RET_ADDR); 618 return _ucas_64_mp(uaddr, old, new, ret); 619 } 620 #endif 621 #endif 622 623 int _ufetch_8(const uint8_t *, uint8_t *); 624 int kasan__ufetch_8(const uint8_t *, uint8_t *); 625 int 626 kasan__ufetch_8(const uint8_t *uaddr, uint8_t *valp) 627 { 628 kasan_shadow_check((unsigned long)valp, sizeof(*valp), true, 629 __RET_ADDR); 630 return _ufetch_8(uaddr, valp); 631 } 632 633 int _ufetch_16(const uint16_t *, uint16_t *); 634 int kasan__ufetch_16(const uint16_t *, uint16_t *); 635 int 636 kasan__ufetch_16(const uint16_t *uaddr, uint16_t *valp) 637 { 638 kasan_shadow_check((unsigned long)valp, sizeof(*valp), true, 639 __RET_ADDR); 640 return _ufetch_16(uaddr, valp); 641 } 642 643 int _ufetch_32(const uint32_t *, uint32_t *); 644 int kasan__ufetch_32(const uint32_t *, uint32_t *); 645 int 646 kasan__ufetch_32(const uint32_t *uaddr, uint32_t *valp) 647 { 648 kasan_shadow_check((unsigned long)valp, sizeof(*valp), true, 649 __RET_ADDR); 650 return _ufetch_32(uaddr, valp); 651 } 652 653 #ifdef _LP64 654 int _ufetch_64(const uint64_t *, uint64_t *); 655 int kasan__ufetch_64(const uint64_t *, uint64_t *); 656 int 657 kasan__ufetch_64(const uint64_t *uaddr, uint64_t *valp) 658 { 659 kasan_shadow_check((unsigned long)valp, sizeof(*valp), true, 660 __RET_ADDR); 661 return _ufetch_64(uaddr, valp); 662 } 663 #endif 664 665 /* -------------------------------------------------------------------------- */ 666 667 #undef atomic_add_32 668 #undef atomic_add_int 669 #undef atomic_add_long 670 #undef atomic_add_ptr 671 #undef atomic_add_64 672 #undef atomic_add_32_nv 673 #undef atomic_add_int_nv 674 #undef atomic_add_long_nv 675 #undef atomic_add_ptr_nv 676 #undef atomic_add_64_nv 677 #undef atomic_and_32 678 #undef atomic_and_uint 679 #undef atomic_and_ulong 680 #undef atomic_and_64 681 #undef atomic_and_32_nv 682 #undef atomic_and_uint_nv 683 #undef atomic_and_ulong_nv 684 #undef atomic_and_64_nv 685 #undef atomic_or_32 686 #undef atomic_or_uint 687 #undef atomic_or_ulong 688 #undef atomic_or_64 689 #undef atomic_or_32_nv 690 #undef atomic_or_uint_nv 691 #undef atomic_or_ulong_nv 692 #undef atomic_or_64_nv 693 #undef atomic_cas_32 694 #undef atomic_cas_uint 695 #undef atomic_cas_ulong 696 #undef atomic_cas_ptr 697 #undef atomic_cas_64 698 #undef atomic_cas_32_ni 699 #undef atomic_cas_uint_ni 700 #undef atomic_cas_ulong_ni 701 #undef atomic_cas_ptr_ni 702 #undef atomic_cas_64_ni 703 #undef atomic_swap_32 704 #undef atomic_swap_uint 705 #undef atomic_swap_ulong 706 #undef atomic_swap_ptr 707 #undef atomic_swap_64 708 #undef atomic_dec_32 709 #undef atomic_dec_uint 710 #undef atomic_dec_ulong 711 #undef atomic_dec_ptr 712 #undef atomic_dec_64 713 #undef atomic_dec_32_nv 714 #undef atomic_dec_uint_nv 715 #undef atomic_dec_ulong_nv 716 #undef atomic_dec_ptr_nv 717 #undef atomic_dec_64_nv 718 #undef atomic_inc_32 719 #undef atomic_inc_uint 720 #undef atomic_inc_ulong 721 #undef atomic_inc_ptr 722 #undef atomic_inc_64 723 #undef atomic_inc_32_nv 724 #undef atomic_inc_uint_nv 725 #undef atomic_inc_ulong_nv 726 #undef atomic_inc_ptr_nv 727 #undef atomic_inc_64_nv 728 729 #define ASAN_ATOMIC_FUNC_ADD(name, tret, targ1, targ2) \ 730 void atomic_add_##name(volatile targ1 *, targ2); \ 731 void kasan_atomic_add_##name(volatile targ1 *, targ2); \ 732 void kasan_atomic_add_##name(volatile targ1 *ptr, targ2 val) \ 733 { \ 734 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 735 __RET_ADDR); \ 736 atomic_add_##name(ptr, val); \ 737 } \ 738 tret atomic_add_##name##_nv(volatile targ1 *, targ2); \ 739 tret kasan_atomic_add_##name##_nv(volatile targ1 *, targ2); \ 740 tret kasan_atomic_add_##name##_nv(volatile targ1 *ptr, targ2 val) \ 741 { \ 742 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 743 __RET_ADDR); \ 744 return atomic_add_##name##_nv(ptr, val); \ 745 } 746 747 #define ASAN_ATOMIC_FUNC_AND(name, tret, targ1, targ2) \ 748 void atomic_and_##name(volatile targ1 *, targ2); \ 749 void kasan_atomic_and_##name(volatile targ1 *, targ2); \ 750 void kasan_atomic_and_##name(volatile targ1 *ptr, targ2 val) \ 751 { \ 752 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 753 __RET_ADDR); \ 754 atomic_and_##name(ptr, val); \ 755 } \ 756 tret atomic_and_##name##_nv(volatile targ1 *, targ2); \ 757 tret kasan_atomic_and_##name##_nv(volatile targ1 *, targ2); \ 758 tret kasan_atomic_and_##name##_nv(volatile targ1 *ptr, targ2 val) \ 759 { \ 760 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 761 __RET_ADDR); \ 762 return atomic_and_##name##_nv(ptr, val); \ 763 } 764 765 #define ASAN_ATOMIC_FUNC_OR(name, tret, targ1, targ2) \ 766 void atomic_or_##name(volatile targ1 *, targ2); \ 767 void kasan_atomic_or_##name(volatile targ1 *, targ2); \ 768 void kasan_atomic_or_##name(volatile targ1 *ptr, targ2 val) \ 769 { \ 770 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 771 __RET_ADDR); \ 772 atomic_or_##name(ptr, val); \ 773 } \ 774 tret atomic_or_##name##_nv(volatile targ1 *, targ2); \ 775 tret kasan_atomic_or_##name##_nv(volatile targ1 *, targ2); \ 776 tret kasan_atomic_or_##name##_nv(volatile targ1 *ptr, targ2 val) \ 777 { \ 778 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 779 __RET_ADDR); \ 780 return atomic_or_##name##_nv(ptr, val); \ 781 } 782 783 #define ASAN_ATOMIC_FUNC_CAS(name, tret, targ1, targ2) \ 784 tret atomic_cas_##name(volatile targ1 *, targ2, targ2); \ 785 tret kasan_atomic_cas_##name(volatile targ1 *, targ2, targ2); \ 786 tret kasan_atomic_cas_##name(volatile targ1 *ptr, targ2 exp, targ2 new) \ 787 { \ 788 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 789 __RET_ADDR); \ 790 return atomic_cas_##name(ptr, exp, new); \ 791 } \ 792 tret atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2); \ 793 tret kasan_atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2); \ 794 tret kasan_atomic_cas_##name##_ni(volatile targ1 *ptr, targ2 exp, targ2 new) \ 795 { \ 796 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 797 __RET_ADDR); \ 798 return atomic_cas_##name##_ni(ptr, exp, new); \ 799 } 800 801 #define ASAN_ATOMIC_FUNC_SWAP(name, tret, targ1, targ2) \ 802 tret atomic_swap_##name(volatile targ1 *, targ2); \ 803 tret kasan_atomic_swap_##name(volatile targ1 *, targ2); \ 804 tret kasan_atomic_swap_##name(volatile targ1 *ptr, targ2 val) \ 805 { \ 806 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 807 __RET_ADDR); \ 808 return atomic_swap_##name(ptr, val); \ 809 } 810 811 #define ASAN_ATOMIC_FUNC_DEC(name, tret, targ1) \ 812 void atomic_dec_##name(volatile targ1 *); \ 813 void kasan_atomic_dec_##name(volatile targ1 *); \ 814 void kasan_atomic_dec_##name(volatile targ1 *ptr) \ 815 { \ 816 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 817 __RET_ADDR); \ 818 atomic_dec_##name(ptr); \ 819 } \ 820 tret atomic_dec_##name##_nv(volatile targ1 *); \ 821 tret kasan_atomic_dec_##name##_nv(volatile targ1 *); \ 822 tret kasan_atomic_dec_##name##_nv(volatile targ1 *ptr) \ 823 { \ 824 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 825 __RET_ADDR); \ 826 return atomic_dec_##name##_nv(ptr); \ 827 } 828 829 #define ASAN_ATOMIC_FUNC_INC(name, tret, targ1) \ 830 void atomic_inc_##name(volatile targ1 *); \ 831 void kasan_atomic_inc_##name(volatile targ1 *); \ 832 void kasan_atomic_inc_##name(volatile targ1 *ptr) \ 833 { \ 834 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 835 __RET_ADDR); \ 836 atomic_inc_##name(ptr); \ 837 } \ 838 tret atomic_inc_##name##_nv(volatile targ1 *); \ 839 tret kasan_atomic_inc_##name##_nv(volatile targ1 *); \ 840 tret kasan_atomic_inc_##name##_nv(volatile targ1 *ptr) \ 841 { \ 842 kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \ 843 __RET_ADDR); \ 844 return atomic_inc_##name##_nv(ptr); \ 845 } 846 847 ASAN_ATOMIC_FUNC_ADD(32, uint32_t, uint32_t, int32_t); 848 ASAN_ATOMIC_FUNC_ADD(64, uint64_t, uint64_t, int64_t); 849 ASAN_ATOMIC_FUNC_ADD(int, unsigned int, unsigned int, int); 850 ASAN_ATOMIC_FUNC_ADD(long, unsigned long, unsigned long, long); 851 ASAN_ATOMIC_FUNC_ADD(ptr, void *, void, ssize_t); 852 853 ASAN_ATOMIC_FUNC_AND(32, uint32_t, uint32_t, uint32_t); 854 ASAN_ATOMIC_FUNC_AND(64, uint64_t, uint64_t, uint64_t); 855 ASAN_ATOMIC_FUNC_AND(uint, unsigned int, unsigned int, unsigned int); 856 ASAN_ATOMIC_FUNC_AND(ulong, unsigned long, unsigned long, unsigned long); 857 858 ASAN_ATOMIC_FUNC_OR(32, uint32_t, uint32_t, uint32_t); 859 ASAN_ATOMIC_FUNC_OR(64, uint64_t, uint64_t, uint64_t); 860 ASAN_ATOMIC_FUNC_OR(uint, unsigned int, unsigned int, unsigned int); 861 ASAN_ATOMIC_FUNC_OR(ulong, unsigned long, unsigned long, unsigned long); 862 863 ASAN_ATOMIC_FUNC_CAS(32, uint32_t, uint32_t, uint32_t); 864 ASAN_ATOMIC_FUNC_CAS(64, uint64_t, uint64_t, uint64_t); 865 ASAN_ATOMIC_FUNC_CAS(uint, unsigned int, unsigned int, unsigned int); 866 ASAN_ATOMIC_FUNC_CAS(ulong, unsigned long, unsigned long, unsigned long); 867 ASAN_ATOMIC_FUNC_CAS(ptr, void *, void, void *); 868 869 ASAN_ATOMIC_FUNC_SWAP(32, uint32_t, uint32_t, uint32_t); 870 ASAN_ATOMIC_FUNC_SWAP(64, uint64_t, uint64_t, uint64_t); 871 ASAN_ATOMIC_FUNC_SWAP(uint, unsigned int, unsigned int, unsigned int); 872 ASAN_ATOMIC_FUNC_SWAP(ulong, unsigned long, unsigned long, unsigned long); 873 ASAN_ATOMIC_FUNC_SWAP(ptr, void *, void, void *); 874 875 ASAN_ATOMIC_FUNC_DEC(32, uint32_t, uint32_t) 876 ASAN_ATOMIC_FUNC_DEC(64, uint64_t, uint64_t) 877 ASAN_ATOMIC_FUNC_DEC(uint, unsigned int, unsigned int); 878 ASAN_ATOMIC_FUNC_DEC(ulong, unsigned long, unsigned long); 879 ASAN_ATOMIC_FUNC_DEC(ptr, void *, void); 880 881 ASAN_ATOMIC_FUNC_INC(32, uint32_t, uint32_t) 882 ASAN_ATOMIC_FUNC_INC(64, uint64_t, uint64_t) 883 ASAN_ATOMIC_FUNC_INC(uint, unsigned int, unsigned int); 884 ASAN_ATOMIC_FUNC_INC(ulong, unsigned long, unsigned long); 885 ASAN_ATOMIC_FUNC_INC(ptr, void *, void); 886 887 /* -------------------------------------------------------------------------- */ 888 889 #ifdef __HAVE_KASAN_INSTR_BUS 890 891 #include <sys/bus.h> 892 893 #undef bus_space_read_multi_1 894 #undef bus_space_read_multi_2 895 #undef bus_space_read_multi_4 896 #undef bus_space_read_multi_8 897 #undef bus_space_read_multi_stream_1 898 #undef bus_space_read_multi_stream_2 899 #undef bus_space_read_multi_stream_4 900 #undef bus_space_read_multi_stream_8 901 #undef bus_space_read_region_1 902 #undef bus_space_read_region_2 903 #undef bus_space_read_region_4 904 #undef bus_space_read_region_8 905 #undef bus_space_read_region_stream_1 906 #undef bus_space_read_region_stream_2 907 #undef bus_space_read_region_stream_4 908 #undef bus_space_read_region_stream_8 909 #undef bus_space_write_multi_1 910 #undef bus_space_write_multi_2 911 #undef bus_space_write_multi_4 912 #undef bus_space_write_multi_8 913 #undef bus_space_write_multi_stream_1 914 #undef bus_space_write_multi_stream_2 915 #undef bus_space_write_multi_stream_4 916 #undef bus_space_write_multi_stream_8 917 #undef bus_space_write_region_1 918 #undef bus_space_write_region_2 919 #undef bus_space_write_region_4 920 #undef bus_space_write_region_8 921 #undef bus_space_write_region_stream_1 922 #undef bus_space_write_region_stream_2 923 #undef bus_space_write_region_stream_4 924 #undef bus_space_write_region_stream_8 925 926 #define ASAN_BUS_READ_FUNC(bytes, bits) \ 927 void bus_space_read_multi_##bytes(bus_space_tag_t, bus_space_handle_t, \ 928 bus_size_t, uint##bits##_t *, bus_size_t); \ 929 void kasan_bus_space_read_multi_##bytes(bus_space_tag_t, \ 930 bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 931 void kasan_bus_space_read_multi_##bytes(bus_space_tag_t tag, \ 932 bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 933 bus_size_t count) \ 934 { \ 935 kasan_shadow_check((uintptr_t)buf, \ 936 sizeof(uint##bits##_t) * count, false, __RET_ADDR); \ 937 bus_space_read_multi_##bytes(tag, hnd, size, buf, count); \ 938 } \ 939 void bus_space_read_multi_stream_##bytes(bus_space_tag_t, \ 940 bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 941 void kasan_bus_space_read_multi_stream_##bytes(bus_space_tag_t, \ 942 bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 943 void kasan_bus_space_read_multi_stream_##bytes(bus_space_tag_t tag, \ 944 bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 945 bus_size_t count) \ 946 { \ 947 kasan_shadow_check((uintptr_t)buf, \ 948 sizeof(uint##bits##_t) * count, false, __RET_ADDR); \ 949 bus_space_read_multi_stream_##bytes(tag, hnd, size, buf, count);\ 950 } \ 951 void bus_space_read_region_##bytes(bus_space_tag_t, bus_space_handle_t, \ 952 bus_size_t, uint##bits##_t *, bus_size_t); \ 953 void kasan_bus_space_read_region_##bytes(bus_space_tag_t, \ 954 bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 955 void kasan_bus_space_read_region_##bytes(bus_space_tag_t tag, \ 956 bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 957 bus_size_t count) \ 958 { \ 959 kasan_shadow_check((uintptr_t)buf, \ 960 sizeof(uint##bits##_t) * count, false, __RET_ADDR); \ 961 bus_space_read_region_##bytes(tag, hnd, size, buf, count); \ 962 } \ 963 void bus_space_read_region_stream_##bytes(bus_space_tag_t, \ 964 bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 965 void kasan_bus_space_read_region_stream_##bytes(bus_space_tag_t, \ 966 bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 967 void kasan_bus_space_read_region_stream_##bytes(bus_space_tag_t tag, \ 968 bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 969 bus_size_t count) \ 970 { \ 971 kasan_shadow_check((uintptr_t)buf, \ 972 sizeof(uint##bits##_t) * count, false, __RET_ADDR); \ 973 bus_space_read_region_stream_##bytes(tag, hnd, size, buf, count);\ 974 } 975 976 #define ASAN_BUS_WRITE_FUNC(bytes, bits) \ 977 void bus_space_write_multi_##bytes(bus_space_tag_t, bus_space_handle_t, \ 978 bus_size_t, const uint##bits##_t *, bus_size_t); \ 979 void kasan_bus_space_write_multi_##bytes(bus_space_tag_t, \ 980 bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 981 void kasan_bus_space_write_multi_##bytes(bus_space_tag_t tag, \ 982 bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 983 bus_size_t count) \ 984 { \ 985 kasan_shadow_check((uintptr_t)buf, \ 986 sizeof(uint##bits##_t) * count, true, __RET_ADDR); \ 987 bus_space_write_multi_##bytes(tag, hnd, size, buf, count); \ 988 } \ 989 void bus_space_write_multi_stream_##bytes(bus_space_tag_t, \ 990 bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 991 void kasan_bus_space_write_multi_stream_##bytes(bus_space_tag_t, \ 992 bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 993 void kasan_bus_space_write_multi_stream_##bytes(bus_space_tag_t tag, \ 994 bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 995 bus_size_t count) \ 996 { \ 997 kasan_shadow_check((uintptr_t)buf, \ 998 sizeof(uint##bits##_t) * count, true, __RET_ADDR); \ 999 bus_space_write_multi_stream_##bytes(tag, hnd, size, buf, count);\ 1000 } \ 1001 void bus_space_write_region_##bytes(bus_space_tag_t, bus_space_handle_t,\ 1002 bus_size_t, const uint##bits##_t *, bus_size_t); \ 1003 void kasan_bus_space_write_region_##bytes(bus_space_tag_t, \ 1004 bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 1005 void kasan_bus_space_write_region_##bytes(bus_space_tag_t tag, \ 1006 bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 1007 bus_size_t count) \ 1008 { \ 1009 kasan_shadow_check((uintptr_t)buf, \ 1010 sizeof(uint##bits##_t) * count, true, __RET_ADDR); \ 1011 bus_space_write_region_##bytes(tag, hnd, size, buf, count); \ 1012 } \ 1013 void bus_space_write_region_stream_##bytes(bus_space_tag_t, \ 1014 bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 1015 void kasan_bus_space_write_region_stream_##bytes(bus_space_tag_t, \ 1016 bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 1017 void kasan_bus_space_write_region_stream_##bytes(bus_space_tag_t tag, \ 1018 bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 1019 bus_size_t count) \ 1020 { \ 1021 kasan_shadow_check((uintptr_t)buf, \ 1022 sizeof(uint##bits##_t) * count, true, __RET_ADDR); \ 1023 bus_space_write_region_stream_##bytes(tag, hnd, size, buf, count);\ 1024 } 1025 1026 ASAN_BUS_READ_FUNC(1, 8) 1027 ASAN_BUS_READ_FUNC(2, 16) 1028 ASAN_BUS_READ_FUNC(4, 32) 1029 ASAN_BUS_READ_FUNC(8, 64) 1030 1031 ASAN_BUS_WRITE_FUNC(1, 8) 1032 ASAN_BUS_WRITE_FUNC(2, 16) 1033 ASAN_BUS_WRITE_FUNC(4, 32) 1034 ASAN_BUS_WRITE_FUNC(8, 64) 1035 1036 #endif /* __HAVE_KASAN_INSTR_BUS */ 1037 1038 /* -------------------------------------------------------------------------- */ 1039 1040 #ifdef __HAVE_KASAN_INSTR_DMA 1041 1042 #include <sys/mbuf.h> 1043 1044 static void 1045 kasan_dma_sync_linear(uint8_t *buf, bus_addr_t offset, bus_size_t len, 1046 bool write, uintptr_t pc) 1047 { 1048 kasan_shadow_check((uintptr_t)(buf + offset), len, write, pc); 1049 } 1050 1051 static void 1052 kasan_dma_sync_mbuf(struct mbuf *m, bus_addr_t offset, bus_size_t len, 1053 bool write, uintptr_t pc) 1054 { 1055 bus_addr_t minlen; 1056 1057 for (; m != NULL && len != 0; m = m->m_next) { 1058 kasan_shadow_check((uintptr_t)m, sizeof(*m), false, pc); 1059 1060 if (offset >= m->m_len) { 1061 offset -= m->m_len; 1062 continue; 1063 } 1064 1065 minlen = MIN(len, m->m_len - offset); 1066 kasan_shadow_check((uintptr_t)(mtod(m, char *) + offset), 1067 minlen, write, pc); 1068 1069 offset = 0; 1070 len -= minlen; 1071 } 1072 } 1073 1074 static void 1075 kasan_dma_sync_uio(struct uio *uio, bus_addr_t offset, bus_size_t len, 1076 bool write, uintptr_t pc) 1077 { 1078 bus_size_t minlen, resid; 1079 struct iovec *iov; 1080 int i; 1081 1082 kasan_shadow_check((uintptr_t)uio, sizeof(struct uio), false, pc); 1083 1084 if (!VMSPACE_IS_KERNEL_P(uio->uio_vmspace)) 1085 return; 1086 1087 resid = uio->uio_resid; 1088 iov = uio->uio_iov; 1089 1090 for (i = 0; i < uio->uio_iovcnt && resid != 0; i++) { 1091 kasan_shadow_check((uintptr_t)&iov[i], sizeof(iov[i]), 1092 false, pc); 1093 minlen = MIN(resid, iov[i].iov_len); 1094 kasan_shadow_check((uintptr_t)iov[i].iov_base, minlen, 1095 write, pc); 1096 resid -= minlen; 1097 } 1098 } 1099 1100 void 1101 kasan_dma_sync(bus_dmamap_t map, bus_addr_t offset, bus_size_t len, int ops) 1102 { 1103 bool write = (ops & (BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE)) != 0; 1104 1105 switch (map->dm_buftype) { 1106 case KASAN_DMA_LINEAR: 1107 kasan_dma_sync_linear(map->dm_buf, offset, len, write, 1108 __RET_ADDR); 1109 break; 1110 case KASAN_DMA_MBUF: 1111 kasan_dma_sync_mbuf(map->dm_buf, offset, len, write, 1112 __RET_ADDR); 1113 break; 1114 case KASAN_DMA_UIO: 1115 kasan_dma_sync_uio(map->dm_buf, offset, len, write, 1116 __RET_ADDR); 1117 break; 1118 case KASAN_DMA_RAW: 1119 break; 1120 default: 1121 panic("%s: impossible", __func__); 1122 } 1123 } 1124 1125 void 1126 kasan_dma_load(bus_dmamap_t map, void *buf, bus_size_t buflen, int type) 1127 { 1128 map->dm_buf = buf; 1129 map->dm_buflen = buflen; 1130 map->dm_buftype = type; 1131 } 1132 1133 #endif /* __HAVE_KASAN_INSTR_DMA */ 1134 1135 /* -------------------------------------------------------------------------- */ 1136 1137 void __asan_register_globals(struct __asan_global *, size_t); 1138 void __asan_unregister_globals(struct __asan_global *, size_t); 1139 1140 void 1141 __asan_register_globals(struct __asan_global *globals, size_t n) 1142 { 1143 size_t i; 1144 1145 for (i = 0; i < n; i++) { 1146 kasan_mark(globals[i].beg, globals[i].size, 1147 globals[i].size_with_redzone, KASAN_GENERIC_REDZONE); 1148 } 1149 } 1150 1151 void 1152 __asan_unregister_globals(struct __asan_global *globals, size_t n) 1153 { 1154 /* never called */ 1155 } 1156 1157 #define ASAN_LOAD_STORE(size) \ 1158 void __asan_load##size(unsigned long); \ 1159 void __asan_load##size(unsigned long addr) \ 1160 { \ 1161 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1162 } \ 1163 void __asan_load##size##_noabort(unsigned long); \ 1164 void __asan_load##size##_noabort(unsigned long addr) \ 1165 { \ 1166 kasan_shadow_check(addr, size, false, __RET_ADDR);\ 1167 } \ 1168 void __asan_store##size(unsigned long); \ 1169 void __asan_store##size(unsigned long addr) \ 1170 { \ 1171 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1172 } \ 1173 void __asan_store##size##_noabort(unsigned long); \ 1174 void __asan_store##size##_noabort(unsigned long addr) \ 1175 { \ 1176 kasan_shadow_check(addr, size, true, __RET_ADDR);\ 1177 } 1178 1179 ASAN_LOAD_STORE(1); 1180 ASAN_LOAD_STORE(2); 1181 ASAN_LOAD_STORE(4); 1182 ASAN_LOAD_STORE(8); 1183 ASAN_LOAD_STORE(16); 1184 1185 void __asan_loadN(unsigned long, size_t); 1186 void __asan_loadN_noabort(unsigned long, size_t); 1187 void __asan_storeN(unsigned long, size_t); 1188 void __asan_storeN_noabort(unsigned long, size_t); 1189 void __asan_handle_no_return(void); 1190 1191 void 1192 __asan_loadN(unsigned long addr, size_t size) 1193 { 1194 kasan_shadow_check(addr, size, false, __RET_ADDR); 1195 } 1196 1197 void 1198 __asan_loadN_noabort(unsigned long addr, size_t size) 1199 { 1200 kasan_shadow_check(addr, size, false, __RET_ADDR); 1201 } 1202 1203 void 1204 __asan_storeN(unsigned long addr, size_t size) 1205 { 1206 kasan_shadow_check(addr, size, true, __RET_ADDR); 1207 } 1208 1209 void 1210 __asan_storeN_noabort(unsigned long addr, size_t size) 1211 { 1212 kasan_shadow_check(addr, size, true, __RET_ADDR); 1213 } 1214 1215 void 1216 __asan_handle_no_return(void) 1217 { 1218 /* nothing */ 1219 } 1220 1221 #define ASAN_SET_SHADOW(byte) \ 1222 void __asan_set_shadow_##byte(void *, size_t); \ 1223 void __asan_set_shadow_##byte(void *addr, size_t size) \ 1224 { \ 1225 __builtin_memset((void *)addr, 0x##byte, size); \ 1226 } 1227 1228 ASAN_SET_SHADOW(00); 1229 ASAN_SET_SHADOW(f1); 1230 ASAN_SET_SHADOW(f2); 1231 ASAN_SET_SHADOW(f3); 1232 ASAN_SET_SHADOW(f5); 1233 ASAN_SET_SHADOW(f8); 1234 1235 void __asan_poison_stack_memory(const void *, size_t); 1236 void __asan_unpoison_stack_memory(const void *, size_t); 1237 1238 void 1239 __asan_poison_stack_memory(const void *addr, size_t size) 1240 { 1241 size = roundup(size, KASAN_SHADOW_SCALE_SIZE); 1242 kasan_shadow_Nbyte_fill(addr, size, KASAN_USE_AFTER_SCOPE); 1243 } 1244 1245 void 1246 __asan_unpoison_stack_memory(const void *addr, size_t size) 1247 { 1248 kasan_shadow_Nbyte_markvalid(addr, size); 1249 } 1250