Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Kernel Electric-Fence (KFENCE). For more info please see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Documentation/dev-tools/kfence.rst.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2020, Google LLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #ifndef MM_KFENCE_KFENCE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define MM_KFENCE_KFENCE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "../slab.h" /* for struct kmem_cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Get the canary byte pattern for @addr. Use a pattern that varies based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * lower 3 bits of the address, to detect memory corruptions with higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * probability, where similar constants are used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define KFENCE_CANARY_PATTERN(addr) ((u8)0xaa ^ (u8)((unsigned long)(addr) & 0x7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* Maximum stack depth for reports. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define KFENCE_STACK_DEPTH 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* KFENCE object states. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) enum kfence_object_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	KFENCE_OBJECT_UNUSED,		/* Object is unused. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	KFENCE_OBJECT_ALLOCATED,	/* Object is currently allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	KFENCE_OBJECT_FREED,		/* Object was allocated, and then freed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) /* Alloc/free tracking information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) struct kfence_track {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	int num_stack_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	unsigned long stack_entries[KFENCE_STACK_DEPTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /* KFENCE metadata per guarded allocation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) struct kfence_metadata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct list_head list;		/* Freelist node; access under kfence_freelist_lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct rcu_head rcu_head;	/* For delayed freeing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 * Lock protecting below data; to ensure consistency of the below data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 * since the following may execute concurrently: __kfence_alloc(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 * __kfence_free(), kfence_handle_page_fault(). However, note that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	 * cannot grab the same metadata off the freelist twice, and multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	 * __kfence_alloc() cannot run concurrently on the same metadata.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	raw_spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	/* The current state of the object; see above. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	enum kfence_object_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	 * Allocated object address; cannot be calculated from size, because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	 * alignment requirements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	 * Invariant: ALIGN_DOWN(addr, PAGE_SIZE) is constant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * The size of the original allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	 * The kmem_cache cache of the last allocation; NULL if never allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	 * or the cache has already been destroyed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct kmem_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 * In case of an invalid access, the page that was unprotected; we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * optimistically only store one address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	unsigned long unprotected_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	/* Allocation and free stack information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct kfence_track alloc_track;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct kfence_track free_track;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) extern struct kfence_metadata kfence_metadata[CONFIG_KFENCE_NUM_OBJECTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) /* KFENCE error types for report generation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) enum kfence_error_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	KFENCE_ERROR_OOB,		/* Detected a out-of-bounds access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	KFENCE_ERROR_UAF,		/* Detected a use-after-free access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	KFENCE_ERROR_CORRUPTION,	/* Detected a memory corruption on free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	KFENCE_ERROR_INVALID,		/* Invalid access of unknown type. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	KFENCE_ERROR_INVALID_FREE,	/* Invalid free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void kfence_report_error(unsigned long address, bool is_write, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			 const struct kfence_metadata *meta, enum kfence_error_type type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void kfence_print_object(struct seq_file *seq, const struct kfence_metadata *meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif /* MM_KFENCE_KFENCE_H */