138da497aSMark Johnston /* $NetBSD: subr_asan.c,v 1.26 2020/09/10 14:10:46 maxv Exp $ */ 238da497aSMark Johnston 338da497aSMark Johnston /* 438da497aSMark Johnston * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net 538da497aSMark Johnston * All rights reserved. 638da497aSMark Johnston * 738da497aSMark Johnston * This code is part of the KASAN subsystem of the NetBSD kernel. 838da497aSMark Johnston * 938da497aSMark Johnston * Redistribution and use in source and binary forms, with or without 1038da497aSMark Johnston * modification, are permitted provided that the following conditions 1138da497aSMark Johnston * are met: 1238da497aSMark Johnston * 1. Redistributions of source code must retain the above copyright 1338da497aSMark Johnston * notice, this list of conditions and the following disclaimer. 1438da497aSMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 1538da497aSMark Johnston * notice, this list of conditions and the following disclaimer in the 1638da497aSMark Johnston * documentation and/or other materials provided with the distribution. 1738da497aSMark Johnston * 1838da497aSMark Johnston * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1938da497aSMark Johnston * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2038da497aSMark Johnston * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2138da497aSMark Johnston * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2238da497aSMark Johnston * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2338da497aSMark Johnston * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2438da497aSMark Johnston * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2538da497aSMark Johnston * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2638da497aSMark Johnston * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2738da497aSMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2838da497aSMark Johnston * SUCH DAMAGE. 2938da497aSMark Johnston */ 3038da497aSMark Johnston 3138da497aSMark Johnston #define SAN_RUNTIME 3238da497aSMark Johnston 3338da497aSMark Johnston #include <sys/cdefs.h> 3438da497aSMark Johnston __FBSDID("$FreeBSD$"); 3538da497aSMark Johnston #if 0 3638da497aSMark Johnston __KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.26 2020/09/10 14:10:46 maxv Exp $"); 3738da497aSMark Johnston #endif 3838da497aSMark Johnston 3938da497aSMark Johnston #include <sys/param.h> 4038da497aSMark Johnston #include <sys/systm.h> 4138da497aSMark Johnston #include <sys/asan.h> 4238da497aSMark Johnston #include <sys/kernel.h> 4338da497aSMark Johnston #include <sys/stack.h> 4438da497aSMark Johnston #include <sys/sysctl.h> 4538da497aSMark Johnston 4638da497aSMark Johnston #include <machine/asan.h> 4738da497aSMark Johnston 4838da497aSMark Johnston /* ASAN constants. Part of the compiler ABI. */ 4938da497aSMark Johnston #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE - 1) 5038da497aSMark Johnston #define KASAN_ALLOCA_SCALE_SIZE 32 5138da497aSMark Johnston 5238da497aSMark Johnston /* ASAN ABI version. */ 5338da497aSMark Johnston #if defined(__clang__) && (__clang_major__ - 0 >= 6) 5438da497aSMark Johnston #define ASAN_ABI_VERSION 8 5538da497aSMark Johnston #elif __GNUC_PREREQ__(7, 1) && !defined(__clang__) 5638da497aSMark Johnston #define ASAN_ABI_VERSION 8 5738da497aSMark Johnston #elif __GNUC_PREREQ__(6, 1) && !defined(__clang__) 5838da497aSMark Johnston #define ASAN_ABI_VERSION 6 5938da497aSMark Johnston #else 6038da497aSMark Johnston #error "Unsupported compiler version" 6138da497aSMark Johnston #endif 6238da497aSMark Johnston 6338da497aSMark Johnston #define __RET_ADDR (unsigned long)__builtin_return_address(0) 6438da497aSMark Johnston 6538da497aSMark Johnston /* Global variable descriptor. Part of the compiler ABI. */ 6638da497aSMark Johnston struct __asan_global_source_location { 6738da497aSMark Johnston const char *filename; 6838da497aSMark Johnston int line_no; 6938da497aSMark Johnston int column_no; 7038da497aSMark Johnston }; 7138da497aSMark Johnston 7238da497aSMark Johnston struct __asan_global { 7338da497aSMark Johnston const void *beg; /* address of the global variable */ 7438da497aSMark Johnston size_t size; /* size of the global variable */ 7538da497aSMark Johnston size_t size_with_redzone; /* size with the redzone */ 7638da497aSMark Johnston const void *name; /* name of the variable */ 7738da497aSMark Johnston const void *module_name; /* name of the module where the var is declared */ 7838da497aSMark Johnston unsigned long has_dynamic_init; /* the var has dyn initializer (c++) */ 7938da497aSMark Johnston struct __asan_global_source_location *location; 8038da497aSMark Johnston #if ASAN_ABI_VERSION >= 7 8138da497aSMark Johnston uintptr_t odr_indicator; /* the address of the ODR indicator symbol */ 8238da497aSMark Johnston #endif 8338da497aSMark Johnston }; 8438da497aSMark Johnston 8538da497aSMark Johnston FEATURE(kasan, "Kernel address sanitizer"); 8638da497aSMark Johnston 8738da497aSMark Johnston static SYSCTL_NODE(_debug, OID_AUTO, kasan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 8838da497aSMark Johnston "KASAN options"); 8938da497aSMark Johnston 9038da497aSMark Johnston static int panic_on_violation = 1; 9138da497aSMark Johnston SYSCTL_INT(_debug_kasan, OID_AUTO, panic_on_violation, CTLFLAG_RDTUN, 9238da497aSMark Johnston &panic_on_violation, 0, 9338da497aSMark Johnston "Panic if an invalid access is detected"); 9438da497aSMark Johnston 9538da497aSMark Johnston static bool kasan_enabled __read_mostly = false; 9638da497aSMark Johnston 9738da497aSMark Johnston /* -------------------------------------------------------------------------- */ 9838da497aSMark Johnston 9938da497aSMark Johnston void 100*20e3b9d8SMark Johnston kasan_shadow_map(vm_offset_t addr, size_t size) 10138da497aSMark Johnston { 10238da497aSMark Johnston size_t sz, npages, i; 10338da497aSMark Johnston vm_offset_t sva, eva; 10438da497aSMark Johnston 105*20e3b9d8SMark Johnston KASSERT(addr % KASAN_SHADOW_SCALE == 0, 106*20e3b9d8SMark Johnston ("%s: invalid address %#lx", __func__, addr)); 10738da497aSMark Johnston 10838da497aSMark Johnston sz = roundup(size, KASAN_SHADOW_SCALE) / KASAN_SHADOW_SCALE; 10938da497aSMark Johnston 110*20e3b9d8SMark Johnston sva = kasan_md_addr_to_shad(addr); 111*20e3b9d8SMark Johnston eva = kasan_md_addr_to_shad(addr) + sz; 11238da497aSMark Johnston 11338da497aSMark Johnston sva = rounddown(sva, PAGE_SIZE); 11438da497aSMark Johnston eva = roundup(eva, PAGE_SIZE); 11538da497aSMark Johnston 11638da497aSMark Johnston npages = (eva - sva) / PAGE_SIZE; 11738da497aSMark Johnston 11838da497aSMark Johnston KASSERT(sva >= KASAN_MIN_ADDRESS && eva < KASAN_MAX_ADDRESS, 11938da497aSMark Johnston ("%s: invalid address range %#lx-%#lx", __func__, sva, eva)); 12038da497aSMark Johnston 12138da497aSMark Johnston for (i = 0; i < npages; i++) 12238da497aSMark Johnston pmap_kasan_enter(sva + ptoa(i)); 12338da497aSMark Johnston } 12438da497aSMark Johnston 12538da497aSMark Johnston void 12638da497aSMark Johnston kasan_init(void) 12738da497aSMark Johnston { 12838da497aSMark Johnston int disabled; 12938da497aSMark Johnston 13038da497aSMark Johnston disabled = 0; 13138da497aSMark Johnston TUNABLE_INT_FETCH("debug.kasan.disabled", &disabled); 13238da497aSMark Johnston if (disabled) 13338da497aSMark Johnston return; 13438da497aSMark Johnston 13538da497aSMark Johnston /* MD initialization. */ 13638da497aSMark Johnston kasan_md_init(); 13738da497aSMark Johnston 13838da497aSMark Johnston /* Now officially enabled. */ 13938da497aSMark Johnston kasan_enabled = true; 14038da497aSMark Johnston } 14138da497aSMark Johnston 14238da497aSMark Johnston static inline const char * 14338da497aSMark Johnston kasan_code_name(uint8_t code) 14438da497aSMark Johnston { 14538da497aSMark Johnston switch (code) { 14638da497aSMark Johnston case KASAN_GENERIC_REDZONE: 14738da497aSMark Johnston return "GenericRedZone"; 14838da497aSMark Johnston case KASAN_MALLOC_REDZONE: 14938da497aSMark Johnston return "MallocRedZone"; 15038da497aSMark Johnston case KASAN_KMEM_REDZONE: 15138da497aSMark Johnston return "KmemRedZone"; 15238da497aSMark Johnston case KASAN_UMA_FREED: 15338da497aSMark Johnston return "UMAUseAfterFree"; 15438da497aSMark Johnston case KASAN_KSTACK_FREED: 15538da497aSMark Johnston return "KernelStack"; 156f1c3adefSMark Johnston case KASAN_EXEC_ARGS_FREED: 157f1c3adefSMark Johnston return "ExecKVA"; 15838da497aSMark Johnston case 1 ... 7: 15938da497aSMark Johnston return "RedZonePartial"; 16038da497aSMark Johnston case KASAN_STACK_LEFT: 16138da497aSMark Johnston return "StackLeft"; 16238da497aSMark Johnston case KASAN_STACK_MID: 16338da497aSMark Johnston return "StackMiddle"; 16438da497aSMark Johnston case KASAN_STACK_RIGHT: 16538da497aSMark Johnston return "StackRight"; 16638da497aSMark Johnston case KASAN_USE_AFTER_RET: 16738da497aSMark Johnston return "UseAfterRet"; 16838da497aSMark Johnston case KASAN_USE_AFTER_SCOPE: 16938da497aSMark Johnston return "UseAfterScope"; 17038da497aSMark Johnston default: 17138da497aSMark Johnston return "Unknown"; 17238da497aSMark Johnston } 17338da497aSMark Johnston } 17438da497aSMark Johnston 17538da497aSMark Johnston #define REPORT(f, ...) do { \ 17638da497aSMark Johnston if (panic_on_violation) { \ 17738da497aSMark Johnston panic(f, __VA_ARGS__); \ 17838da497aSMark Johnston } else { \ 17938da497aSMark Johnston struct stack st; \ 18038da497aSMark Johnston \ 18138da497aSMark Johnston stack_save(&st); \ 18238da497aSMark Johnston printf(f "\n", __VA_ARGS__); \ 18338da497aSMark Johnston stack_print_ddb(&st); \ 18438da497aSMark Johnston } \ 18538da497aSMark Johnston } while (0) 18638da497aSMark Johnston 18738da497aSMark Johnston static void 18838da497aSMark Johnston kasan_report(unsigned long addr, size_t size, bool write, unsigned long pc, 18938da497aSMark Johnston uint8_t code) 19038da497aSMark Johnston { 19138da497aSMark Johnston REPORT("ASan: Invalid access, %zu-byte %s at %#lx, %s(%x)", 19238da497aSMark Johnston size, (write ? "write" : "read"), addr, kasan_code_name(code), 19338da497aSMark Johnston code); 19438da497aSMark Johnston } 19538da497aSMark Johnston 19638da497aSMark Johnston static __always_inline void 19738da497aSMark Johnston kasan_shadow_1byte_markvalid(unsigned long addr) 19838da497aSMark Johnston { 19938da497aSMark Johnston int8_t *byte = (int8_t *)kasan_md_addr_to_shad(addr); 20038da497aSMark Johnston int8_t last = (addr & KASAN_SHADOW_MASK) + 1; 20138da497aSMark Johnston 20238da497aSMark Johnston *byte = last; 20338da497aSMark Johnston } 20438da497aSMark Johnston 20538da497aSMark Johnston static __always_inline void 20638da497aSMark Johnston kasan_shadow_Nbyte_markvalid(const void *addr, size_t size) 20738da497aSMark Johnston { 20838da497aSMark Johnston size_t i; 20938da497aSMark Johnston 21038da497aSMark Johnston for (i = 0; i < size; i++) { 21138da497aSMark Johnston kasan_shadow_1byte_markvalid((unsigned long)addr + i); 21238da497aSMark Johnston } 21338da497aSMark Johnston } 21438da497aSMark Johnston 21538da497aSMark Johnston static __always_inline void 21638da497aSMark Johnston kasan_shadow_Nbyte_fill(const void *addr, size_t size, uint8_t code) 21738da497aSMark Johnston { 21838da497aSMark Johnston void *shad; 21938da497aSMark Johnston 22038da497aSMark Johnston if (__predict_false(size == 0)) 22138da497aSMark Johnston return; 22238da497aSMark Johnston if (__predict_false(kasan_md_unsupported((vm_offset_t)addr))) 22338da497aSMark Johnston return; 22438da497aSMark Johnston 22538da497aSMark Johnston KASSERT((vm_offset_t)addr % KASAN_SHADOW_SCALE == 0, 22638da497aSMark Johnston ("%s: invalid address %p", __func__, addr)); 22738da497aSMark Johnston KASSERT(size % KASAN_SHADOW_SCALE == 0, 22838da497aSMark Johnston ("%s: invalid size %zu", __func__, size)); 22938da497aSMark Johnston 23038da497aSMark Johnston shad = (void *)kasan_md_addr_to_shad((uintptr_t)addr); 23138da497aSMark Johnston size = size >> KASAN_SHADOW_SCALE_SHIFT; 23238da497aSMark Johnston 23338da497aSMark Johnston __builtin_memset(shad, code, size); 23438da497aSMark Johnston } 23538da497aSMark Johnston 23638da497aSMark Johnston /* 23738da497aSMark Johnston * In an area of size 'sz_with_redz', mark the 'size' first bytes as valid, 23838da497aSMark Johnston * and the rest as invalid. There are generally two use cases: 23938da497aSMark Johnston * 24038da497aSMark Johnston * o kasan_mark(addr, origsize, size, code), with origsize < size. This marks 24138da497aSMark Johnston * the redzone at the end of the buffer as invalid. If the entire is to be 24238da497aSMark Johnston * marked invalid, origsize will be 0. 24338da497aSMark Johnston * 24438da497aSMark Johnston * o kasan_mark(addr, size, size, 0). This marks the entire buffer as valid. 24538da497aSMark Johnston */ 24638da497aSMark Johnston void 24738da497aSMark Johnston kasan_mark(const void *addr, size_t size, size_t redzsize, uint8_t code) 24838da497aSMark Johnston { 24938da497aSMark Johnston size_t i, n, redz; 25038da497aSMark Johnston int8_t *shad; 25138da497aSMark Johnston 25238da497aSMark Johnston if ((vm_offset_t)addr >= DMAP_MIN_ADDRESS && 25338da497aSMark Johnston (vm_offset_t)addr < DMAP_MAX_ADDRESS) 25438da497aSMark Johnston return; 25538da497aSMark Johnston 25638da497aSMark Johnston KASSERT((vm_offset_t)addr >= VM_MIN_KERNEL_ADDRESS && 25738da497aSMark Johnston (vm_offset_t)addr < VM_MAX_KERNEL_ADDRESS, 25838da497aSMark Johnston ("%s: invalid address %p", __func__, addr)); 25938da497aSMark Johnston KASSERT((vm_offset_t)addr % KASAN_SHADOW_SCALE == 0, 26038da497aSMark Johnston ("%s: invalid address %p", __func__, addr)); 26138da497aSMark Johnston redz = redzsize - roundup(size, KASAN_SHADOW_SCALE); 26238da497aSMark Johnston KASSERT(redz % KASAN_SHADOW_SCALE == 0, 26338da497aSMark Johnston ("%s: invalid size %zu", __func__, redz)); 26438da497aSMark Johnston shad = (int8_t *)kasan_md_addr_to_shad((uintptr_t)addr); 26538da497aSMark Johnston 26638da497aSMark Johnston /* Chunks of 8 bytes, valid. */ 26738da497aSMark Johnston n = size / KASAN_SHADOW_SCALE; 26838da497aSMark Johnston for (i = 0; i < n; i++) { 26938da497aSMark Johnston *shad++ = 0; 27038da497aSMark Johnston } 27138da497aSMark Johnston 27238da497aSMark Johnston /* Possibly one chunk, mid. */ 27338da497aSMark Johnston if ((size & KASAN_SHADOW_MASK) != 0) { 27438da497aSMark Johnston *shad++ = (size & KASAN_SHADOW_MASK); 27538da497aSMark Johnston } 27638da497aSMark Johnston 27738da497aSMark Johnston /* Chunks of 8 bytes, invalid. */ 27838da497aSMark Johnston n = redz / KASAN_SHADOW_SCALE; 27938da497aSMark Johnston for (i = 0; i < n; i++) { 28038da497aSMark Johnston *shad++ = code; 28138da497aSMark Johnston } 28238da497aSMark Johnston } 28338da497aSMark Johnston 28438da497aSMark Johnston /* -------------------------------------------------------------------------- */ 28538da497aSMark Johnston 28638da497aSMark Johnston #define ADDR_CROSSES_SCALE_BOUNDARY(addr, size) \ 28738da497aSMark Johnston (addr >> KASAN_SHADOW_SCALE_SHIFT) != \ 28838da497aSMark Johnston ((addr + size - 1) >> KASAN_SHADOW_SCALE_SHIFT) 28938da497aSMark Johnston 29038da497aSMark Johnston static __always_inline bool 29138da497aSMark Johnston kasan_shadow_1byte_isvalid(unsigned long addr, uint8_t *code) 29238da497aSMark Johnston { 29338da497aSMark Johnston int8_t *byte = (int8_t *)kasan_md_addr_to_shad(addr); 29438da497aSMark Johnston int8_t last = (addr & KASAN_SHADOW_MASK) + 1; 29538da497aSMark Johnston 29638da497aSMark Johnston if (__predict_true(*byte == 0 || last <= *byte)) { 29738da497aSMark Johnston return (true); 29838da497aSMark Johnston } 29938da497aSMark Johnston *code = *byte; 30038da497aSMark Johnston return (false); 30138da497aSMark Johnston } 30238da497aSMark Johnston 30338da497aSMark Johnston static __always_inline bool 30438da497aSMark Johnston kasan_shadow_2byte_isvalid(unsigned long addr, uint8_t *code) 30538da497aSMark Johnston { 30638da497aSMark Johnston int8_t *byte, last; 30738da497aSMark Johnston 30838da497aSMark Johnston if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 2)) { 30938da497aSMark Johnston return (kasan_shadow_1byte_isvalid(addr, code) && 31038da497aSMark Johnston kasan_shadow_1byte_isvalid(addr+1, code)); 31138da497aSMark Johnston } 31238da497aSMark Johnston 31338da497aSMark Johnston byte = (int8_t *)kasan_md_addr_to_shad(addr); 31438da497aSMark Johnston last = ((addr + 1) & KASAN_SHADOW_MASK) + 1; 31538da497aSMark Johnston 31638da497aSMark Johnston if (__predict_true(*byte == 0 || last <= *byte)) { 31738da497aSMark Johnston return (true); 31838da497aSMark Johnston } 31938da497aSMark Johnston *code = *byte; 32038da497aSMark Johnston return (false); 32138da497aSMark Johnston } 32238da497aSMark Johnston 32338da497aSMark Johnston static __always_inline bool 32438da497aSMark Johnston kasan_shadow_4byte_isvalid(unsigned long addr, uint8_t *code) 32538da497aSMark Johnston { 32638da497aSMark Johnston int8_t *byte, last; 32738da497aSMark Johnston 32838da497aSMark Johnston if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 4)) { 32938da497aSMark Johnston return (kasan_shadow_2byte_isvalid(addr, code) && 33038da497aSMark Johnston kasan_shadow_2byte_isvalid(addr+2, code)); 33138da497aSMark Johnston } 33238da497aSMark Johnston 33338da497aSMark Johnston byte = (int8_t *)kasan_md_addr_to_shad(addr); 33438da497aSMark Johnston last = ((addr + 3) & KASAN_SHADOW_MASK) + 1; 33538da497aSMark Johnston 33638da497aSMark Johnston if (__predict_true(*byte == 0 || last <= *byte)) { 33738da497aSMark Johnston return (true); 33838da497aSMark Johnston } 33938da497aSMark Johnston *code = *byte; 34038da497aSMark Johnston return (false); 34138da497aSMark Johnston } 34238da497aSMark Johnston 34338da497aSMark Johnston static __always_inline bool 34438da497aSMark Johnston kasan_shadow_8byte_isvalid(unsigned long addr, uint8_t *code) 34538da497aSMark Johnston { 34638da497aSMark Johnston int8_t *byte, last; 34738da497aSMark Johnston 34838da497aSMark Johnston if (ADDR_CROSSES_SCALE_BOUNDARY(addr, 8)) { 34938da497aSMark Johnston return (kasan_shadow_4byte_isvalid(addr, code) && 35038da497aSMark Johnston kasan_shadow_4byte_isvalid(addr+4, code)); 35138da497aSMark Johnston } 35238da497aSMark Johnston 35338da497aSMark Johnston byte = (int8_t *)kasan_md_addr_to_shad(addr); 35438da497aSMark Johnston last = ((addr + 7) & KASAN_SHADOW_MASK) + 1; 35538da497aSMark Johnston 35638da497aSMark Johnston if (__predict_true(*byte == 0 || last <= *byte)) { 35738da497aSMark Johnston return (true); 35838da497aSMark Johnston } 35938da497aSMark Johnston *code = *byte; 36038da497aSMark Johnston return (false); 36138da497aSMark Johnston } 36238da497aSMark Johnston 36338da497aSMark Johnston static __always_inline bool 36438da497aSMark Johnston kasan_shadow_Nbyte_isvalid(unsigned long addr, size_t size, uint8_t *code) 36538da497aSMark Johnston { 36638da497aSMark Johnston size_t i; 36738da497aSMark Johnston 36838da497aSMark Johnston for (i = 0; i < size; i++) { 36938da497aSMark Johnston if (!kasan_shadow_1byte_isvalid(addr+i, code)) 37038da497aSMark Johnston return (false); 37138da497aSMark Johnston } 37238da497aSMark Johnston 37338da497aSMark Johnston return (true); 37438da497aSMark Johnston } 37538da497aSMark Johnston 37638da497aSMark Johnston static __always_inline void 37738da497aSMark Johnston kasan_shadow_check(unsigned long addr, size_t size, bool write, 37838da497aSMark Johnston unsigned long retaddr) 37938da497aSMark Johnston { 38038da497aSMark Johnston uint8_t code; 38138da497aSMark Johnston bool valid; 38238da497aSMark Johnston 38338da497aSMark Johnston if (__predict_false(!kasan_enabled)) 38438da497aSMark Johnston return; 38538da497aSMark Johnston if (__predict_false(size == 0)) 38638da497aSMark Johnston return; 38738da497aSMark Johnston if (__predict_false(kasan_md_unsupported(addr))) 38838da497aSMark Johnston return; 38938da497aSMark Johnston if (__predict_false(panicstr != NULL)) 39038da497aSMark Johnston return; 39138da497aSMark Johnston 39238da497aSMark Johnston if (__builtin_constant_p(size)) { 39338da497aSMark Johnston switch (size) { 39438da497aSMark Johnston case 1: 39538da497aSMark Johnston valid = kasan_shadow_1byte_isvalid(addr, &code); 39638da497aSMark Johnston break; 39738da497aSMark Johnston case 2: 39838da497aSMark Johnston valid = kasan_shadow_2byte_isvalid(addr, &code); 39938da497aSMark Johnston break; 40038da497aSMark Johnston case 4: 40138da497aSMark Johnston valid = kasan_shadow_4byte_isvalid(addr, &code); 40238da497aSMark Johnston break; 40338da497aSMark Johnston case 8: 40438da497aSMark Johnston valid = kasan_shadow_8byte_isvalid(addr, &code); 40538da497aSMark Johnston break; 40638da497aSMark Johnston default: 40738da497aSMark Johnston valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 40838da497aSMark Johnston break; 40938da497aSMark Johnston } 41038da497aSMark Johnston } else { 41138da497aSMark Johnston valid = kasan_shadow_Nbyte_isvalid(addr, size, &code); 41238da497aSMark Johnston } 41338da497aSMark Johnston 41438da497aSMark Johnston if (__predict_false(!valid)) { 41538da497aSMark Johnston kasan_report(addr, size, write, retaddr, code); 41638da497aSMark Johnston } 41738da497aSMark Johnston } 41838da497aSMark Johnston 41938da497aSMark Johnston /* -------------------------------------------------------------------------- */ 42038da497aSMark Johnston 42138da497aSMark Johnston void * 42238da497aSMark Johnston kasan_memcpy(void *dst, const void *src, size_t len) 42338da497aSMark Johnston { 42438da497aSMark Johnston kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 42538da497aSMark Johnston kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 42638da497aSMark Johnston return (__builtin_memcpy(dst, src, len)); 42738da497aSMark Johnston } 42838da497aSMark Johnston 42938da497aSMark Johnston int 43038da497aSMark Johnston kasan_memcmp(const void *b1, const void *b2, size_t len) 43138da497aSMark Johnston { 43238da497aSMark Johnston kasan_shadow_check((unsigned long)b1, len, false, __RET_ADDR); 43338da497aSMark Johnston kasan_shadow_check((unsigned long)b2, len, false, __RET_ADDR); 43438da497aSMark Johnston return (__builtin_memcmp(b1, b2, len)); 43538da497aSMark Johnston } 43638da497aSMark Johnston 43738da497aSMark Johnston void * 43838da497aSMark Johnston kasan_memset(void *b, int c, size_t len) 43938da497aSMark Johnston { 44038da497aSMark Johnston kasan_shadow_check((unsigned long)b, len, true, __RET_ADDR); 44138da497aSMark Johnston return (__builtin_memset(b, c, len)); 44238da497aSMark Johnston } 44338da497aSMark Johnston 44438da497aSMark Johnston void * 44538da497aSMark Johnston kasan_memmove(void *dst, const void *src, size_t len) 44638da497aSMark Johnston { 44738da497aSMark Johnston kasan_shadow_check((unsigned long)src, len, false, __RET_ADDR); 44838da497aSMark Johnston kasan_shadow_check((unsigned long)dst, len, true, __RET_ADDR); 44938da497aSMark Johnston return (__builtin_memmove(dst, src, len)); 45038da497aSMark Johnston } 45138da497aSMark Johnston 45238da497aSMark Johnston size_t 45338da497aSMark Johnston kasan_strlen(const char *str) 45438da497aSMark Johnston { 45538da497aSMark Johnston const char *s; 45638da497aSMark Johnston 45738da497aSMark Johnston s = str; 45838da497aSMark Johnston while (1) { 45938da497aSMark Johnston kasan_shadow_check((unsigned long)s, 1, false, __RET_ADDR); 46038da497aSMark Johnston if (*s == '\0') 46138da497aSMark Johnston break; 46238da497aSMark Johnston s++; 46338da497aSMark Johnston } 46438da497aSMark Johnston 46538da497aSMark Johnston return (s - str); 46638da497aSMark Johnston } 46738da497aSMark Johnston 46838da497aSMark Johnston char * 46938da497aSMark Johnston kasan_strcpy(char *dst, const char *src) 47038da497aSMark Johnston { 47138da497aSMark Johnston char *save = dst; 47238da497aSMark Johnston 47338da497aSMark Johnston while (1) { 47438da497aSMark Johnston kasan_shadow_check((unsigned long)src, 1, false, __RET_ADDR); 47538da497aSMark Johnston kasan_shadow_check((unsigned long)dst, 1, true, __RET_ADDR); 47638da497aSMark Johnston *dst = *src; 47738da497aSMark Johnston if (*src == '\0') 47838da497aSMark Johnston break; 47938da497aSMark Johnston src++, dst++; 48038da497aSMark Johnston } 48138da497aSMark Johnston 48238da497aSMark Johnston return save; 48338da497aSMark Johnston } 48438da497aSMark Johnston 48538da497aSMark Johnston int 48638da497aSMark Johnston kasan_strcmp(const char *s1, const char *s2) 48738da497aSMark Johnston { 48838da497aSMark Johnston while (1) { 48938da497aSMark Johnston kasan_shadow_check((unsigned long)s1, 1, false, __RET_ADDR); 49038da497aSMark Johnston kasan_shadow_check((unsigned long)s2, 1, false, __RET_ADDR); 49138da497aSMark Johnston if (*s1 != *s2) 49238da497aSMark Johnston break; 49338da497aSMark Johnston if (*s1 == '\0') 49438da497aSMark Johnston return 0; 49538da497aSMark Johnston s1++, s2++; 49638da497aSMark Johnston } 49738da497aSMark Johnston 49838da497aSMark Johnston return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 49938da497aSMark Johnston } 50038da497aSMark Johnston 50138da497aSMark Johnston int 50238da497aSMark Johnston kasan_copyin(const void *uaddr, void *kaddr, size_t len) 50338da497aSMark Johnston { 50438da497aSMark Johnston kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 50538da497aSMark Johnston return (copyin(uaddr, kaddr, len)); 50638da497aSMark Johnston } 50738da497aSMark Johnston 50838da497aSMark Johnston int 50938da497aSMark Johnston kasan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 51038da497aSMark Johnston { 51138da497aSMark Johnston kasan_shadow_check((unsigned long)kaddr, len, true, __RET_ADDR); 51238da497aSMark Johnston return (copyinstr(uaddr, kaddr, len, done)); 51338da497aSMark Johnston } 51438da497aSMark Johnston 51538da497aSMark Johnston int 51638da497aSMark Johnston kasan_copyout(const void *kaddr, void *uaddr, size_t len) 51738da497aSMark Johnston { 51838da497aSMark Johnston kasan_shadow_check((unsigned long)kaddr, len, false, __RET_ADDR); 51938da497aSMark Johnston return (copyout(kaddr, uaddr, len)); 52038da497aSMark Johnston } 52138da497aSMark Johnston 52238da497aSMark Johnston /* -------------------------------------------------------------------------- */ 52338da497aSMark Johnston 52438da497aSMark Johnston #include <machine/atomic.h> 52538da497aSMark Johnston #define ATOMIC_SAN_PREFIX kasan 52638da497aSMark Johnston #include <sys/atomic_san.h> 52738da497aSMark Johnston 52838da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_ADD(name, type) \ 52938da497aSMark Johnston void kasan_atomic_add_##name(volatile type *ptr, type val) \ 53038da497aSMark Johnston { \ 53138da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 53238da497aSMark Johnston __RET_ADDR); \ 53338da497aSMark Johnston atomic_add_##name(ptr, val); \ 53438da497aSMark Johnston } 53538da497aSMark Johnston 53638da497aSMark Johnston #define ASAN_ATOMIC_FUNC_ADD(name, type) \ 53738da497aSMark Johnston _ASAN_ATOMIC_FUNC_ADD(name, type) \ 53838da497aSMark Johnston _ASAN_ATOMIC_FUNC_ADD(acq_##name, type) \ 53938da497aSMark Johnston _ASAN_ATOMIC_FUNC_ADD(rel_##name, type) 54038da497aSMark Johnston 54138da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 54238da497aSMark Johnston void kasan_atomic_subtract_##name(volatile type *ptr, type val) \ 54338da497aSMark Johnston { \ 54438da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 54538da497aSMark Johnston __RET_ADDR); \ 54638da497aSMark Johnston atomic_subtract_##name(ptr, val); \ 54738da497aSMark Johnston } 54838da497aSMark Johnston 54938da497aSMark Johnston #define ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 55038da497aSMark Johnston _ASAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 55138da497aSMark Johnston _ASAN_ATOMIC_FUNC_SUBTRACT(acq_##name, type) \ 55238da497aSMark Johnston _ASAN_ATOMIC_FUNC_SUBTRACT(rel_##name, type) 55338da497aSMark Johnston 55438da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_SET(name, type) \ 55538da497aSMark Johnston void kasan_atomic_set_##name(volatile type *ptr, type val) \ 55638da497aSMark Johnston { \ 55738da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 55838da497aSMark Johnston __RET_ADDR); \ 55938da497aSMark Johnston atomic_set_##name(ptr, val); \ 56038da497aSMark Johnston } 56138da497aSMark Johnston 56238da497aSMark Johnston #define ASAN_ATOMIC_FUNC_SET(name, type) \ 56338da497aSMark Johnston _ASAN_ATOMIC_FUNC_SET(name, type) \ 56438da497aSMark Johnston _ASAN_ATOMIC_FUNC_SET(acq_##name, type) \ 56538da497aSMark Johnston _ASAN_ATOMIC_FUNC_SET(rel_##name, type) 56638da497aSMark Johnston 56738da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 56838da497aSMark Johnston void kasan_atomic_clear_##name(volatile type *ptr, type val) \ 56938da497aSMark Johnston { \ 57038da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 57138da497aSMark Johnston __RET_ADDR); \ 57238da497aSMark Johnston atomic_clear_##name(ptr, val); \ 57338da497aSMark Johnston } 57438da497aSMark Johnston 57538da497aSMark Johnston #define ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 57638da497aSMark Johnston _ASAN_ATOMIC_FUNC_CLEAR(name, type) \ 57738da497aSMark Johnston _ASAN_ATOMIC_FUNC_CLEAR(acq_##name, type) \ 57838da497aSMark Johnston _ASAN_ATOMIC_FUNC_CLEAR(rel_##name, type) 57938da497aSMark Johnston 58038da497aSMark Johnston #define ASAN_ATOMIC_FUNC_FETCHADD(name, type) \ 58138da497aSMark Johnston type kasan_atomic_fetchadd_##name(volatile type *ptr, type val) \ 58238da497aSMark Johnston { \ 58338da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 58438da497aSMark Johnston __RET_ADDR); \ 58538da497aSMark Johnston return (atomic_fetchadd_##name(ptr, val)); \ 58638da497aSMark Johnston } 58738da497aSMark Johnston 58838da497aSMark Johnston #define ASAN_ATOMIC_FUNC_READANDCLEAR(name, type) \ 58938da497aSMark Johnston type kasan_atomic_readandclear_##name(volatile type *ptr) \ 59038da497aSMark Johnston { \ 59138da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 59238da497aSMark Johnston __RET_ADDR); \ 59338da497aSMark Johnston return (atomic_readandclear_##name(ptr)); \ 59438da497aSMark Johnston } 59538da497aSMark Johnston 59638da497aSMark Johnston #define ASAN_ATOMIC_FUNC_TESTANDCLEAR(name, type) \ 59738da497aSMark Johnston int kasan_atomic_testandclear_##name(volatile type *ptr, u_int v) \ 59838da497aSMark Johnston { \ 59938da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 60038da497aSMark Johnston __RET_ADDR); \ 60138da497aSMark Johnston return (atomic_testandclear_##name(ptr, v)); \ 60238da497aSMark Johnston } 60338da497aSMark Johnston 60438da497aSMark Johnston #define ASAN_ATOMIC_FUNC_TESTANDSET(name, type) \ 60538da497aSMark Johnston int kasan_atomic_testandset_##name(volatile type *ptr, u_int v) \ 60638da497aSMark Johnston { \ 60738da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 60838da497aSMark Johnston __RET_ADDR); \ 60938da497aSMark Johnston return (atomic_testandset_##name(ptr, v)); \ 61038da497aSMark Johnston } 61138da497aSMark Johnston 61238da497aSMark Johnston #define ASAN_ATOMIC_FUNC_SWAP(name, type) \ 61338da497aSMark Johnston type kasan_atomic_swap_##name(volatile type *ptr, type val) \ 61438da497aSMark Johnston { \ 61538da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 61638da497aSMark Johnston __RET_ADDR); \ 61738da497aSMark Johnston return (atomic_swap_##name(ptr, val)); \ 61838da497aSMark Johnston } 61938da497aSMark Johnston 62038da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 62138da497aSMark Johnston int kasan_atomic_cmpset_##name(volatile type *ptr, type oval, \ 62238da497aSMark Johnston type nval) \ 62338da497aSMark Johnston { \ 62438da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 62538da497aSMark Johnston __RET_ADDR); \ 62638da497aSMark Johnston return (atomic_cmpset_##name(ptr, oval, nval)); \ 62738da497aSMark Johnston } 62838da497aSMark Johnston 62938da497aSMark Johnston #define ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 63038da497aSMark Johnston _ASAN_ATOMIC_FUNC_CMPSET(name, type) \ 63138da497aSMark Johnston _ASAN_ATOMIC_FUNC_CMPSET(acq_##name, type) \ 63238da497aSMark Johnston _ASAN_ATOMIC_FUNC_CMPSET(rel_##name, type) 63338da497aSMark Johnston 63438da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 63538da497aSMark Johnston int kasan_atomic_fcmpset_##name(volatile type *ptr, type *oval, \ 63638da497aSMark Johnston type nval) \ 63738da497aSMark Johnston { \ 63838da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 63938da497aSMark Johnston __RET_ADDR); \ 64038da497aSMark Johnston return (atomic_fcmpset_##name(ptr, oval, nval)); \ 64138da497aSMark Johnston } 64238da497aSMark Johnston 64338da497aSMark Johnston #define ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 64438da497aSMark Johnston _ASAN_ATOMIC_FUNC_FCMPSET(name, type) \ 64538da497aSMark Johnston _ASAN_ATOMIC_FUNC_FCMPSET(acq_##name, type) \ 64638da497aSMark Johnston _ASAN_ATOMIC_FUNC_FCMPSET(rel_##name, type) 64738da497aSMark Johnston 64838da497aSMark Johnston #define ASAN_ATOMIC_FUNC_THREAD_FENCE(name) \ 64938da497aSMark Johnston void kasan_atomic_thread_fence_##name(void) \ 65038da497aSMark Johnston { \ 65138da497aSMark Johnston atomic_thread_fence_##name(); \ 65238da497aSMark Johnston } 65338da497aSMark Johnston 65438da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 65538da497aSMark Johnston type kasan_atomic_load_##name(volatile type *ptr) \ 65638da497aSMark Johnston { \ 65738da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 65838da497aSMark Johnston __RET_ADDR); \ 65938da497aSMark Johnston return (atomic_load_##name(ptr)); \ 66038da497aSMark Johnston } 66138da497aSMark Johnston 66238da497aSMark Johnston #define ASAN_ATOMIC_FUNC_LOAD(name, type) \ 66338da497aSMark Johnston _ASAN_ATOMIC_FUNC_LOAD(name, type) \ 66438da497aSMark Johnston _ASAN_ATOMIC_FUNC_LOAD(acq_##name, type) 66538da497aSMark Johnston 66638da497aSMark Johnston #define _ASAN_ATOMIC_FUNC_STORE(name, type) \ 66738da497aSMark Johnston void kasan_atomic_store_##name(volatile type *ptr, type val) \ 66838da497aSMark Johnston { \ 66938da497aSMark Johnston kasan_shadow_check((uintptr_t)ptr, sizeof(type), true, \ 67038da497aSMark Johnston __RET_ADDR); \ 67138da497aSMark Johnston atomic_store_##name(ptr, val); \ 67238da497aSMark Johnston } 67338da497aSMark Johnston 67438da497aSMark Johnston #define ASAN_ATOMIC_FUNC_STORE(name, type) \ 67538da497aSMark Johnston _ASAN_ATOMIC_FUNC_STORE(name, type) \ 67638da497aSMark Johnston _ASAN_ATOMIC_FUNC_STORE(rel_##name, type) 67738da497aSMark Johnston 67838da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(8, uint8_t); 67938da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(16, uint16_t); 68038da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(32, uint32_t); 68138da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(64, uint64_t); 68238da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(int, u_int); 68338da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(long, u_long); 68438da497aSMark Johnston ASAN_ATOMIC_FUNC_ADD(ptr, uintptr_t); 68538da497aSMark Johnston 68638da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(8, uint8_t); 68738da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(16, uint16_t); 68838da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(32, uint32_t); 68938da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(64, uint64_t); 69038da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(int, u_int); 69138da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(long, u_long); 69238da497aSMark Johnston ASAN_ATOMIC_FUNC_SUBTRACT(ptr, uintptr_t); 69338da497aSMark Johnston 69438da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(8, uint8_t); 69538da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(16, uint16_t); 69638da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(32, uint32_t); 69738da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(64, uint64_t); 69838da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(int, u_int); 69938da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(long, u_long); 70038da497aSMark Johnston ASAN_ATOMIC_FUNC_SET(ptr, uintptr_t); 70138da497aSMark Johnston 70238da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(8, uint8_t); 70338da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(16, uint16_t); 70438da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(32, uint32_t); 70538da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(64, uint64_t); 70638da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(int, u_int); 70738da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(long, u_long); 70838da497aSMark Johnston ASAN_ATOMIC_FUNC_CLEAR(ptr, uintptr_t); 70938da497aSMark Johnston 71038da497aSMark Johnston ASAN_ATOMIC_FUNC_FETCHADD(32, uint32_t); 71138da497aSMark Johnston ASAN_ATOMIC_FUNC_FETCHADD(64, uint64_t); 71238da497aSMark Johnston ASAN_ATOMIC_FUNC_FETCHADD(int, u_int); 71338da497aSMark Johnston ASAN_ATOMIC_FUNC_FETCHADD(long, u_long); 71438da497aSMark Johnston 71538da497aSMark Johnston ASAN_ATOMIC_FUNC_READANDCLEAR(32, uint32_t); 71638da497aSMark Johnston ASAN_ATOMIC_FUNC_READANDCLEAR(64, uint64_t); 71738da497aSMark Johnston ASAN_ATOMIC_FUNC_READANDCLEAR(int, u_int); 71838da497aSMark Johnston ASAN_ATOMIC_FUNC_READANDCLEAR(long, u_long); 71938da497aSMark Johnston ASAN_ATOMIC_FUNC_READANDCLEAR(ptr, uintptr_t); 72038da497aSMark Johnston 72138da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDCLEAR(32, uint32_t); 72238da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDCLEAR(64, uint64_t); 72338da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDCLEAR(int, u_int); 72438da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDCLEAR(long, u_long); 72538da497aSMark Johnston 72638da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDSET(32, uint32_t); 72738da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDSET(64, uint64_t); 72838da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDSET(int, u_int); 72938da497aSMark Johnston ASAN_ATOMIC_FUNC_TESTANDSET(long, u_long); 73038da497aSMark Johnston 73138da497aSMark Johnston ASAN_ATOMIC_FUNC_SWAP(32, uint32_t); 73238da497aSMark Johnston ASAN_ATOMIC_FUNC_SWAP(64, uint64_t); 73338da497aSMark Johnston ASAN_ATOMIC_FUNC_SWAP(int, u_int); 73438da497aSMark Johnston ASAN_ATOMIC_FUNC_SWAP(long, u_long); 73538da497aSMark Johnston ASAN_ATOMIC_FUNC_SWAP(ptr, uintptr_t); 73638da497aSMark Johnston 73738da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(8, uint8_t); 73838da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(16, uint16_t); 73938da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(32, uint32_t); 74038da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(64, uint64_t); 74138da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(int, u_int); 74238da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(long, u_long); 74338da497aSMark Johnston ASAN_ATOMIC_FUNC_CMPSET(ptr, uintptr_t); 74438da497aSMark Johnston 74538da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(8, uint8_t); 74638da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(16, uint16_t); 74738da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(32, uint32_t); 74838da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(64, uint64_t); 74938da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(int, u_int); 75038da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(long, u_long); 75138da497aSMark Johnston ASAN_ATOMIC_FUNC_FCMPSET(ptr, uintptr_t); 75238da497aSMark Johnston 75338da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(8, uint8_t); 75438da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(16, uint16_t); 75538da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(32, uint32_t); 75638da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(64, uint64_t); 75738da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(char, u_char); 75838da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(short, u_short); 75938da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(int, u_int); 76038da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(long, u_long); 76138da497aSMark Johnston ASAN_ATOMIC_FUNC_LOAD(ptr, uintptr_t); 76238da497aSMark Johnston 76338da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(8, uint8_t); 76438da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(16, uint16_t); 76538da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(32, uint32_t); 76638da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(64, uint64_t); 76738da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(char, u_char); 76838da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(short, u_short); 76938da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(int, u_int); 77038da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(long, u_long); 77138da497aSMark Johnston ASAN_ATOMIC_FUNC_STORE(ptr, uintptr_t); 77238da497aSMark Johnston 77338da497aSMark Johnston ASAN_ATOMIC_FUNC_THREAD_FENCE(acq); 77438da497aSMark Johnston ASAN_ATOMIC_FUNC_THREAD_FENCE(rel); 77538da497aSMark Johnston ASAN_ATOMIC_FUNC_THREAD_FENCE(acq_rel); 77638da497aSMark Johnston ASAN_ATOMIC_FUNC_THREAD_FENCE(seq_cst); 77738da497aSMark Johnston 77838da497aSMark Johnston void 77938da497aSMark Johnston kasan_atomic_interrupt_fence(void) 78038da497aSMark Johnston { 78138da497aSMark Johnston } 78238da497aSMark Johnston 78338da497aSMark Johnston /* -------------------------------------------------------------------------- */ 78438da497aSMark Johnston 78538da497aSMark Johnston #include <sys/bus.h> 78638da497aSMark Johnston #include <machine/bus.h> 78738da497aSMark Johnston #define BUS_SAN_PREFIX kasan 78838da497aSMark Johnston #include <sys/bus_san.h> 78938da497aSMark Johnston 79038da497aSMark Johnston int 79138da497aSMark Johnston kasan_bus_space_map(bus_space_tag_t tag, bus_addr_t hnd, bus_size_t size, 79238da497aSMark Johnston int flags, bus_space_handle_t *handlep) 79338da497aSMark Johnston { 79438da497aSMark Johnston return (bus_space_map(tag, hnd, size, flags, handlep)); 79538da497aSMark Johnston } 79638da497aSMark Johnston 79738da497aSMark Johnston void 79838da497aSMark Johnston kasan_bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t hnd, 79938da497aSMark Johnston bus_size_t size) 80038da497aSMark Johnston { 80138da497aSMark Johnston bus_space_unmap(tag, hnd, size); 80238da497aSMark Johnston } 80338da497aSMark Johnston 80438da497aSMark Johnston int 80538da497aSMark Johnston kasan_bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t hnd, 80638da497aSMark Johnston bus_size_t offset, bus_size_t size, bus_space_handle_t *handlep) 80738da497aSMark Johnston { 80838da497aSMark Johnston return (bus_space_subregion(tag, hnd, offset, size, handlep)); 80938da497aSMark Johnston } 81038da497aSMark Johnston 81138da497aSMark Johnston void 81238da497aSMark Johnston kasan_bus_space_free(bus_space_tag_t tag, bus_space_handle_t hnd, 81338da497aSMark Johnston bus_size_t size) 81438da497aSMark Johnston { 81538da497aSMark Johnston bus_space_free(tag, hnd, size); 81638da497aSMark Johnston } 81738da497aSMark Johnston 81838da497aSMark Johnston void 81938da497aSMark Johnston kasan_bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t hnd, 82038da497aSMark Johnston bus_size_t offset, bus_size_t size, int flags) 82138da497aSMark Johnston { 82238da497aSMark Johnston bus_space_barrier(tag, hnd, offset, size, flags); 82338da497aSMark Johnston } 82438da497aSMark Johnston 82538da497aSMark Johnston #define ASAN_BUS_READ_FUNC(func, width, type) \ 82638da497aSMark Johnston type kasan_bus_space_read##func##_##width(bus_space_tag_t tag, \ 82738da497aSMark Johnston bus_space_handle_t hnd, bus_size_t offset) \ 82838da497aSMark Johnston { \ 82938da497aSMark Johnston return (bus_space_read##func##_##width(tag, hnd, \ 83038da497aSMark Johnston offset)); \ 83138da497aSMark Johnston } \ 83238da497aSMark Johnston 83338da497aSMark Johnston #define ASAN_BUS_READ_PTR_FUNC(func, width, type) \ 83438da497aSMark Johnston void kasan_bus_space_read_##func##_##width(bus_space_tag_t tag, \ 83538da497aSMark Johnston bus_space_handle_t hnd, bus_size_t size, type *buf, \ 83638da497aSMark Johnston bus_size_t count) \ 83738da497aSMark Johnston { \ 83838da497aSMark Johnston kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 83938da497aSMark Johnston false, __RET_ADDR); \ 84038da497aSMark Johnston bus_space_read_##func##_##width(tag, hnd, size, buf, \ 84138da497aSMark Johnston count); \ 84238da497aSMark Johnston } 84338da497aSMark Johnston 84438da497aSMark Johnston ASAN_BUS_READ_FUNC(, 1, uint8_t) 84538da497aSMark Johnston ASAN_BUS_READ_FUNC(_stream, 1, uint8_t) 84638da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(multi, 1, uint8_t) 84738da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(multi_stream, 1, uint8_t) 84838da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(region, 1, uint8_t) 84938da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(region_stream, 1, uint8_t) 85038da497aSMark Johnston 85138da497aSMark Johnston ASAN_BUS_READ_FUNC(, 2, uint16_t) 85238da497aSMark Johnston ASAN_BUS_READ_FUNC(_stream, 2, uint16_t) 85338da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(multi, 2, uint16_t) 85438da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(multi_stream, 2, uint16_t) 85538da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(region, 2, uint16_t) 85638da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(region_stream, 2, uint16_t) 85738da497aSMark Johnston 85838da497aSMark Johnston ASAN_BUS_READ_FUNC(, 4, uint32_t) 85938da497aSMark Johnston ASAN_BUS_READ_FUNC(_stream, 4, uint32_t) 86038da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(multi, 4, uint32_t) 86138da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(multi_stream, 4, uint32_t) 86238da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(region, 4, uint32_t) 86338da497aSMark Johnston ASAN_BUS_READ_PTR_FUNC(region_stream, 4, uint32_t) 86438da497aSMark Johnston 86538da497aSMark Johnston ASAN_BUS_READ_FUNC(, 8, uint64_t) 86638da497aSMark Johnston 86738da497aSMark Johnston #define ASAN_BUS_WRITE_FUNC(func, width, type) \ 86838da497aSMark Johnston void kasan_bus_space_write##func##_##width(bus_space_tag_t tag, \ 86938da497aSMark Johnston bus_space_handle_t hnd, bus_size_t offset, type value) \ 87038da497aSMark Johnston { \ 87138da497aSMark Johnston bus_space_write##func##_##width(tag, hnd, offset, value);\ 87238da497aSMark Johnston } \ 87338da497aSMark Johnston 87438da497aSMark Johnston #define ASAN_BUS_WRITE_PTR_FUNC(func, width, type) \ 87538da497aSMark Johnston void kasan_bus_space_write_##func##_##width(bus_space_tag_t tag,\ 87638da497aSMark Johnston bus_space_handle_t hnd, bus_size_t size, const type *buf, \ 87738da497aSMark Johnston bus_size_t count) \ 87838da497aSMark Johnston { \ 87938da497aSMark Johnston kasan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 88038da497aSMark Johnston true, __RET_ADDR); \ 88138da497aSMark Johnston bus_space_write_##func##_##width(tag, hnd, size, buf, \ 88238da497aSMark Johnston count); \ 88338da497aSMark Johnston } 88438da497aSMark Johnston 88538da497aSMark Johnston ASAN_BUS_WRITE_FUNC(, 1, uint8_t) 88638da497aSMark Johnston ASAN_BUS_WRITE_FUNC(_stream, 1, uint8_t) 88738da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(multi, 1, uint8_t) 88838da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 1, uint8_t) 88938da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(region, 1, uint8_t) 89038da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(region_stream, 1, uint8_t) 89138da497aSMark Johnston 89238da497aSMark Johnston ASAN_BUS_WRITE_FUNC(, 2, uint16_t) 89338da497aSMark Johnston ASAN_BUS_WRITE_FUNC(_stream, 2, uint16_t) 89438da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(multi, 2, uint16_t) 89538da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 2, uint16_t) 89638da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(region, 2, uint16_t) 89738da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(region_stream, 2, uint16_t) 89838da497aSMark Johnston 89938da497aSMark Johnston ASAN_BUS_WRITE_FUNC(, 4, uint32_t) 90038da497aSMark Johnston ASAN_BUS_WRITE_FUNC(_stream, 4, uint32_t) 90138da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(multi, 4, uint32_t) 90238da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(multi_stream, 4, uint32_t) 90338da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(region, 4, uint32_t) 90438da497aSMark Johnston ASAN_BUS_WRITE_PTR_FUNC(region_stream, 4, uint32_t) 90538da497aSMark Johnston 90638da497aSMark Johnston ASAN_BUS_WRITE_FUNC(, 8, uint64_t) 90738da497aSMark Johnston 90838da497aSMark Johnston #define ASAN_BUS_SET_FUNC(func, width, type) \ 90938da497aSMark Johnston void kasan_bus_space_set_##func##_##width(bus_space_tag_t tag, \ 91038da497aSMark Johnston bus_space_handle_t hnd, bus_size_t offset, type value, \ 91138da497aSMark Johnston bus_size_t count) \ 91238da497aSMark Johnston { \ 91338da497aSMark Johnston bus_space_set_##func##_##width(tag, hnd, offset, value, \ 91438da497aSMark Johnston count); \ 91538da497aSMark Johnston } 91638da497aSMark Johnston 91738da497aSMark Johnston ASAN_BUS_SET_FUNC(multi, 1, uint8_t) 91838da497aSMark Johnston ASAN_BUS_SET_FUNC(region, 1, uint8_t) 91938da497aSMark Johnston ASAN_BUS_SET_FUNC(multi_stream, 1, uint8_t) 92038da497aSMark Johnston ASAN_BUS_SET_FUNC(region_stream, 1, uint8_t) 92138da497aSMark Johnston 92238da497aSMark Johnston ASAN_BUS_SET_FUNC(multi, 2, uint16_t) 92338da497aSMark Johnston ASAN_BUS_SET_FUNC(region, 2, uint16_t) 92438da497aSMark Johnston ASAN_BUS_SET_FUNC(multi_stream, 2, uint16_t) 92538da497aSMark Johnston ASAN_BUS_SET_FUNC(region_stream, 2, uint16_t) 92638da497aSMark Johnston 92738da497aSMark Johnston ASAN_BUS_SET_FUNC(multi, 4, uint32_t) 92838da497aSMark Johnston ASAN_BUS_SET_FUNC(region, 4, uint32_t) 92938da497aSMark Johnston ASAN_BUS_SET_FUNC(multi_stream, 4, uint32_t) 93038da497aSMark Johnston ASAN_BUS_SET_FUNC(region_stream, 4, uint32_t) 93138da497aSMark Johnston 93238da497aSMark Johnston /* -------------------------------------------------------------------------- */ 93338da497aSMark Johnston 93438da497aSMark Johnston void __asan_register_globals(struct __asan_global *, size_t); 93538da497aSMark Johnston void __asan_unregister_globals(struct __asan_global *, size_t); 93638da497aSMark Johnston 93738da497aSMark Johnston void 93838da497aSMark Johnston __asan_register_globals(struct __asan_global *globals, size_t n) 93938da497aSMark Johnston { 94038da497aSMark Johnston size_t i; 94138da497aSMark Johnston 94238da497aSMark Johnston for (i = 0; i < n; i++) { 94338da497aSMark Johnston kasan_mark(globals[i].beg, globals[i].size, 94438da497aSMark Johnston globals[i].size_with_redzone, KASAN_GENERIC_REDZONE); 94538da497aSMark Johnston } 94638da497aSMark Johnston } 94738da497aSMark Johnston 94838da497aSMark Johnston void 94938da497aSMark Johnston __asan_unregister_globals(struct __asan_global *globals, size_t n) 95038da497aSMark Johnston { 95138da497aSMark Johnston /* never called */ 95238da497aSMark Johnston } 95338da497aSMark Johnston 95438da497aSMark Johnston #define ASAN_LOAD_STORE(size) \ 95538da497aSMark Johnston void __asan_load##size(unsigned long); \ 95638da497aSMark Johnston void __asan_load##size(unsigned long addr) \ 95738da497aSMark Johnston { \ 95838da497aSMark Johnston kasan_shadow_check(addr, size, false, __RET_ADDR);\ 95938da497aSMark Johnston } \ 96038da497aSMark Johnston void __asan_load##size##_noabort(unsigned long); \ 96138da497aSMark Johnston void __asan_load##size##_noabort(unsigned long addr) \ 96238da497aSMark Johnston { \ 96338da497aSMark Johnston kasan_shadow_check(addr, size, false, __RET_ADDR);\ 96438da497aSMark Johnston } \ 96538da497aSMark Johnston void __asan_store##size(unsigned long); \ 96638da497aSMark Johnston void __asan_store##size(unsigned long addr) \ 96738da497aSMark Johnston { \ 96838da497aSMark Johnston kasan_shadow_check(addr, size, true, __RET_ADDR);\ 96938da497aSMark Johnston } \ 97038da497aSMark Johnston void __asan_store##size##_noabort(unsigned long); \ 97138da497aSMark Johnston void __asan_store##size##_noabort(unsigned long addr) \ 97238da497aSMark Johnston { \ 97338da497aSMark Johnston kasan_shadow_check(addr, size, true, __RET_ADDR);\ 97438da497aSMark Johnston } 97538da497aSMark Johnston 97638da497aSMark Johnston ASAN_LOAD_STORE(1); 97738da497aSMark Johnston ASAN_LOAD_STORE(2); 97838da497aSMark Johnston ASAN_LOAD_STORE(4); 97938da497aSMark Johnston ASAN_LOAD_STORE(8); 98038da497aSMark Johnston ASAN_LOAD_STORE(16); 98138da497aSMark Johnston 98238da497aSMark Johnston void __asan_loadN(unsigned long, size_t); 98338da497aSMark Johnston void __asan_loadN_noabort(unsigned long, size_t); 98438da497aSMark Johnston void __asan_storeN(unsigned long, size_t); 98538da497aSMark Johnston void __asan_storeN_noabort(unsigned long, size_t); 98638da497aSMark Johnston void __asan_handle_no_return(void); 98738da497aSMark Johnston 98838da497aSMark Johnston void 98938da497aSMark Johnston __asan_loadN(unsigned long addr, size_t size) 99038da497aSMark Johnston { 99138da497aSMark Johnston kasan_shadow_check(addr, size, false, __RET_ADDR); 99238da497aSMark Johnston } 99338da497aSMark Johnston 99438da497aSMark Johnston void 99538da497aSMark Johnston __asan_loadN_noabort(unsigned long addr, size_t size) 99638da497aSMark Johnston { 99738da497aSMark Johnston kasan_shadow_check(addr, size, false, __RET_ADDR); 99838da497aSMark Johnston } 99938da497aSMark Johnston 100038da497aSMark Johnston void 100138da497aSMark Johnston __asan_storeN(unsigned long addr, size_t size) 100238da497aSMark Johnston { 100338da497aSMark Johnston kasan_shadow_check(addr, size, true, __RET_ADDR); 100438da497aSMark Johnston } 100538da497aSMark Johnston 100638da497aSMark Johnston void 100738da497aSMark Johnston __asan_storeN_noabort(unsigned long addr, size_t size) 100838da497aSMark Johnston { 100938da497aSMark Johnston kasan_shadow_check(addr, size, true, __RET_ADDR); 101038da497aSMark Johnston } 101138da497aSMark Johnston 101238da497aSMark Johnston void 101338da497aSMark Johnston __asan_handle_no_return(void) 101438da497aSMark Johnston { 101538da497aSMark Johnston /* nothing */ 101638da497aSMark Johnston } 101738da497aSMark Johnston 101838da497aSMark Johnston #define ASAN_SET_SHADOW(byte) \ 101938da497aSMark Johnston void __asan_set_shadow_##byte(void *, size_t); \ 102038da497aSMark Johnston void __asan_set_shadow_##byte(void *addr, size_t size) \ 102138da497aSMark Johnston { \ 102238da497aSMark Johnston __builtin_memset((void *)addr, 0x##byte, size); \ 102338da497aSMark Johnston } 102438da497aSMark Johnston 102538da497aSMark Johnston ASAN_SET_SHADOW(00); 102638da497aSMark Johnston ASAN_SET_SHADOW(f1); 102738da497aSMark Johnston ASAN_SET_SHADOW(f2); 102838da497aSMark Johnston ASAN_SET_SHADOW(f3); 102938da497aSMark Johnston ASAN_SET_SHADOW(f5); 103038da497aSMark Johnston ASAN_SET_SHADOW(f8); 103138da497aSMark Johnston 103238da497aSMark Johnston void __asan_poison_stack_memory(const void *, size_t); 103338da497aSMark Johnston void __asan_unpoison_stack_memory(const void *, size_t); 103438da497aSMark Johnston 103538da497aSMark Johnston void 103638da497aSMark Johnston __asan_poison_stack_memory(const void *addr, size_t size) 103738da497aSMark Johnston { 103838da497aSMark Johnston size = roundup(size, KASAN_SHADOW_SCALE); 103938da497aSMark Johnston kasan_shadow_Nbyte_fill(addr, size, KASAN_USE_AFTER_SCOPE); 104038da497aSMark Johnston } 104138da497aSMark Johnston 104238da497aSMark Johnston void 104338da497aSMark Johnston __asan_unpoison_stack_memory(const void *addr, size_t size) 104438da497aSMark Johnston { 104538da497aSMark Johnston kasan_shadow_Nbyte_markvalid(addr, size); 104638da497aSMark Johnston } 104738da497aSMark Johnston 104838da497aSMark Johnston void __asan_alloca_poison(const void *, size_t); 104938da497aSMark Johnston void __asan_allocas_unpoison(const void *, const void *); 105038da497aSMark Johnston 105138da497aSMark Johnston void 105238da497aSMark Johnston __asan_alloca_poison(const void *addr, size_t size) 105338da497aSMark Johnston { 105438da497aSMark Johnston const void *l, *r; 105538da497aSMark Johnston 105638da497aSMark Johnston KASSERT((vm_offset_t)addr % KASAN_ALLOCA_SCALE_SIZE == 0, 105738da497aSMark Johnston ("%s: invalid address %p", __func__, addr)); 105838da497aSMark Johnston 105938da497aSMark Johnston l = (const uint8_t *)addr - KASAN_ALLOCA_SCALE_SIZE; 106038da497aSMark Johnston r = (const uint8_t *)addr + roundup(size, KASAN_ALLOCA_SCALE_SIZE); 106138da497aSMark Johnston 106238da497aSMark Johnston kasan_shadow_Nbyte_fill(l, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_LEFT); 106338da497aSMark Johnston kasan_mark(addr, size, roundup(size, KASAN_ALLOCA_SCALE_SIZE), 106438da497aSMark Johnston KASAN_STACK_MID); 106538da497aSMark Johnston kasan_shadow_Nbyte_fill(r, KASAN_ALLOCA_SCALE_SIZE, KASAN_STACK_RIGHT); 106638da497aSMark Johnston } 106738da497aSMark Johnston 106838da497aSMark Johnston void 106938da497aSMark Johnston __asan_allocas_unpoison(const void *stkbegin, const void *stkend) 107038da497aSMark Johnston { 107138da497aSMark Johnston size_t size; 107238da497aSMark Johnston 107338da497aSMark Johnston if (__predict_false(!stkbegin)) 107438da497aSMark Johnston return; 107538da497aSMark Johnston if (__predict_false((uintptr_t)stkbegin > (uintptr_t)stkend)) 107638da497aSMark Johnston return; 107738da497aSMark Johnston size = (uintptr_t)stkend - (uintptr_t)stkbegin; 107838da497aSMark Johnston 107938da497aSMark Johnston kasan_shadow_Nbyte_fill(stkbegin, size, 0); 108038da497aSMark Johnston } 108138da497aSMark Johnston 108238da497aSMark Johnston void __asan_poison_memory_region(const void *addr, size_t size); 108338da497aSMark Johnston void __asan_unpoison_memory_region(const void *addr, size_t size); 108438da497aSMark Johnston 108538da497aSMark Johnston void 108638da497aSMark Johnston __asan_poison_memory_region(const void *addr, size_t size) 108738da497aSMark Johnston { 108838da497aSMark Johnston } 108938da497aSMark Johnston 109038da497aSMark Johnston void 109138da497aSMark Johnston __asan_unpoison_memory_region(const void *addr, size_t size) 109238da497aSMark Johnston { 109338da497aSMark Johnston } 1094