xref: /OK3568_Linux_fs/kernel/include/linux/kfence.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Kernel Electric-Fence (KFENCE). Public interface for allocator and fault
4*4882a593Smuzhiyun  * handler integration. For more info see Documentation/dev-tools/kfence.rst.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2020, Google LLC.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _LINUX_KFENCE_H
10*4882a593Smuzhiyun #define _LINUX_KFENCE_H
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/mm.h>
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #ifdef CONFIG_KFENCE
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun /*
18*4882a593Smuzhiyun  * We allocate an even number of pages, as it simplifies calculations to map
19*4882a593Smuzhiyun  * address to metadata indices; effectively, the very first page serves as an
20*4882a593Smuzhiyun  * extended guard page, but otherwise has no special purpose.
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun #define KFENCE_POOL_SIZE ((CONFIG_KFENCE_NUM_OBJECTS + 1) * 2 * PAGE_SIZE)
23*4882a593Smuzhiyun extern char *__kfence_pool;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #ifdef CONFIG_KFENCE_STATIC_KEYS
26*4882a593Smuzhiyun #include <linux/static_key.h>
27*4882a593Smuzhiyun DECLARE_STATIC_KEY_FALSE(kfence_allocation_key);
28*4882a593Smuzhiyun #else
29*4882a593Smuzhiyun #include <linux/atomic.h>
30*4882a593Smuzhiyun extern atomic_t kfence_allocation_gate;
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /**
34*4882a593Smuzhiyun  * is_kfence_address() - check if an address belongs to KFENCE pool
35*4882a593Smuzhiyun  * @addr: address to check
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * Return: true or false depending on whether the address is within the KFENCE
38*4882a593Smuzhiyun  * object range.
39*4882a593Smuzhiyun  *
40*4882a593Smuzhiyun  * KFENCE objects live in a separate page range and are not to be intermixed
41*4882a593Smuzhiyun  * with regular heap objects (e.g. KFENCE objects must never be added to the
42*4882a593Smuzhiyun  * allocator freelists). Failing to do so may and will result in heap
43*4882a593Smuzhiyun  * corruptions, therefore is_kfence_address() must be used to check whether
44*4882a593Smuzhiyun  * an object requires specific handling.
45*4882a593Smuzhiyun  *
46*4882a593Smuzhiyun  * Note: This function may be used in fast-paths, and is performance critical.
47*4882a593Smuzhiyun  * Future changes should take this into account; for instance, we want to avoid
48*4882a593Smuzhiyun  * introducing another load and therefore need to keep KFENCE_POOL_SIZE a
49*4882a593Smuzhiyun  * constant (until immediate patching support is added to the kernel).
50*4882a593Smuzhiyun  */
is_kfence_address(const void * addr)51*4882a593Smuzhiyun static __always_inline bool is_kfence_address(const void *addr)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	/*
54*4882a593Smuzhiyun 	 * The __kfence_pool != NULL check is required to deal with the case
55*4882a593Smuzhiyun 	 * where __kfence_pool == NULL && addr < KFENCE_POOL_SIZE. Keep it in
56*4882a593Smuzhiyun 	 * the slow-path after the range-check!
57*4882a593Smuzhiyun 	 */
58*4882a593Smuzhiyun 	return unlikely((unsigned long)((char *)addr - __kfence_pool) < KFENCE_POOL_SIZE && __kfence_pool);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /**
62*4882a593Smuzhiyun  * kfence_alloc_pool() - allocate the KFENCE pool via memblock
63*4882a593Smuzhiyun  */
64*4882a593Smuzhiyun void __init kfence_alloc_pool(void);
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /**
67*4882a593Smuzhiyun  * kfence_init() - perform KFENCE initialization at boot time
68*4882a593Smuzhiyun  *
69*4882a593Smuzhiyun  * Requires that kfence_alloc_pool() was called before. This sets up the
70*4882a593Smuzhiyun  * allocation gate timer, and requires that workqueues are available.
71*4882a593Smuzhiyun  */
72*4882a593Smuzhiyun void __init kfence_init(void);
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun /**
75*4882a593Smuzhiyun  * kfence_shutdown_cache() - handle shutdown_cache() for KFENCE objects
76*4882a593Smuzhiyun  * @s: cache being shut down
77*4882a593Smuzhiyun  *
78*4882a593Smuzhiyun  * Before shutting down a cache, one must ensure there are no remaining objects
79*4882a593Smuzhiyun  * allocated from it. Because KFENCE objects are not referenced from the cache
80*4882a593Smuzhiyun  * directly, we need to check them here.
81*4882a593Smuzhiyun  *
82*4882a593Smuzhiyun  * Note that shutdown_cache() is internal to SL*B, and kmem_cache_destroy() does
83*4882a593Smuzhiyun  * not return if allocated objects still exist: it prints an error message and
84*4882a593Smuzhiyun  * simply aborts destruction of a cache, leaking memory.
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  * If the only such objects are KFENCE objects, we will not leak the entire
87*4882a593Smuzhiyun  * cache, but instead try to provide more useful debug info by making allocated
88*4882a593Smuzhiyun  * objects "zombie allocations". Objects may then still be used or freed (which
89*4882a593Smuzhiyun  * is handled gracefully), but usage will result in showing KFENCE error reports
90*4882a593Smuzhiyun  * which include stack traces to the user of the object, the original allocation
91*4882a593Smuzhiyun  * site, and caller to shutdown_cache().
92*4882a593Smuzhiyun  */
93*4882a593Smuzhiyun void kfence_shutdown_cache(struct kmem_cache *s);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun /*
96*4882a593Smuzhiyun  * Allocate a KFENCE object. Allocators must not call this function directly,
97*4882a593Smuzhiyun  * use kfence_alloc() instead.
98*4882a593Smuzhiyun  */
99*4882a593Smuzhiyun void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /**
102*4882a593Smuzhiyun  * kfence_alloc() - allocate a KFENCE object with a low probability
103*4882a593Smuzhiyun  * @s:     struct kmem_cache with object requirements
104*4882a593Smuzhiyun  * @size:  exact size of the object to allocate (can be less than @s->size
105*4882a593Smuzhiyun  *         e.g. for kmalloc caches)
106*4882a593Smuzhiyun  * @flags: GFP flags
107*4882a593Smuzhiyun  *
108*4882a593Smuzhiyun  * Return:
109*4882a593Smuzhiyun  * * NULL     - must proceed with allocating as usual,
110*4882a593Smuzhiyun  * * non-NULL - pointer to a KFENCE object.
111*4882a593Smuzhiyun  *
112*4882a593Smuzhiyun  * kfence_alloc() should be inserted into the heap allocation fast path,
113*4882a593Smuzhiyun  * allowing it to transparently return KFENCE-allocated objects with a low
114*4882a593Smuzhiyun  * probability using a static branch (the probability is controlled by the
115*4882a593Smuzhiyun  * kfence.sample_interval boot parameter).
116*4882a593Smuzhiyun  */
kfence_alloc(struct kmem_cache * s,size_t size,gfp_t flags)117*4882a593Smuzhiyun static __always_inline void *kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun #ifdef CONFIG_KFENCE_STATIC_KEYS
120*4882a593Smuzhiyun 	if (static_branch_unlikely(&kfence_allocation_key))
121*4882a593Smuzhiyun #else
122*4882a593Smuzhiyun 	if (unlikely(!atomic_read(&kfence_allocation_gate)))
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun 		return __kfence_alloc(s, size, flags);
125*4882a593Smuzhiyun 	return NULL;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun /**
129*4882a593Smuzhiyun  * kfence_ksize() - get actual amount of memory allocated for a KFENCE object
130*4882a593Smuzhiyun  * @addr: pointer to a heap object
131*4882a593Smuzhiyun  *
132*4882a593Smuzhiyun  * Return:
133*4882a593Smuzhiyun  * * 0     - not a KFENCE object, must call __ksize() instead,
134*4882a593Smuzhiyun  * * non-0 - this many bytes can be accessed without causing a memory error.
135*4882a593Smuzhiyun  *
136*4882a593Smuzhiyun  * kfence_ksize() returns the number of bytes requested for a KFENCE object at
137*4882a593Smuzhiyun  * allocation time. This number may be less than the object size of the
138*4882a593Smuzhiyun  * corresponding struct kmem_cache.
139*4882a593Smuzhiyun  */
140*4882a593Smuzhiyun size_t kfence_ksize(const void *addr);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun /**
143*4882a593Smuzhiyun  * kfence_object_start() - find the beginning of a KFENCE object
144*4882a593Smuzhiyun  * @addr: address within a KFENCE-allocated object
145*4882a593Smuzhiyun  *
146*4882a593Smuzhiyun  * Return: address of the beginning of the object.
147*4882a593Smuzhiyun  *
148*4882a593Smuzhiyun  * SL[AU]B-allocated objects are laid out within a page one by one, so it is
149*4882a593Smuzhiyun  * easy to calculate the beginning of an object given a pointer inside it and
150*4882a593Smuzhiyun  * the object size. The same is not true for KFENCE, which places a single
151*4882a593Smuzhiyun  * object at either end of the page. This helper function is used to find the
152*4882a593Smuzhiyun  * beginning of a KFENCE-allocated object.
153*4882a593Smuzhiyun  */
154*4882a593Smuzhiyun void *kfence_object_start(const void *addr);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun /**
157*4882a593Smuzhiyun  * __kfence_free() - release a KFENCE heap object to KFENCE pool
158*4882a593Smuzhiyun  * @addr: object to be freed
159*4882a593Smuzhiyun  *
160*4882a593Smuzhiyun  * Requires: is_kfence_address(addr)
161*4882a593Smuzhiyun  *
162*4882a593Smuzhiyun  * Release a KFENCE object and mark it as freed.
163*4882a593Smuzhiyun  */
164*4882a593Smuzhiyun void __kfence_free(void *addr);
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /**
167*4882a593Smuzhiyun  * kfence_free() - try to release an arbitrary heap object to KFENCE pool
168*4882a593Smuzhiyun  * @addr: object to be freed
169*4882a593Smuzhiyun  *
170*4882a593Smuzhiyun  * Return:
171*4882a593Smuzhiyun  * * false - object doesn't belong to KFENCE pool and was ignored,
172*4882a593Smuzhiyun  * * true  - object was released to KFENCE pool.
173*4882a593Smuzhiyun  *
174*4882a593Smuzhiyun  * Release a KFENCE object and mark it as freed. May be called on any object,
175*4882a593Smuzhiyun  * even non-KFENCE objects, to simplify integration of the hooks into the
176*4882a593Smuzhiyun  * allocator's free codepath. The allocator must check the return value to
177*4882a593Smuzhiyun  * determine if it was a KFENCE object or not.
178*4882a593Smuzhiyun  */
kfence_free(void * addr)179*4882a593Smuzhiyun static __always_inline __must_check bool kfence_free(void *addr)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	if (!is_kfence_address(addr))
182*4882a593Smuzhiyun 		return false;
183*4882a593Smuzhiyun 	__kfence_free(addr);
184*4882a593Smuzhiyun 	return true;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun /**
188*4882a593Smuzhiyun  * kfence_handle_page_fault() - perform page fault handling for KFENCE pages
189*4882a593Smuzhiyun  * @addr: faulting address
190*4882a593Smuzhiyun  * @is_write: is access a write
191*4882a593Smuzhiyun  * @regs: current struct pt_regs (can be NULL, but shows full stack trace)
192*4882a593Smuzhiyun  *
193*4882a593Smuzhiyun  * Return:
194*4882a593Smuzhiyun  * * false - address outside KFENCE pool,
195*4882a593Smuzhiyun  * * true  - page fault handled by KFENCE, no additional handling required.
196*4882a593Smuzhiyun  *
197*4882a593Smuzhiyun  * A page fault inside KFENCE pool indicates a memory error, such as an
198*4882a593Smuzhiyun  * out-of-bounds access, a use-after-free or an invalid memory access. In these
199*4882a593Smuzhiyun  * cases KFENCE prints an error message and marks the offending page as
200*4882a593Smuzhiyun  * present, so that the kernel can proceed.
201*4882a593Smuzhiyun  */
202*4882a593Smuzhiyun bool __must_check kfence_handle_page_fault(unsigned long addr, bool is_write, struct pt_regs *regs);
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun #else /* CONFIG_KFENCE */
205*4882a593Smuzhiyun 
is_kfence_address(const void * addr)206*4882a593Smuzhiyun static inline bool is_kfence_address(const void *addr) { return false; }
kfence_alloc_pool(void)207*4882a593Smuzhiyun static inline void kfence_alloc_pool(void) { }
kfence_init(void)208*4882a593Smuzhiyun static inline void kfence_init(void) { }
kfence_shutdown_cache(struct kmem_cache * s)209*4882a593Smuzhiyun static inline void kfence_shutdown_cache(struct kmem_cache *s) { }
kfence_alloc(struct kmem_cache * s,size_t size,gfp_t flags)210*4882a593Smuzhiyun static inline void *kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) { return NULL; }
kfence_ksize(const void * addr)211*4882a593Smuzhiyun static inline size_t kfence_ksize(const void *addr) { return 0; }
kfence_object_start(const void * addr)212*4882a593Smuzhiyun static inline void *kfence_object_start(const void *addr) { return NULL; }
__kfence_free(void * addr)213*4882a593Smuzhiyun static inline void __kfence_free(void *addr) { }
kfence_free(void * addr)214*4882a593Smuzhiyun static inline bool __must_check kfence_free(void *addr) { return false; }
kfence_handle_page_fault(unsigned long addr,bool is_write,struct pt_regs * regs)215*4882a593Smuzhiyun static inline bool __must_check kfence_handle_page_fault(unsigned long addr, bool is_write,
216*4882a593Smuzhiyun 							 struct pt_regs *regs)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	return false;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun #endif
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun #endif /* _LINUX_KFENCE_H */
224