1 // SPDX-License-Identifier: GPL-2.0
3 * This file contains core hardware tag-based KASAN code.
5 * Copyright (c) 2020 Google, Inc.
6 * Author: Andrey Konovalov <andreyknvl@google.com>
9 #define pr_fmt(fmt) "kasan: " fmt
11 #include <linux/kasan.h>
12 #include <linux/kernel.h>
13 #include <linux/memory.h>
15 #include <linux/string.h>
16 #include <linux/types.h>
20 /* kasan_init_hw_tags_cpu() is called for each CPU. */
21 void kasan_init_hw_tags_cpu(void)
23 hw_init_tags(KASAN_TAG_MAX);
27 /* kasan_init_hw_tags() is called once on boot CPU. */
28 void __init kasan_init_hw_tags(void)
30 pr_info("KernelAddressSanitizer initialized\n");
33 void poison_range(const void *address, size_t size, u8 value)
35 hw_set_mem_tag_range(kasan_reset_tag(address),
36 round_up(size, KASAN_GRANULE_SIZE), value);
39 void unpoison_range(const void *address, size_t size)
41 hw_set_mem_tag_range(kasan_reset_tag(address),
42 round_up(size, KASAN_GRANULE_SIZE), get_tag(address));
45 bool check_invalid_free(void *addr)
47 u8 ptr_tag = get_tag(addr);
48 u8 mem_tag = hw_get_mem_tag(addr);
50 return (mem_tag == KASAN_TAG_INVALID) ||
51 (ptr_tag != KASAN_TAG_KERNEL && ptr_tag != mem_tag);
54 void kasan_set_free_info(struct kmem_cache *cache,
57 struct kasan_alloc_meta *alloc_meta;
59 alloc_meta = kasan_get_alloc_meta(cache, object);
60 kasan_set_track(&alloc_meta->free_track[0], GFP_NOWAIT);
63 struct kasan_track *kasan_get_free_track(struct kmem_cache *cache,
66 struct kasan_alloc_meta *alloc_meta;
68 alloc_meta = kasan_get_alloc_meta(cache, object);
69 return &alloc_meta->free_track[0];