1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 4 * Copyright (c) 2020 Google, Inc. 5 */ 6 7 #include <linux/atomic.h> 8 9 #include "kasan.h" 10 11 extern struct kasan_stack_ring stack_ring; 12 13 static const char *get_common_bug_type(struct kasan_report_info *info) 14 { 15 /* 16 * If access_size is a negative number, then it has reason to be 17 * defined as out-of-bounds bug type. 18 * 19 * Casting negative numbers to size_t would indeed turn up as 20 * a large size_t and its value will be larger than ULONG_MAX/2, 21 * so that this can qualify as out-of-bounds. 22 */ 23 if (info->access_addr + info->access_size < info->access_addr) 24 return "out-of-bounds"; 25 26 return "invalid-access"; 27 } 28 29 void kasan_complete_mode_report_info(struct kasan_report_info *info) 30 { 31 unsigned long flags; 32 u64 pos; 33 struct kasan_stack_ring_entry *entry; 34 void *ptr; 35 u32 pid; 36 depot_stack_handle_t stack; 37 bool is_free; 38 bool alloc_found = false, free_found = false; 39 40 if ((!info->cache || !info->object) && !info->bug_type) { 41 info->bug_type = get_common_bug_type(info); 42 return; 43 } 44 45 write_lock_irqsave(&stack_ring.lock, flags); 46 47 pos = atomic64_read(&stack_ring.pos); 48 49 /* 50 * The loop below tries to find stack ring entries relevant to the 51 * buggy object. This is a best-effort process. 52 * 53 * First, another object with the same tag can be allocated in place of 54 * the buggy object. Also, since the number of entries is limited, the 55 * entries relevant to the buggy object can be overwritten. 56 */ 57 58 for (u64 i = pos - 1; i != pos - 1 - stack_ring.size; i--) { 59 if (alloc_found && free_found) 60 break; 61 62 entry = &stack_ring.entries[i % stack_ring.size]; 63 64 /* Paired with smp_store_release() in save_stack_info(). */ 65 ptr = (void *)smp_load_acquire(&entry->ptr); 66 67 if (kasan_reset_tag(ptr) != info->object || 68 get_tag(ptr) != get_tag(info->access_addr)) 69 continue; 70 71 pid = READ_ONCE(entry->pid); 72 stack = READ_ONCE(entry->stack); 73 is_free = READ_ONCE(entry->is_free); 74 75 if (is_free) { 76 /* 77 * Second free of the same object. 78 * Give up on trying to find the alloc entry. 79 */ 80 if (free_found) 81 break; 82 83 info->free_track.pid = pid; 84 info->free_track.stack = stack; 85 free_found = true; 86 87 /* 88 * If a free entry is found first, the bug is likely 89 * a use-after-free. 90 */ 91 if (!info->bug_type) 92 info->bug_type = "slab-use-after-free"; 93 } else { 94 /* Second alloc of the same object. Give up. */ 95 if (alloc_found) 96 break; 97 98 info->alloc_track.pid = pid; 99 info->alloc_track.stack = stack; 100 alloc_found = true; 101 102 /* 103 * If an alloc entry is found first, the bug is likely 104 * an out-of-bounds. 105 */ 106 if (!info->bug_type) 107 info->bug_type = "slab-out-of-bounds"; 108 } 109 } 110 111 write_unlock_irqrestore(&stack_ring.lock, flags); 112 113 /* Assign the common bug type if no entries were found. */ 114 if (!info->bug_type) 115 info->bug_type = get_common_bug_type(info); 116 } 117