162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * This file contains generic KASAN specific error reporting code. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2014 Samsung Electronics Co., Ltd. 662306a36Sopenharmony_ci * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Some code borrowed from https://github.com/xairy/kasan-prototype by 962306a36Sopenharmony_ci * Andrey Konovalov <andreyknvl@gmail.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/bitops.h> 1362306a36Sopenharmony_ci#include <linux/ftrace.h> 1462306a36Sopenharmony_ci#include <linux/init.h> 1562306a36Sopenharmony_ci#include <linux/kernel.h> 1662306a36Sopenharmony_ci#include <linux/mm.h> 1762306a36Sopenharmony_ci#include <linux/printk.h> 1862306a36Sopenharmony_ci#include <linux/sched.h> 1962306a36Sopenharmony_ci#include <linux/sched/task_stack.h> 2062306a36Sopenharmony_ci#include <linux/slab.h> 2162306a36Sopenharmony_ci#include <linux/stackdepot.h> 2262306a36Sopenharmony_ci#include <linux/stacktrace.h> 2362306a36Sopenharmony_ci#include <linux/string.h> 2462306a36Sopenharmony_ci#include <linux/types.h> 2562306a36Sopenharmony_ci#include <linux/kasan.h> 2662306a36Sopenharmony_ci#include <linux/module.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <asm/sections.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include "kasan.h" 3162306a36Sopenharmony_ci#include "../slab.h" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ciconst void *kasan_find_first_bad_addr(const void *addr, size_t size) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci const void *p = addr; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci if (!addr_has_metadata(p)) 3862306a36Sopenharmony_ci return p; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci while (p < addr + size && !(*(u8 *)kasan_mem_to_shadow(p))) 4162306a36Sopenharmony_ci p += KASAN_GRANULE_SIZE; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci return p; 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cisize_t kasan_get_alloc_size(void *object, struct kmem_cache *cache) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci size_t size = 0; 4962306a36Sopenharmony_ci u8 *shadow; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci /* 5262306a36Sopenharmony_ci * Skip the addr_has_metadata check, as this function only operates on 5362306a36Sopenharmony_ci * slab memory, which must have metadata. 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* 5762306a36Sopenharmony_ci * The loop below returns 0 for freed objects, for which KASAN cannot 5862306a36Sopenharmony_ci * calculate the allocation size based on the metadata. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci shadow = (u8 *)kasan_mem_to_shadow(object); 6162306a36Sopenharmony_ci while (size < cache->object_size) { 6262306a36Sopenharmony_ci if (*shadow == 0) 6362306a36Sopenharmony_ci size += KASAN_GRANULE_SIZE; 6462306a36Sopenharmony_ci else if (*shadow >= 1 && *shadow <= KASAN_GRANULE_SIZE - 1) 6562306a36Sopenharmony_ci return size + *shadow; 6662306a36Sopenharmony_ci else 6762306a36Sopenharmony_ci return size; 6862306a36Sopenharmony_ci shadow++; 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci return cache->object_size; 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic const char *get_shadow_bug_type(struct kasan_report_info *info) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci const char *bug_type = "unknown-crash"; 7762306a36Sopenharmony_ci u8 *shadow_addr; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci shadow_addr = (u8 *)kasan_mem_to_shadow(info->first_bad_addr); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci /* 8262306a36Sopenharmony_ci * If shadow byte value is in [0, KASAN_GRANULE_SIZE) we can look 8362306a36Sopenharmony_ci * at the next shadow byte to determine the type of the bad access. 8462306a36Sopenharmony_ci */ 8562306a36Sopenharmony_ci if (*shadow_addr > 0 && *shadow_addr <= KASAN_GRANULE_SIZE - 1) 8662306a36Sopenharmony_ci shadow_addr++; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci switch (*shadow_addr) { 8962306a36Sopenharmony_ci case 0 ... KASAN_GRANULE_SIZE - 1: 9062306a36Sopenharmony_ci /* 9162306a36Sopenharmony_ci * In theory it's still possible to see these shadow values 9262306a36Sopenharmony_ci * due to a data race in the kernel code. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci bug_type = "out-of-bounds"; 9562306a36Sopenharmony_ci break; 9662306a36Sopenharmony_ci case KASAN_PAGE_REDZONE: 9762306a36Sopenharmony_ci case KASAN_SLAB_REDZONE: 9862306a36Sopenharmony_ci bug_type = "slab-out-of-bounds"; 9962306a36Sopenharmony_ci break; 10062306a36Sopenharmony_ci case KASAN_GLOBAL_REDZONE: 10162306a36Sopenharmony_ci bug_type = "global-out-of-bounds"; 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci case KASAN_STACK_LEFT: 10462306a36Sopenharmony_ci case KASAN_STACK_MID: 10562306a36Sopenharmony_ci case KASAN_STACK_RIGHT: 10662306a36Sopenharmony_ci case KASAN_STACK_PARTIAL: 10762306a36Sopenharmony_ci bug_type = "stack-out-of-bounds"; 10862306a36Sopenharmony_ci break; 10962306a36Sopenharmony_ci case KASAN_PAGE_FREE: 11062306a36Sopenharmony_ci bug_type = "use-after-free"; 11162306a36Sopenharmony_ci break; 11262306a36Sopenharmony_ci case KASAN_SLAB_FREE: 11362306a36Sopenharmony_ci case KASAN_SLAB_FREETRACK: 11462306a36Sopenharmony_ci bug_type = "slab-use-after-free"; 11562306a36Sopenharmony_ci break; 11662306a36Sopenharmony_ci case KASAN_ALLOCA_LEFT: 11762306a36Sopenharmony_ci case KASAN_ALLOCA_RIGHT: 11862306a36Sopenharmony_ci bug_type = "alloca-out-of-bounds"; 11962306a36Sopenharmony_ci break; 12062306a36Sopenharmony_ci case KASAN_VMALLOC_INVALID: 12162306a36Sopenharmony_ci bug_type = "vmalloc-out-of-bounds"; 12262306a36Sopenharmony_ci break; 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci return bug_type; 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic const char *get_wild_bug_type(struct kasan_report_info *info) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci const char *bug_type = "unknown-crash"; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci if ((unsigned long)info->access_addr < PAGE_SIZE) 13362306a36Sopenharmony_ci bug_type = "null-ptr-deref"; 13462306a36Sopenharmony_ci else if ((unsigned long)info->access_addr < TASK_SIZE) 13562306a36Sopenharmony_ci bug_type = "user-memory-access"; 13662306a36Sopenharmony_ci else 13762306a36Sopenharmony_ci bug_type = "wild-memory-access"; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci return bug_type; 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic const char *get_bug_type(struct kasan_report_info *info) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci /* 14562306a36Sopenharmony_ci * If access_size is a negative number, then it has reason to be 14662306a36Sopenharmony_ci * defined as out-of-bounds bug type. 14762306a36Sopenharmony_ci * 14862306a36Sopenharmony_ci * Casting negative numbers to size_t would indeed turn up as 14962306a36Sopenharmony_ci * a large size_t and its value will be larger than ULONG_MAX/2, 15062306a36Sopenharmony_ci * so that this can qualify as out-of-bounds. 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_ci if (info->access_addr + info->access_size < info->access_addr) 15362306a36Sopenharmony_ci return "out-of-bounds"; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (addr_has_metadata(info->access_addr)) 15662306a36Sopenharmony_ci return get_shadow_bug_type(info); 15762306a36Sopenharmony_ci return get_wild_bug_type(info); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_civoid kasan_complete_mode_report_info(struct kasan_report_info *info) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci struct kasan_alloc_meta *alloc_meta; 16362306a36Sopenharmony_ci struct kasan_free_meta *free_meta; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci if (!info->bug_type) 16662306a36Sopenharmony_ci info->bug_type = get_bug_type(info); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci if (!info->cache || !info->object) 16962306a36Sopenharmony_ci return; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci alloc_meta = kasan_get_alloc_meta(info->cache, info->object); 17262306a36Sopenharmony_ci if (alloc_meta) 17362306a36Sopenharmony_ci memcpy(&info->alloc_track, &alloc_meta->alloc_track, 17462306a36Sopenharmony_ci sizeof(info->alloc_track)); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci if (*(u8 *)kasan_mem_to_shadow(info->object) == KASAN_SLAB_FREETRACK) { 17762306a36Sopenharmony_ci /* Free meta must be present with KASAN_SLAB_FREETRACK. */ 17862306a36Sopenharmony_ci free_meta = kasan_get_free_meta(info->cache, info->object); 17962306a36Sopenharmony_ci memcpy(&info->free_track, &free_meta->free_track, 18062306a36Sopenharmony_ci sizeof(info->free_track)); 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_civoid kasan_metadata_fetch_row(char *buffer, void *row) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci memcpy(buffer, kasan_mem_to_shadow(row), META_BYTES_PER_ROW); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_civoid kasan_print_aux_stacks(struct kmem_cache *cache, const void *object) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci struct kasan_alloc_meta *alloc_meta; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci alloc_meta = kasan_get_alloc_meta(cache, object); 19462306a36Sopenharmony_ci if (!alloc_meta) 19562306a36Sopenharmony_ci return; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci if (alloc_meta->aux_stack[0]) { 19862306a36Sopenharmony_ci pr_err("Last potentially related work creation:\n"); 19962306a36Sopenharmony_ci stack_depot_print(alloc_meta->aux_stack[0]); 20062306a36Sopenharmony_ci pr_err("\n"); 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci if (alloc_meta->aux_stack[1]) { 20362306a36Sopenharmony_ci pr_err("Second to last potentially related work creation:\n"); 20462306a36Sopenharmony_ci stack_depot_print(alloc_meta->aux_stack[1]); 20562306a36Sopenharmony_ci pr_err("\n"); 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#ifdef CONFIG_KASAN_STACK 21062306a36Sopenharmony_cistatic bool __must_check tokenize_frame_descr(const char **frame_descr, 21162306a36Sopenharmony_ci char *token, size_t max_tok_len, 21262306a36Sopenharmony_ci unsigned long *value) 21362306a36Sopenharmony_ci{ 21462306a36Sopenharmony_ci const char *sep = strchr(*frame_descr, ' '); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci if (sep == NULL) 21762306a36Sopenharmony_ci sep = *frame_descr + strlen(*frame_descr); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (token != NULL) { 22062306a36Sopenharmony_ci const size_t tok_len = sep - *frame_descr; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci if (tok_len + 1 > max_tok_len) { 22362306a36Sopenharmony_ci pr_err("KASAN internal error: frame description too long: %s\n", 22462306a36Sopenharmony_ci *frame_descr); 22562306a36Sopenharmony_ci return false; 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci /* Copy token (+ 1 byte for '\0'). */ 22962306a36Sopenharmony_ci strscpy(token, *frame_descr, tok_len + 1); 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* Advance frame_descr past separator. */ 23362306a36Sopenharmony_ci *frame_descr = sep + 1; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci if (value != NULL && kstrtoul(token, 10, value)) { 23662306a36Sopenharmony_ci pr_err("KASAN internal error: not a valid number: %s\n", token); 23762306a36Sopenharmony_ci return false; 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci return true; 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic void print_decoded_frame_descr(const char *frame_descr) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci /* 24662306a36Sopenharmony_ci * We need to parse the following string: 24762306a36Sopenharmony_ci * "n alloc_1 alloc_2 ... alloc_n" 24862306a36Sopenharmony_ci * where alloc_i looks like 24962306a36Sopenharmony_ci * "offset size len name" 25062306a36Sopenharmony_ci * or "offset size len name:line". 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci char token[64]; 25462306a36Sopenharmony_ci unsigned long num_objects; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), 25762306a36Sopenharmony_ci &num_objects)) 25862306a36Sopenharmony_ci return; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci pr_err("\n"); 26162306a36Sopenharmony_ci pr_err("This frame has %lu %s:\n", num_objects, 26262306a36Sopenharmony_ci num_objects == 1 ? "object" : "objects"); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci while (num_objects--) { 26562306a36Sopenharmony_ci unsigned long offset; 26662306a36Sopenharmony_ci unsigned long size; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci /* access offset */ 26962306a36Sopenharmony_ci if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), 27062306a36Sopenharmony_ci &offset)) 27162306a36Sopenharmony_ci return; 27262306a36Sopenharmony_ci /* access size */ 27362306a36Sopenharmony_ci if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), 27462306a36Sopenharmony_ci &size)) 27562306a36Sopenharmony_ci return; 27662306a36Sopenharmony_ci /* name length (unused) */ 27762306a36Sopenharmony_ci if (!tokenize_frame_descr(&frame_descr, NULL, 0, NULL)) 27862306a36Sopenharmony_ci return; 27962306a36Sopenharmony_ci /* object name */ 28062306a36Sopenharmony_ci if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), 28162306a36Sopenharmony_ci NULL)) 28262306a36Sopenharmony_ci return; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* Strip line number; without filename it's not very helpful. */ 28562306a36Sopenharmony_ci strreplace(token, ':', '\0'); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci /* Finally, print object information. */ 28862306a36Sopenharmony_ci pr_err(" [%lu, %lu) '%s'", offset, offset + size, token); 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci} 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci/* Returns true only if the address is on the current task's stack. */ 29362306a36Sopenharmony_cistatic bool __must_check get_address_stack_frame_info(const void *addr, 29462306a36Sopenharmony_ci unsigned long *offset, 29562306a36Sopenharmony_ci const char **frame_descr, 29662306a36Sopenharmony_ci const void **frame_pc) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci unsigned long aligned_addr; 29962306a36Sopenharmony_ci unsigned long mem_ptr; 30062306a36Sopenharmony_ci const u8 *shadow_bottom; 30162306a36Sopenharmony_ci const u8 *shadow_ptr; 30262306a36Sopenharmony_ci const unsigned long *frame; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci BUILD_BUG_ON(IS_ENABLED(CONFIG_STACK_GROWSUP)); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci aligned_addr = round_down((unsigned long)addr, sizeof(long)); 30762306a36Sopenharmony_ci mem_ptr = round_down(aligned_addr, KASAN_GRANULE_SIZE); 30862306a36Sopenharmony_ci shadow_ptr = kasan_mem_to_shadow((void *)aligned_addr); 30962306a36Sopenharmony_ci shadow_bottom = kasan_mem_to_shadow(end_of_stack(current)); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci while (shadow_ptr >= shadow_bottom && *shadow_ptr != KASAN_STACK_LEFT) { 31262306a36Sopenharmony_ci shadow_ptr--; 31362306a36Sopenharmony_ci mem_ptr -= KASAN_GRANULE_SIZE; 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci while (shadow_ptr >= shadow_bottom && *shadow_ptr == KASAN_STACK_LEFT) { 31762306a36Sopenharmony_ci shadow_ptr--; 31862306a36Sopenharmony_ci mem_ptr -= KASAN_GRANULE_SIZE; 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci if (shadow_ptr < shadow_bottom) 32262306a36Sopenharmony_ci return false; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci frame = (const unsigned long *)(mem_ptr + KASAN_GRANULE_SIZE); 32562306a36Sopenharmony_ci if (frame[0] != KASAN_CURRENT_STACK_FRAME_MAGIC) { 32662306a36Sopenharmony_ci pr_err("KASAN internal error: frame info validation failed; invalid marker: %lu\n", 32762306a36Sopenharmony_ci frame[0]); 32862306a36Sopenharmony_ci return false; 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci *offset = (unsigned long)addr - (unsigned long)frame; 33262306a36Sopenharmony_ci *frame_descr = (const char *)frame[1]; 33362306a36Sopenharmony_ci *frame_pc = (void *)frame[2]; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci return true; 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_civoid kasan_print_address_stack_frame(const void *addr) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci unsigned long offset; 34162306a36Sopenharmony_ci const char *frame_descr; 34262306a36Sopenharmony_ci const void *frame_pc; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci if (WARN_ON(!object_is_on_stack(addr))) 34562306a36Sopenharmony_ci return; 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci pr_err("The buggy address belongs to stack of task %s/%d\n", 34862306a36Sopenharmony_ci current->comm, task_pid_nr(current)); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci if (!get_address_stack_frame_info(addr, &offset, &frame_descr, 35162306a36Sopenharmony_ci &frame_pc)) 35262306a36Sopenharmony_ci return; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci pr_err(" and is located at offset %lu in frame:\n", offset); 35562306a36Sopenharmony_ci pr_err(" %pS\n", frame_pc); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci if (!frame_descr) 35862306a36Sopenharmony_ci return; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci print_decoded_frame_descr(frame_descr); 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci#endif /* CONFIG_KASAN_STACK */ 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci#define DEFINE_ASAN_REPORT_LOAD(size) \ 36562306a36Sopenharmony_civoid __asan_report_load##size##_noabort(void *addr) \ 36662306a36Sopenharmony_ci{ \ 36762306a36Sopenharmony_ci kasan_report(addr, size, false, _RET_IP_); \ 36862306a36Sopenharmony_ci} \ 36962306a36Sopenharmony_ciEXPORT_SYMBOL(__asan_report_load##size##_noabort) 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci#define DEFINE_ASAN_REPORT_STORE(size) \ 37262306a36Sopenharmony_civoid __asan_report_store##size##_noabort(void *addr) \ 37362306a36Sopenharmony_ci{ \ 37462306a36Sopenharmony_ci kasan_report(addr, size, true, _RET_IP_); \ 37562306a36Sopenharmony_ci} \ 37662306a36Sopenharmony_ciEXPORT_SYMBOL(__asan_report_store##size##_noabort) 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ciDEFINE_ASAN_REPORT_LOAD(1); 37962306a36Sopenharmony_ciDEFINE_ASAN_REPORT_LOAD(2); 38062306a36Sopenharmony_ciDEFINE_ASAN_REPORT_LOAD(4); 38162306a36Sopenharmony_ciDEFINE_ASAN_REPORT_LOAD(8); 38262306a36Sopenharmony_ciDEFINE_ASAN_REPORT_LOAD(16); 38362306a36Sopenharmony_ciDEFINE_ASAN_REPORT_STORE(1); 38462306a36Sopenharmony_ciDEFINE_ASAN_REPORT_STORE(2); 38562306a36Sopenharmony_ciDEFINE_ASAN_REPORT_STORE(4); 38662306a36Sopenharmony_ciDEFINE_ASAN_REPORT_STORE(8); 38762306a36Sopenharmony_ciDEFINE_ASAN_REPORT_STORE(16); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_civoid __asan_report_load_n_noabort(void *addr, ssize_t size) 39062306a36Sopenharmony_ci{ 39162306a36Sopenharmony_ci kasan_report(addr, size, false, _RET_IP_); 39262306a36Sopenharmony_ci} 39362306a36Sopenharmony_ciEXPORT_SYMBOL(__asan_report_load_n_noabort); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_civoid __asan_report_store_n_noabort(void *addr, ssize_t size) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci kasan_report(addr, size, true, _RET_IP_); 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ciEXPORT_SYMBOL(__asan_report_store_n_noabort); 400