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

Cache object: 74b15d36cfc981c368f7413bd855c0a8


[ 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.