| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * This file contains common tag-based KASAN code. |
| * |
| * Copyright (c) 2018 Google, Inc. |
| * Copyright (c) 2020 Google, Inc. |
| */ |
| |
| #include <linux/init.h> |
| #include <linux/kasan.h> |
| #include <linux/kernel.h> |
| #include <linux/memory.h> |
| #include <linux/mm.h> |
| #include <linux/static_key.h> |
| #include <linux/string.h> |
| #include <linux/types.h> |
| |
| #include "kasan.h" |
| |
| void kasan_set_free_info(struct kmem_cache *cache, |
| void *object, u8 tag) |
| { |
| struct kasan_alloc_meta *alloc_meta; |
| u8 idx = 0; |
| |
| alloc_meta = kasan_get_alloc_meta(cache, object); |
| if (!alloc_meta) |
| return; |
| |
| #ifdef CONFIG_KASAN_TAGS_IDENTIFY |
| idx = alloc_meta->free_track_idx; |
| alloc_meta->free_pointer_tag[idx] = tag; |
| alloc_meta->free_track_idx = (idx + 1) % KASAN_NR_FREE_STACKS; |
| #endif |
| |
| kasan_set_track(&alloc_meta->free_track[idx], GFP_NOWAIT); |
| } |
| |
| struct kasan_track *kasan_get_free_track(struct kmem_cache *cache, |
| void *object, u8 tag) |
| { |
| struct kasan_alloc_meta *alloc_meta; |
| int i = 0; |
| |
| alloc_meta = kasan_get_alloc_meta(cache, object); |
| if (!alloc_meta) |
| return NULL; |
| |
| #ifdef CONFIG_KASAN_TAGS_IDENTIFY |
| for (i = 0; i < KASAN_NR_FREE_STACKS; i++) { |
| if (alloc_meta->free_pointer_tag[i] == tag) |
| break; |
| } |
| if (i == KASAN_NR_FREE_STACKS) |
| i = alloc_meta->free_track_idx; |
| #endif |
| |
| return &alloc_meta->free_track[i]; |
| } |