cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kasan.h (17691B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __MM_KASAN_KASAN_H
      3#define __MM_KASAN_KASAN_H
      4
      5#include <linux/kasan.h>
      6#include <linux/kasan-tags.h>
      7#include <linux/kfence.h>
      8#include <linux/stackdepot.h>
      9
     10#ifdef CONFIG_KASAN_HW_TAGS
     11
     12#include <linux/static_key.h>
     13#include "../slab.h"
     14
     15DECLARE_STATIC_KEY_TRUE(kasan_flag_vmalloc);
     16DECLARE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
     17
     18enum kasan_mode {
     19	KASAN_MODE_SYNC,
     20	KASAN_MODE_ASYNC,
     21	KASAN_MODE_ASYMM,
     22};
     23
     24extern enum kasan_mode kasan_mode __ro_after_init;
     25
     26static inline bool kasan_vmalloc_enabled(void)
     27{
     28	return static_branch_likely(&kasan_flag_vmalloc);
     29}
     30
     31static inline bool kasan_stack_collection_enabled(void)
     32{
     33	return static_branch_unlikely(&kasan_flag_stacktrace);
     34}
     35
     36static inline bool kasan_async_fault_possible(void)
     37{
     38	return kasan_mode == KASAN_MODE_ASYNC || kasan_mode == KASAN_MODE_ASYMM;
     39}
     40
     41static inline bool kasan_sync_fault_possible(void)
     42{
     43	return kasan_mode == KASAN_MODE_SYNC || kasan_mode == KASAN_MODE_ASYMM;
     44}
     45
     46#else
     47
     48static inline bool kasan_stack_collection_enabled(void)
     49{
     50	return true;
     51}
     52
     53static inline bool kasan_async_fault_possible(void)
     54{
     55	return false;
     56}
     57
     58static inline bool kasan_sync_fault_possible(void)
     59{
     60	return true;
     61}
     62
     63#endif
     64
     65#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
     66#define KASAN_GRANULE_SIZE	(1UL << KASAN_SHADOW_SCALE_SHIFT)
     67#else
     68#include <asm/mte-kasan.h>
     69#define KASAN_GRANULE_SIZE	MTE_GRANULE_SIZE
     70#endif
     71
     72#define KASAN_GRANULE_MASK	(KASAN_GRANULE_SIZE - 1)
     73
     74#define KASAN_MEMORY_PER_SHADOW_PAGE	(KASAN_GRANULE_SIZE << PAGE_SHIFT)
     75
     76#ifdef CONFIG_KASAN_GENERIC
     77#define KASAN_PAGE_FREE		0xFF  /* freed page */
     78#define KASAN_PAGE_REDZONE	0xFE  /* redzone for kmalloc_large allocation */
     79#define KASAN_SLAB_REDZONE	0xFC  /* redzone for slab object */
     80#define KASAN_SLAB_FREE		0xFB  /* freed slab object */
     81#define KASAN_VMALLOC_INVALID	0xF8  /* inaccessible space in vmap area */
     82#else
     83#define KASAN_PAGE_FREE		KASAN_TAG_INVALID
     84#define KASAN_PAGE_REDZONE	KASAN_TAG_INVALID
     85#define KASAN_SLAB_REDZONE	KASAN_TAG_INVALID
     86#define KASAN_SLAB_FREE		KASAN_TAG_INVALID
     87#define KASAN_VMALLOC_INVALID	KASAN_TAG_INVALID /* only used for SW_TAGS */
     88#endif
     89
     90#ifdef CONFIG_KASAN_GENERIC
     91
     92#define KASAN_SLAB_FREETRACK	0xFA  /* freed slab object with free track */
     93#define KASAN_GLOBAL_REDZONE	0xF9  /* redzone for global variable */
     94
     95/* Stack redzone shadow values. Compiler ABI, do not change. */
     96#define KASAN_STACK_LEFT	0xF1
     97#define KASAN_STACK_MID		0xF2
     98#define KASAN_STACK_RIGHT	0xF3
     99#define KASAN_STACK_PARTIAL	0xF4
    100
    101/* alloca redzone shadow values. */
    102#define KASAN_ALLOCA_LEFT	0xCA
    103#define KASAN_ALLOCA_RIGHT	0xCB
    104
    105/* alloca redzone size. Compiler ABI, do not change. */
    106#define KASAN_ALLOCA_REDZONE_SIZE	32
    107
    108/* Stack frame marker. Compiler ABI, do not change. */
    109#define KASAN_CURRENT_STACK_FRAME_MAGIC 0x41B58AB3
    110
    111/* Dummy value to avoid breaking randconfig/all*config builds. */
    112#ifndef KASAN_ABI_VERSION
    113#define KASAN_ABI_VERSION 1
    114#endif
    115
    116#endif /* CONFIG_KASAN_GENERIC */
    117
    118/* Metadata layout customization. */
    119#define META_BYTES_PER_BLOCK 1
    120#define META_BLOCKS_PER_ROW 16
    121#define META_BYTES_PER_ROW (META_BLOCKS_PER_ROW * META_BYTES_PER_BLOCK)
    122#define META_MEM_BYTES_PER_ROW (META_BYTES_PER_ROW * KASAN_GRANULE_SIZE)
    123#define META_ROWS_AROUND_ADDR 2
    124
    125enum kasan_report_type {
    126	KASAN_REPORT_ACCESS,
    127	KASAN_REPORT_INVALID_FREE,
    128};
    129
    130struct kasan_report_info {
    131	enum kasan_report_type type;
    132	void *access_addr;
    133	void *first_bad_addr;
    134	size_t access_size;
    135	bool is_write;
    136	unsigned long ip;
    137};
    138
    139/* Do not change the struct layout: compiler ABI. */
    140struct kasan_source_location {
    141	const char *filename;
    142	int line_no;
    143	int column_no;
    144};
    145
    146/* Do not change the struct layout: compiler ABI. */
    147struct kasan_global {
    148	const void *beg;		/* Address of the beginning of the global variable. */
    149	size_t size;			/* Size of the global variable. */
    150	size_t size_with_redzone;	/* Size of the variable + size of the redzone. 32 bytes aligned. */
    151	const void *name;
    152	const void *module_name;	/* Name of the module where the global variable is declared. */
    153	unsigned long has_dynamic_init;	/* This is needed for C++. */
    154#if KASAN_ABI_VERSION >= 4
    155	struct kasan_source_location *location;
    156#endif
    157#if KASAN_ABI_VERSION >= 5
    158	char *odr_indicator;
    159#endif
    160};
    161
    162/* Structures for keeping alloc and free tracks. */
    163
    164#define KASAN_STACK_DEPTH 64
    165
    166struct kasan_track {
    167	u32 pid;
    168	depot_stack_handle_t stack;
    169};
    170
    171#if defined(CONFIG_KASAN_TAGS_IDENTIFY) && defined(CONFIG_KASAN_SW_TAGS)
    172#define KASAN_NR_FREE_STACKS 5
    173#else
    174#define KASAN_NR_FREE_STACKS 1
    175#endif
    176
    177struct kasan_alloc_meta {
    178	struct kasan_track alloc_track;
    179	/* Generic mode stores free track in kasan_free_meta. */
    180#ifdef CONFIG_KASAN_GENERIC
    181	depot_stack_handle_t aux_stack[2];
    182#else
    183	struct kasan_track free_track[KASAN_NR_FREE_STACKS];
    184#endif
    185#ifdef CONFIG_KASAN_TAGS_IDENTIFY
    186	u8 free_pointer_tag[KASAN_NR_FREE_STACKS];
    187	u8 free_track_idx;
    188#endif
    189};
    190
    191struct qlist_node {
    192	struct qlist_node *next;
    193};
    194
    195/*
    196 * Free meta is stored either in the object itself or in the redzone after the
    197 * object. In the former case, free meta offset is 0. In the latter case, the
    198 * offset is between 0 and INT_MAX. INT_MAX marks that free meta is not present.
    199 */
    200#define KASAN_NO_FREE_META INT_MAX
    201
    202/*
    203 * Free meta is only used by Generic mode while the object is in quarantine.
    204 * After that, slab allocator stores the freelist pointer in the object.
    205 */
    206struct kasan_free_meta {
    207#ifdef CONFIG_KASAN_GENERIC
    208	struct qlist_node quarantine_link;
    209	struct kasan_track free_track;
    210#endif
    211};
    212
    213#if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
    214/* Used in KUnit-compatible KASAN tests. */
    215struct kunit_kasan_status {
    216	bool report_found;
    217	bool sync_fault;
    218};
    219#endif
    220
    221struct kasan_alloc_meta *kasan_get_alloc_meta(struct kmem_cache *cache,
    222						const void *object);
    223#ifdef CONFIG_KASAN_GENERIC
    224struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache,
    225						const void *object);
    226#endif
    227
    228#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
    229
    230static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
    231{
    232	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
    233		<< KASAN_SHADOW_SCALE_SHIFT);
    234}
    235
    236static inline bool addr_has_metadata(const void *addr)
    237{
    238	return (kasan_reset_tag(addr) >=
    239		kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
    240}
    241
    242/**
    243 * kasan_check_range - Check memory region, and report if invalid access.
    244 * @addr: the accessed address
    245 * @size: the accessed size
    246 * @write: true if access is a write access
    247 * @ret_ip: return address
    248 * @return: true if access was valid, false if invalid
    249 */
    250bool kasan_check_range(unsigned long addr, size_t size, bool write,
    251				unsigned long ret_ip);
    252
    253#else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
    254
    255static inline bool addr_has_metadata(const void *addr)
    256{
    257	return (is_vmalloc_addr(addr) || virt_addr_valid(addr));
    258}
    259
    260#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
    261
    262#if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
    263void kasan_print_tags(u8 addr_tag, const void *addr);
    264#else
    265static inline void kasan_print_tags(u8 addr_tag, const void *addr) { }
    266#endif
    267
    268void *kasan_find_first_bad_addr(void *addr, size_t size);
    269const char *kasan_get_bug_type(struct kasan_report_info *info);
    270void kasan_metadata_fetch_row(char *buffer, void *row);
    271
    272#if defined(CONFIG_KASAN_STACK)
    273void kasan_print_address_stack_frame(const void *addr);
    274#else
    275static inline void kasan_print_address_stack_frame(const void *addr) { }
    276#endif
    277
    278bool kasan_report(unsigned long addr, size_t size,
    279		bool is_write, unsigned long ip);
    280void kasan_report_invalid_free(void *object, unsigned long ip);
    281
    282struct page *kasan_addr_to_page(const void *addr);
    283struct slab *kasan_addr_to_slab(const void *addr);
    284
    285depot_stack_handle_t kasan_save_stack(gfp_t flags, bool can_alloc);
    286void kasan_set_track(struct kasan_track *track, gfp_t flags);
    287void kasan_set_free_info(struct kmem_cache *cache, void *object, u8 tag);
    288struct kasan_track *kasan_get_free_track(struct kmem_cache *cache,
    289				void *object, u8 tag);
    290
    291#if defined(CONFIG_KASAN_GENERIC) && \
    292	(defined(CONFIG_SLAB) || defined(CONFIG_SLUB))
    293bool kasan_quarantine_put(struct kmem_cache *cache, void *object);
    294void kasan_quarantine_reduce(void);
    295void kasan_quarantine_remove_cache(struct kmem_cache *cache);
    296#else
    297static inline bool kasan_quarantine_put(struct kmem_cache *cache, void *object) { return false; }
    298static inline void kasan_quarantine_reduce(void) { }
    299static inline void kasan_quarantine_remove_cache(struct kmem_cache *cache) { }
    300#endif
    301
    302#ifndef arch_kasan_set_tag
    303static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
    304{
    305	return addr;
    306}
    307#endif
    308#ifndef arch_kasan_get_tag
    309#define arch_kasan_get_tag(addr)	0
    310#endif
    311
    312#define set_tag(addr, tag)	((void *)arch_kasan_set_tag((addr), (tag)))
    313#define get_tag(addr)		arch_kasan_get_tag(addr)
    314
    315#ifdef CONFIG_KASAN_HW_TAGS
    316
    317#ifndef arch_enable_tagging_sync
    318#define arch_enable_tagging_sync()
    319#endif
    320#ifndef arch_enable_tagging_async
    321#define arch_enable_tagging_async()
    322#endif
    323#ifndef arch_enable_tagging_asymm
    324#define arch_enable_tagging_asymm()
    325#endif
    326#ifndef arch_force_async_tag_fault
    327#define arch_force_async_tag_fault()
    328#endif
    329#ifndef arch_get_random_tag
    330#define arch_get_random_tag()	(0xFF)
    331#endif
    332#ifndef arch_get_mem_tag
    333#define arch_get_mem_tag(addr)	(0xFF)
    334#endif
    335#ifndef arch_set_mem_tag_range
    336#define arch_set_mem_tag_range(addr, size, tag, init) ((void *)(addr))
    337#endif
    338
    339#define hw_enable_tagging_sync()		arch_enable_tagging_sync()
    340#define hw_enable_tagging_async()		arch_enable_tagging_async()
    341#define hw_enable_tagging_asymm()		arch_enable_tagging_asymm()
    342#define hw_force_async_tag_fault()		arch_force_async_tag_fault()
    343#define hw_get_random_tag()			arch_get_random_tag()
    344#define hw_get_mem_tag(addr)			arch_get_mem_tag(addr)
    345#define hw_set_mem_tag_range(addr, size, tag, init) \
    346			arch_set_mem_tag_range((addr), (size), (tag), (init))
    347
    348void kasan_enable_tagging(void);
    349
    350#else /* CONFIG_KASAN_HW_TAGS */
    351
    352#define hw_enable_tagging_sync()
    353#define hw_enable_tagging_async()
    354#define hw_enable_tagging_asymm()
    355
    356static inline void kasan_enable_tagging(void) { }
    357
    358#endif /* CONFIG_KASAN_HW_TAGS */
    359
    360#if defined(CONFIG_KASAN_HW_TAGS) && IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
    361
    362void kasan_force_async_fault(void);
    363
    364#else /* CONFIG_KASAN_HW_TAGS && CONFIG_KASAN_KUNIT_TEST */
    365
    366static inline void kasan_force_async_fault(void) { }
    367
    368#endif /* CONFIG_KASAN_HW_TAGS && CONFIG_KASAN_KUNIT_TEST */
    369
    370#ifdef CONFIG_KASAN_SW_TAGS
    371u8 kasan_random_tag(void);
    372#elif defined(CONFIG_KASAN_HW_TAGS)
    373static inline u8 kasan_random_tag(void) { return hw_get_random_tag(); }
    374#else
    375static inline u8 kasan_random_tag(void) { return 0; }
    376#endif
    377
    378#ifdef CONFIG_KASAN_HW_TAGS
    379
    380static inline void kasan_poison(const void *addr, size_t size, u8 value, bool init)
    381{
    382	addr = kasan_reset_tag(addr);
    383
    384	/* Skip KFENCE memory if called explicitly outside of sl*b. */
    385	if (is_kfence_address(addr))
    386		return;
    387
    388	if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
    389		return;
    390	if (WARN_ON(size & KASAN_GRANULE_MASK))
    391		return;
    392
    393	hw_set_mem_tag_range((void *)addr, size, value, init);
    394}
    395
    396static inline void kasan_unpoison(const void *addr, size_t size, bool init)
    397{
    398	u8 tag = get_tag(addr);
    399
    400	addr = kasan_reset_tag(addr);
    401
    402	/* Skip KFENCE memory if called explicitly outside of sl*b. */
    403	if (is_kfence_address(addr))
    404		return;
    405
    406	if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
    407		return;
    408	/*
    409	 * Explicitly initialize the memory with the precise object size to
    410	 * avoid overwriting the slab redzone. This disables initialization in
    411	 * the arch code and may thus lead to performance penalty. This penalty
    412	 * does not affect production builds, as slab redzones are not enabled
    413	 * there.
    414	 */
    415	if (__slub_debug_enabled() &&
    416	    init && ((unsigned long)size & KASAN_GRANULE_MASK)) {
    417		init = false;
    418		memzero_explicit((void *)addr, size);
    419	}
    420	size = round_up(size, KASAN_GRANULE_SIZE);
    421
    422	hw_set_mem_tag_range((void *)addr, size, tag, init);
    423}
    424
    425static inline bool kasan_byte_accessible(const void *addr)
    426{
    427	u8 ptr_tag = get_tag(addr);
    428	u8 mem_tag = hw_get_mem_tag((void *)addr);
    429
    430	return ptr_tag == KASAN_TAG_KERNEL || ptr_tag == mem_tag;
    431}
    432
    433#else /* CONFIG_KASAN_HW_TAGS */
    434
    435/**
    436 * kasan_poison - mark the memory range as inaccessible
    437 * @addr - range start address, must be aligned to KASAN_GRANULE_SIZE
    438 * @size - range size, must be aligned to KASAN_GRANULE_SIZE
    439 * @value - value that's written to metadata for the range
    440 * @init - whether to initialize the memory range (only for hardware tag-based)
    441 *
    442 * The size gets aligned to KASAN_GRANULE_SIZE before marking the range.
    443 */
    444void kasan_poison(const void *addr, size_t size, u8 value, bool init);
    445
    446/**
    447 * kasan_unpoison - mark the memory range as accessible
    448 * @addr - range start address, must be aligned to KASAN_GRANULE_SIZE
    449 * @size - range size, can be unaligned
    450 * @init - whether to initialize the memory range (only for hardware tag-based)
    451 *
    452 * For the tag-based modes, the @size gets aligned to KASAN_GRANULE_SIZE before
    453 * marking the range.
    454 * For the generic mode, the last granule of the memory range gets partially
    455 * unpoisoned based on the @size.
    456 */
    457void kasan_unpoison(const void *addr, size_t size, bool init);
    458
    459bool kasan_byte_accessible(const void *addr);
    460
    461#endif /* CONFIG_KASAN_HW_TAGS */
    462
    463#ifdef CONFIG_KASAN_GENERIC
    464
    465/**
    466 * kasan_poison_last_granule - mark the last granule of the memory range as
    467 * inaccessible
    468 * @addr - range start address, must be aligned to KASAN_GRANULE_SIZE
    469 * @size - range size
    470 *
    471 * This function is only available for the generic mode, as it's the only mode
    472 * that has partially poisoned memory granules.
    473 */
    474void kasan_poison_last_granule(const void *address, size_t size);
    475
    476#else /* CONFIG_KASAN_GENERIC */
    477
    478static inline void kasan_poison_last_granule(const void *address, size_t size) { }
    479
    480#endif /* CONFIG_KASAN_GENERIC */
    481
    482#ifndef kasan_arch_is_ready
    483static inline bool kasan_arch_is_ready(void)	{ return true; }
    484#elif !defined(CONFIG_KASAN_GENERIC) || !defined(CONFIG_KASAN_OUTLINE)
    485#error kasan_arch_is_ready only works in KASAN generic outline mode!
    486#endif
    487
    488#if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) || IS_ENABLED(CONFIG_KASAN_MODULE_TEST)
    489
    490bool kasan_save_enable_multi_shot(void);
    491void kasan_restore_multi_shot(bool enabled);
    492
    493#endif
    494
    495/*
    496 * Exported functions for interfaces called from assembly or from generated
    497 * code. Declared here to avoid warnings about missing declarations.
    498 */
    499
    500asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
    501void __asan_register_globals(struct kasan_global *globals, size_t size);
    502void __asan_unregister_globals(struct kasan_global *globals, size_t size);
    503void __asan_handle_no_return(void);
    504void __asan_alloca_poison(unsigned long addr, size_t size);
    505void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
    506
    507void __asan_load1(unsigned long addr);
    508void __asan_store1(unsigned long addr);
    509void __asan_load2(unsigned long addr);
    510void __asan_store2(unsigned long addr);
    511void __asan_load4(unsigned long addr);
    512void __asan_store4(unsigned long addr);
    513void __asan_load8(unsigned long addr);
    514void __asan_store8(unsigned long addr);
    515void __asan_load16(unsigned long addr);
    516void __asan_store16(unsigned long addr);
    517void __asan_loadN(unsigned long addr, size_t size);
    518void __asan_storeN(unsigned long addr, size_t size);
    519
    520void __asan_load1_noabort(unsigned long addr);
    521void __asan_store1_noabort(unsigned long addr);
    522void __asan_load2_noabort(unsigned long addr);
    523void __asan_store2_noabort(unsigned long addr);
    524void __asan_load4_noabort(unsigned long addr);
    525void __asan_store4_noabort(unsigned long addr);
    526void __asan_load8_noabort(unsigned long addr);
    527void __asan_store8_noabort(unsigned long addr);
    528void __asan_load16_noabort(unsigned long addr);
    529void __asan_store16_noabort(unsigned long addr);
    530void __asan_loadN_noabort(unsigned long addr, size_t size);
    531void __asan_storeN_noabort(unsigned long addr, size_t size);
    532
    533void __asan_report_load1_noabort(unsigned long addr);
    534void __asan_report_store1_noabort(unsigned long addr);
    535void __asan_report_load2_noabort(unsigned long addr);
    536void __asan_report_store2_noabort(unsigned long addr);
    537void __asan_report_load4_noabort(unsigned long addr);
    538void __asan_report_store4_noabort(unsigned long addr);
    539void __asan_report_load8_noabort(unsigned long addr);
    540void __asan_report_store8_noabort(unsigned long addr);
    541void __asan_report_load16_noabort(unsigned long addr);
    542void __asan_report_store16_noabort(unsigned long addr);
    543void __asan_report_load_n_noabort(unsigned long addr, size_t size);
    544void __asan_report_store_n_noabort(unsigned long addr, size_t size);
    545
    546void __asan_set_shadow_00(const void *addr, size_t size);
    547void __asan_set_shadow_f1(const void *addr, size_t size);
    548void __asan_set_shadow_f2(const void *addr, size_t size);
    549void __asan_set_shadow_f3(const void *addr, size_t size);
    550void __asan_set_shadow_f5(const void *addr, size_t size);
    551void __asan_set_shadow_f8(const void *addr, size_t size);
    552
    553void __hwasan_load1_noabort(unsigned long addr);
    554void __hwasan_store1_noabort(unsigned long addr);
    555void __hwasan_load2_noabort(unsigned long addr);
    556void __hwasan_store2_noabort(unsigned long addr);
    557void __hwasan_load4_noabort(unsigned long addr);
    558void __hwasan_store4_noabort(unsigned long addr);
    559void __hwasan_load8_noabort(unsigned long addr);
    560void __hwasan_store8_noabort(unsigned long addr);
    561void __hwasan_load16_noabort(unsigned long addr);
    562void __hwasan_store16_noabort(unsigned long addr);
    563void __hwasan_loadN_noabort(unsigned long addr, size_t size);
    564void __hwasan_storeN_noabort(unsigned long addr, size_t size);
    565
    566void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
    567
    568#endif /* __MM_KASAN_KASAN_H */