The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_asan.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 8acd9a8b938fcaead4430bc2e3751f4e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.