Commit | Line | Data |
---|---|---|
2e903b91 AK |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * This file contains hardware tag-based KASAN specific error reporting code. | |
4 | * | |
5 | * Copyright (c) 2020 Google, Inc. | |
6 | * Author: Andrey Konovalov <andreyknvl@google.com> | |
7 | */ | |
8 | ||
9 | #include <linux/kasan.h> | |
10 | #include <linux/kernel.h> | |
11 | #include <linux/memory.h> | |
12 | #include <linux/mm.h> | |
13 | #include <linux/string.h> | |
14 | #include <linux/types.h> | |
15 | ||
16 | #include "kasan.h" | |
17 | ||
f00748bf | 18 | void *kasan_find_first_bad_addr(void *addr, size_t size) |
2e903b91 | 19 | { |
8f17febb KYL |
20 | /* |
21 | * Hardware Tag-Based KASAN only calls this function for normal memory | |
22 | * accesses, and thus addr points precisely to the first bad address | |
23 | * with an invalid (and present) memory tag. Therefore: | |
24 | * 1. Return the address as is without walking memory tags. | |
25 | * 2. Skip the addr_has_metadata check. | |
26 | */ | |
c0054c56 | 27 | return kasan_reset_tag(addr); |
2e903b91 AK |
28 | } |
29 | ||
8f17febb KYL |
30 | size_t kasan_get_alloc_size(void *object, struct kmem_cache *cache) |
31 | { | |
32 | size_t size = 0; | |
33 | int i = 0; | |
34 | u8 memory_tag; | |
35 | ||
36 | /* | |
37 | * Skip the addr_has_metadata check, as this function only operates on | |
38 | * slab memory, which must have metadata. | |
39 | */ | |
40 | ||
41 | /* | |
42 | * The loop below returns 0 for freed objects, for which KASAN cannot | |
43 | * calculate the allocation size based on the metadata. | |
44 | */ | |
45 | while (size < cache->object_size) { | |
46 | memory_tag = hw_get_mem_tag(object + i * KASAN_GRANULE_SIZE); | |
47 | if (memory_tag != KASAN_TAG_INVALID) | |
48 | size += KASAN_GRANULE_SIZE; | |
49 | else | |
50 | return size; | |
51 | i++; | |
52 | } | |
53 | ||
54 | return cache->object_size; | |
55 | } | |
56 | ||
f00748bf | 57 | void kasan_metadata_fetch_row(char *buffer, void *row) |
2e903b91 AK |
58 | { |
59 | int i; | |
60 | ||
61 | for (i = 0; i < META_BYTES_PER_ROW; i++) | |
62 | buffer[i] = hw_get_mem_tag(row + i * KASAN_GRANULE_SIZE); | |
63 | } | |
64 | ||
f00748bf | 65 | void kasan_print_tags(u8 addr_tag, const void *addr) |
2e903b91 AK |
66 | { |
67 | u8 memory_tag = hw_get_mem_tag((void *)addr); | |
68 | ||
69 | pr_err("Pointer tag: [%02x], memory tag: [%02x]\n", | |
70 | addr_tag, memory_tag); | |
71 | } |