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