Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
[linux-2.6-microblaze.git] / mm / kasan / report_tags.c
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 "kasan.h"
8 #include "../slab.h"
9
10 const char *kasan_get_bug_type(struct kasan_access_info *info)
11 {
12 #ifdef CONFIG_KASAN_TAGS_IDENTIFY
13         struct kasan_alloc_meta *alloc_meta;
14         struct kmem_cache *cache;
15         struct page *page;
16         const void *addr;
17         void *object;
18         u8 tag;
19         int i;
20
21         tag = get_tag(info->access_addr);
22         addr = kasan_reset_tag(info->access_addr);
23         page = kasan_addr_to_page(addr);
24         if (page && PageSlab(page)) {
25                 cache = page->slab_cache;
26                 object = nearest_obj(cache, page, (void *)addr);
27                 alloc_meta = kasan_get_alloc_meta(cache, object);
28
29                 if (alloc_meta) {
30                         for (i = 0; i < KASAN_NR_FREE_STACKS; i++) {
31                                 if (alloc_meta->free_pointer_tag[i] == tag)
32                                         return "use-after-free";
33                         }
34                 }
35                 return "out-of-bounds";
36         }
37 #endif
38
39         /*
40          * If access_size is a negative number, then it has reason to be
41          * defined as out-of-bounds bug type.
42          *
43          * Casting negative numbers to size_t would indeed turn up as
44          * a large size_t and its value will be larger than ULONG_MAX/2,
45          * so that this can qualify as out-of-bounds.
46          */
47         if (info->access_addr + info->access_size < info->access_addr)
48                 return "out-of-bounds";
49
50         return "invalid-access";
51 }