xref: /xnu-11417.101.15/osfmk/kern/kalloc.h (revision e3723e1f17661b24996789d8afc084c0c3303b26)
1 /*
2  * Copyright (c) 2000-2021 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 /*
32  * Mach Operating System
33  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34  * All Rights Reserved.
35  *
36  * Permission to use, copy, modify and distribute this software and its
37  * documentation is hereby granted, provided that both the copyright
38  * notice and this permission notice appear in all copies of the
39  * software, derivative works or modified versions, and any portions
40  * thereof, and that both notices appear in supporting documentation.
41  *
42  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45  *
46  * Carnegie Mellon requests users of this software to return to
47  *
48  *  Software Distribution Coordinator  or  [email protected]
49  *  School of Computer Science
50  *  Carnegie Mellon University
51  *  Pittsburgh PA 15213-3890
52  *
53  * any improvements or extensions that they make and grant Carnegie Mellon
54  * the rights to redistribute these changes.
55  */
56 
57 #ifdef  KERNEL_PRIVATE
58 
59 #ifndef _KERN_KALLOC_H_
60 #define _KERN_KALLOC_H_
61 
62 #include <mach/machine/vm_types.h>
63 #include <mach/boolean.h>
64 #include <mach/vm_types.h>
65 #include <kern/zalloc.h>
66 #include <libkern/section_keywords.h>
67 #include <os/alloc_util.h>
68 #if XNU_KERNEL_PRIVATE
69 #include <kern/counter.h>
70 #endif /* XNU_KERNEL_PRIVATE */
71 
72 __BEGIN_DECLS __ASSUME_PTR_ABI_SINGLE_BEGIN
73 
74 /*!
75  * @const KALLOC_SAFE_ALLOC_SIZE
76  *
77  * @brief
78  * The maximum allocation size that is safe to allocate with Z_NOFAIL in kalloc.
79  */
80 #define KALLOC_SAFE_ALLOC_SIZE  (16u * 1024u)
81 
82 #if XNU_KERNEL_PRIVATE
83 /*!
84  * @typedef kalloc_heap_t
85  *
86  * @abstract
87  * A kalloc heap view represents a sub-accounting context
88  * for a given kalloc heap.
89  */
90 typedef struct kalloc_heap {
91 	zone_stats_t        kh_stats;
92 	const char         *__unsafe_indexable kh_name;
93 	zone_kheap_id_t     kh_heap_id;
94 	vm_tag_t            kh_tag;
95 	uint16_t            kh_type_hash;
96 	zone_id_t           kh_zstart;
97 	struct kalloc_heap *kh_views;
98 } *kalloc_heap_t;
99 
100 /*!
101  * @macro KALLOC_HEAP_DECLARE
102  *
103  * @abstract
104  * (optionally) declare a kalloc heap view in a header.
105  *
106  * @discussion
107  * Unlike kernel zones, new full blown heaps cannot be instantiated.
108  * However new accounting views of the base heaps can be made.
109  */
110 #define KALLOC_HEAP_DECLARE(var) \
111 	extern struct kalloc_heap var[1]
112 
113 /**
114  * @const KHEAP_DATA_BUFFERS
115  *
116  * @brief
117  * The builtin heap for bags of pure bytes.
118  *
119  * @discussion
120  * This set of kalloc zones should contain pure bags of bytes with no pointers
121  * or length/offset fields.
122  *
123  * The zones forming the heap aren't sequestered from each other, however the
124  * entire heap lives in a different submap from any other kernel allocation.
125  *
126  * The main motivation behind this separation is due to the fact that a lot of
127  * these objects have been used by attackers to spray the heap to make it more
128  * predictable while exploiting use-after-frees or overflows.
129  *
130  * Common attributes that make these objects useful for spraying includes
131  * control of:
132  * - Data in allocation
133  * - Time of alloc and free (lifetime)
134  * - Size of allocation
135  */
136 KALLOC_HEAP_DECLARE(KHEAP_DATA_BUFFERS);
137 
138 /**
139  * @const KHEAP_DATA_SHARED
140  *
141  * @brief
142  * The builtin heap for bags of pure bytes that get shared across components.
143  *
144  * @discussion
145  * There's a further distinction that we can make between kalloc zones that
146  * contain bag of bytes, which is based on their intended use. In particular
147  * a number of pure data allocations are intended to be shared between kernel
148  * and user or kernel and coprocessors (DMA). These allocations cannot
149  * sustain the security XNU_KERNEL_RESTRICTED checks, therefore we isolate
150  * them in a separated heap, to further increase the security guarantees
151  * around KHEAP_DATA_BUFFERS.
152  */
153 KALLOC_HEAP_DECLARE(KHEAP_DATA_SHARED);
154 
155 /**
156  * @const KHEAP_DEFAULT
157  *
158  * @brief
159  * The builtin default core kernel kalloc heap.
160  *
161  * @discussion
162  * This set of kalloc zones should contain other objects that don't have their
163  * own security mitigations. The individual zones are themselves sequestered.
164  */
165 KALLOC_HEAP_DECLARE(KHEAP_DEFAULT);
166 
167 /**
168  * @const KHEAP_KT_VAR
169  *
170  * @brief
171  * Temporary heap for variable sized kalloc type allocations
172  *
173  * @discussion
174  * This heap will be removed when logic for kalloc_type_var_views is added
175  *
176  */
177 KALLOC_HEAP_DECLARE(KHEAP_KT_VAR);
178 
179 /*!
180  * @macro KALLOC_HEAP_DEFINE
181  *
182  * @abstract
183  * Defines a given kalloc heap view and what it points to.
184  *
185  * @discussion
186  * Kalloc heaps are views over one of the pre-defined builtin heaps
187  * (such as @c KHEAP_DATA_BUFFERS or @c KHEAP_DEFAULT). Instantiating
188  * a new one allows for accounting of allocations through this view.
189  *
190  * Kalloc heap views are initialized during the @c STARTUP_SUB_ZALLOC phase,
191  * as the last rank. If views on zones are created, these must have been
192  * created before this stage.
193  *
194  * @param var           the name for the zone view.
195  * @param name          a string describing the zone view.
196  * @param heap_id       a @c KHEAP_ID_* constant.
197  */
198 #define KALLOC_HEAP_DEFINE(var, name, heap_id) \
199 	SECURITY_READ_ONLY_LATE(struct kalloc_heap) var[1] = { { \
200 	    .kh_name = (name), \
201 	    .kh_heap_id = (heap_id), \
202 	} }; \
203 	STARTUP_ARG(ZALLOC, STARTUP_RANK_MIDDLE, kheap_startup_init, var)
204 
205 
206 /*
207  * Allocations of type SO_NAME are known to not have pointers for
208  * most platforms -- for macOS this is not guaranteed
209  */
210 #if XNU_TARGET_OS_OSX
211 #define KHEAP_SONAME KHEAP_DEFAULT
212 #else /* XNU_TARGET_OS_OSX */
213 #define KHEAP_SONAME KHEAP_DATA_BUFFERS
214 #endif /* XNU_TARGET_OS_OSX */
215 
216 #endif /* XNU_KERNEL_PRIVATE */
217 
218 /*!
219  * @enum kalloc_type_flags_t
220  *
221  * @brief
222  * Flags that can be passed to @c KALLOC_TYPE_DEFINE
223  *
224  * @discussion
225  * These flags can be used to request for a specific accounting
226  * behavior.
227  *
228  * @const KT_DEFAULT
229  * Passing this flag will provide default accounting behavior
230  * i.e shared accounting unless toggled with KT_OPTIONS_ACCT is
231  * set in kt boot-arg.
232  *
233  * @const KT_PRIV_ACCT
234  * Passing this flag will provide individual stats for your
235  * @c kalloc_type_view that is defined.
236  *
237  * @const KT_SHARED_ACCT
238  * Passing this flag will accumulate stats as a part of the
239  * zone that your @c kalloc_type_view points to.
240  *
241  * @const KT_DATA_ONLY
242  * Represents that the type is "data-only". Adopters should not
243  * set this flag manually, it is meant for the compiler to set
244  * automatically when KALLOC_TYPE_CHECK(DATA) passes.
245  *
246  * @const KT_VM
247  * Represents that the type is large enough to use the VM. Adopters
248  * should not set this flag manually, it is meant for the compiler
249  * to set automatically when KALLOC_TYPE_VM_SIZE_CHECK passes.
250  *
251  * @const KT_PTR_ARRAY
252  * Represents that the type is an array of pointers. Adopters should not
253  * set this flag manually, it is meant for the compiler to set
254  * automatically when KALLOC_TYPE_CHECK(PTR) passes.
255  *
256  * @const KT_CHANGED*
257  * Represents a change in the version of the kalloc_type_view. This
258  * is required inorder to decouple requiring kexts to be rebuilt to
259  * use the new defintions right away. This flags should not be used
260  * manually at a callsite, it is meant for internal use only. Future
261  * changes to kalloc_type_view defintion should toggle this flag.
262  *
263  #if XNU_KERNEL_PRIVATE
264  * @const KT_NOEARLY
265  * This flags will force the callsite to bypass the early (shared) zone and
266  * directly allocate from the assigned zone. This can only be used
267  * with KT_PRIV_ACCT right now. If you still require this behavior
268  * but don't want private stats use Z_SET_NOTEARLY at the allocation
269  * callsite instead.
270  *
271  * @const KT_SLID
272  * To indicate that strings in the view were slid during early boot.
273  *
274  * @const KT_PROCESSED
275  * This flag is set once the view is parse during early boot. Views
276  * that are not in BootKC on macOS aren't parsed and therefore will
277  * not have this flag set. The runtime can use this as an indication
278  * to appropriately redirect the call.
279  *
280  * @const KT_HASH
281  * Hash of signature used by kmem_*_guard to determine range and
282  * direction for allocation
283  #endif
284  */
285 __options_decl(kalloc_type_flags_t, uint32_t, {
286 	KT_DEFAULT        = 0x0001,
287 	KT_PRIV_ACCT      = 0x0002,
288 	KT_SHARED_ACCT    = 0x0004,
289 	KT_DATA_ONLY      = 0x0008,
290 	KT_VM             = 0x0010,
291 	KT_CHANGED        = 0x0020,
292 	KT_CHANGED2       = 0x0040,
293 	KT_PTR_ARRAY      = 0x0080,
294 #if XNU_KERNEL_PRIVATE
295 	KT_NOEARLY       = 0x2000,
296 	KT_SLID           = 0x4000,
297 	KT_PROCESSED      = 0x8000,
298 	KT_HASH           = 0xffff0000,
299 #endif
300 });
301 
302 /*!
303  * @typedef kalloc_type_view_t
304  *
305  * @abstract
306  * A kalloc type view is a structure used to redirect callers
307  * of @c kalloc_type to a particular zone based on the signature of
308  * their type.
309  *
310  * @discussion
311  * These structures are automatically created under the hood for every
312  * @c kalloc_type and @c kfree_type callsite. They are ingested during startup
313  * and are assigned zones based on the security policy for their signature.
314  *
315  * These structs are protected by the kernel lockdown and can't be initialized
316  * dynamically. They must be created using @c KALLOC_TYPE_DEFINE() or
317  * @c kalloc_type or @c kfree_type.
318  *
319  */
320 #if XNU_KERNEL_PRIVATE
321 struct kalloc_type_view {
322 	struct zone_view        kt_zv;
323 	const char             *kt_signature __unsafe_indexable;
324 	kalloc_type_flags_t     kt_flags;
325 	uint32_t                kt_size;
326 	zone_t                  kt_zearly;
327 	zone_t                  kt_zsig;
328 };
329 #else /* XNU_KERNEL_PRIVATE */
330 struct kalloc_type_view {
331 	struct zone_view        kt_zv;
332 	const char             *kt_signature __unsafe_indexable;
333 	kalloc_type_flags_t     kt_flags;
334 	uint32_t                kt_size;
335 	void                   *unused1;
336 	void                   *unused2;
337 };
338 #endif /* XNU_KERNEL_PRIVATE */
339 
340 /*
341  * The set of zones used by all kalloc heaps are defined by the constants
342  * below.
343  *
344  * KHEAP_START_SIZE: Size of the first sequential zone.
345  * KHEAP_MAX_SIZE  : Size of the last sequential zone.
346  * KHEAP_STEP_WIDTH: Number of zones created at every step (power of 2).
347  * KHEAP_STEP_START: Size of the first step.
348  * We also create some extra initial zones that don't follow the sequence
349  * for sizes 8 (on armv7 only), 16 and 32.
350  *
351  * idx step_increment   zone_elem_size
352  * 0       -                  16
353  * 1       -                  32
354  * 2       16                 48
355  * 3       16                 64
356  * 4       32                 96
357  * 5       32                 128
358  * 6       64                 192
359  * 7       64                 256
360  * 8       128                384
361  * 9       128                512
362  * 10      256                768
363  * 11      256                1024
364  * 12      512                1536
365  * 13      512                2048
366  * 14      1024               3072
367  * 15      1024               4096
368  * 16      2048               6144
369  * 17      2048               8192
370  * 18      4096               12288
371  * 19      4096               16384
372  * 20      8192               24576
373  * 21      8192               32768
374  */
375 #define kalloc_log2down(mask)   (31 - __builtin_clz(mask))
376 #define KHEAP_START_SIZE        32
377 #if  __x86_64__
378 #define KHEAP_MAX_SIZE          (16 * 1024)
379 #define KHEAP_EXTRA_ZONES       2
380 #else
381 #define KHEAP_MAX_SIZE          (32 * 1024)
382 #define KHEAP_EXTRA_ZONES       2
383 #endif
384 #define KHEAP_STEP_WIDTH        2
385 #define KHEAP_STEP_START        16
386 #define KHEAP_START_IDX         kalloc_log2down(KHEAP_START_SIZE)
387 #define KHEAP_NUM_STEPS         (kalloc_log2down(KHEAP_MAX_SIZE) - \
388 	                                kalloc_log2down(KHEAP_START_SIZE))
389 #define KHEAP_NUM_ZONES         (KHEAP_NUM_STEPS * KHEAP_STEP_WIDTH + \
390 	                                KHEAP_EXTRA_ZONES)
391 
392 /*!
393  * @enum kalloc_type_version_t
394  *
395  * @brief
396  * Enum that holds versioning information for @c kalloc_type_var_view
397  *
398  * @const KT_V1
399  * Version 1
400  *
401  */
402 __options_decl(kalloc_type_version_t, uint16_t, {
403 	KT_V1             = 0x0001,
404 });
405 
406 /*!
407  * @typedef kalloc_type_var_view_t
408  *
409  * @abstract
410  * This structure is analoguous to @c kalloc_type_view but handles
411  * @c kalloc_type callsites that are variable in size.
412  *
413  * @discussion
414  * These structures are automatically created under the hood for every
415  * variable sized @c kalloc_type and @c kfree_type callsite. They are ingested
416  * during startup and are assigned zones based on the security policy for
417  * their signature.
418  *
419  * These structs are protected by the kernel lockdown and can't be initialized
420  * dynamically. They must be created using @c KALLOC_TYPE_VAR_DEFINE() or
421  * @c kalloc_type or @c kfree_type.
422  *
423  */
424 struct kalloc_type_var_view {
425 	kalloc_type_version_t   kt_version;
426 	uint16_t                kt_size_hdr;
427 	/*
428 	 * Temporary: Needs to be 32bits cause we have many structs that use
429 	 * IONew/Delete that are larger than 32K.
430 	 */
431 	uint32_t                kt_size_type;
432 	zone_stats_t            kt_stats;
433 	const char             *__unsafe_indexable kt_name;
434 	zone_view_t             kt_next;
435 	zone_id_t               kt_heap_start;
436 	uint8_t                 kt_zones[KHEAP_NUM_ZONES];
437 	const char             * __unsafe_indexable kt_sig_hdr;
438 	const char             * __unsafe_indexable kt_sig_type;
439 	kalloc_type_flags_t     kt_flags;
440 };
441 
442 typedef struct kalloc_type_var_view *kalloc_type_var_view_t;
443 
444 /*!
445  * @macro KALLOC_TYPE_DECLARE
446  *
447  * @abstract
448  * (optionally) declares a kalloc type view (in a header).
449  *
450  * @param var           the name for the kalloc type view.
451  */
452 #define KALLOC_TYPE_DECLARE(var) \
453 	extern struct kalloc_type_view var[1]
454 
455 /*!
456  * @macro KALLOC_TYPE_DEFINE
457  *
458  * @abstract
459  * Defines a given kalloc type view with prefered accounting
460  *
461  * @discussion
462  * This macro allows you to define a kalloc type with private
463  * accounting. The defined kalloc_type_view can be used with
464  * kalloc_type_impl/kfree_type_impl to allocate/free memory.
465  * zalloc/zfree can also be used from inside xnu. However doing
466  * so doesn't handle freeing a NULL pointer or the use of tags.
467  *
468  * @param var           the name for the kalloc type view.
469  * @param type          the type of your allocation.
470  * @param flags         a @c KT_* flag.
471  */
472 #define KALLOC_TYPE_DEFINE(var, type, flags) \
473 	_KALLOC_TYPE_DEFINE(var, type, flags); \
474 	__ZONE_DECLARE_TYPE(var, type)
475 
476 /*!
477  * @macro KALLOC_TYPE_VAR_DECLARE
478  *
479  * @abstract
480  * (optionally) declares a kalloc type var view (in a header).
481  *
482  * @param var           the name for the kalloc type var view.
483  */
484 #define KALLOC_TYPE_VAR_DECLARE(var) \
485 	extern struct kalloc_type_var_view var[1]
486 
487 /*!
488  * @macro KALLOC_TYPE_VAR_DEFINE
489  *
490  * @abstract
491  * Defines a given kalloc type view with prefered accounting for
492  * variable sized typed allocations.
493  *
494  * @discussion
495  * As the views aren't yet being ingested, individual stats aren't
496  * available. The defined kalloc_type_var_view should be used with
497  * kalloc_type_var_impl/kfree_type_var_impl to allocate/free memory.
498  *
499  * This macro comes in 2 variants:
500  *
501  * 1. @c KALLOC_TYPE_VAR_DEFINE(var, e_ty, flags)
502  * 2. @c KALLOC_TYPE_VAR_DEFINE(var, h_ty, e_ty, flags)
503  *
504  * @param var           the name for the kalloc type var view.
505  * @param h_ty          the type of header in the allocation.
506  * @param e_ty          the type of repeating part in the allocation.
507  * @param flags         a @c KT_* flag.
508  */
509 #define KALLOC_TYPE_VAR_DEFINE(...) KALLOC_DISPATCH(KALLOC_TYPE_VAR_DEFINE, ##__VA_ARGS__)
510 
511 #ifdef XNU_KERNEL_PRIVATE
512 
513 /*
514  * These versions allow specifying the kalloc heap to allocate memory
515  * from
516  */
517 #define kheap_alloc_tag(kalloc_heap, size, flags, itag) \
518 	__kheap_alloc(kalloc_heap, size, __zone_flags_mix_tag(flags, itag), NULL)
519 #define kheap_alloc(kalloc_heap, size, flags) \
520 	kheap_alloc_tag(kalloc_heap, size, flags, VM_ALLOC_SITE_TAG())
521 
522 /*
523  * These versions should be used for allocating pure data bytes that
524  * do not contain any pointers
525  */
526 #define kalloc_data_tag(size, flags, itag) \
527 	kheap_alloc_tag(KHEAP_DATA_BUFFERS, size, flags, itag)
528 #define kalloc_data(size, flags) \
529 	kheap_alloc(KHEAP_DATA_BUFFERS, size, flags)
530 
531 #define krealloc_data_tag(elem, old_size, new_size, flags, itag) \
532 	__kheap_realloc(KHEAP_DATA_BUFFERS, elem, old_size, new_size, \
533 	    __zone_flags_mix_tag(flags, itag), NULL)
534 #define krealloc_data(elem, old_size, new_size, flags) \
535 	krealloc_data_tag(elem, old_size, new_size, flags, \
536 	    VM_ALLOC_SITE_TAG())
537 
538 #define kfree_data(elem, size) \
539 	kheap_free(KHEAP_DATA_BUFFERS, elem, size);
540 
541 #define kfree_data_addr(elem) \
542 	kheap_free_addr(KHEAP_DATA_BUFFERS, elem);
543 
544 extern void kheap_free_bounded(
545 	kalloc_heap_t heap,
546 	void         *addr __unsafe_indexable,
547 	vm_size_t     min_sz,
548 	vm_size_t     max_sz);
549 
550 extern void kalloc_data_require(
551 	void         *data __unsafe_indexable,
552 	vm_size_t     size);
553 
554 extern void kalloc_non_data_require(
555 	void         *data __unsafe_indexable,
556 	vm_size_t     size);
557 
558 #else /* XNU_KERNEL_PRIVATE */
559 
560 extern void *__sized_by(size) kalloc(
561 	vm_size_t           size) __attribute__((malloc, alloc_size(1)));
562 
563 extern void *__unsafe_indexable kalloc_data(
564 	vm_size_t           size,
565 	zalloc_flags_t      flags);
566 
567 __attribute__((malloc, alloc_size(1)))
568 static inline void *
__sized_by(size)569 __sized_by(size)
570 __kalloc_data(vm_size_t size, zalloc_flags_t flags)
571 {
572 	void *__unsafe_indexable addr = (kalloc_data)(size, flags);
573 	if (flags & Z_NOFAIL) {
574 		__builtin_assume(addr != NULL);
575 	}
576 	return addr ? __unsafe_forge_bidi_indexable(uint8_t *, addr, size) : NULL;
577 }
578 
579 #define kalloc_data(size, fl) __kalloc_data(size, fl)
580 
581 extern void *__unsafe_indexable krealloc_data(
582 	void               *ptr __unsafe_indexable,
583 	vm_size_t           old_size,
584 	vm_size_t           new_size,
585 	zalloc_flags_t      flags);
586 
587 __attribute__((malloc, alloc_size(3)))
588 static inline void *
__sized_by(new_size)589 __sized_by(new_size)
590 __krealloc_data(
591 	void               *ptr __sized_by(old_size),
592 	vm_size_t           old_size,
593 	vm_size_t           new_size,
594 	zalloc_flags_t      flags)
595 {
596 	void *__unsafe_indexable addr = (krealloc_data)(ptr, old_size, new_size, flags);
597 	if (flags & Z_NOFAIL) {
598 		__builtin_assume(addr != NULL);
599 	}
600 	return addr ? __unsafe_forge_bidi_indexable(uint8_t *, addr, new_size) : NULL;
601 }
602 
603 #define krealloc_data(ptr, old_size, new_size, fl) \
604 	__krealloc_data(ptr, old_size, new_size, fl)
605 
606 extern void kfree(
607 	void               *data __unsafe_indexable,
608 	vm_size_t           size);
609 
610 extern void kfree_data(
611 	void               *ptr __unsafe_indexable,
612 	vm_size_t           size);
613 
614 extern void kfree_data_addr(
615 	void               *ptr __unsafe_indexable);
616 
617 #endif /* !XNU_KERNEL_PRIVATE */
618 
619 /*!
620  * @macro kalloc_type
621  *
622  * @abstract
623  * Allocates element of a particular type
624  *
625  * @discussion
626  * This family of allocators segregate kalloc allocations based on their type.
627  *
628  * This macro comes in 3 variants:
629  *
630  * 1. @c kalloc_type(type, flags)
631  *    Use this macro for fixed sized allocation of a particular type.
632  *
633  * 2. @c kalloc_type(e_type, count, flags)
634  *    Use this macro for variable sized allocations that form an array,
635  *    do note that @c kalloc_type(e_type, 1, flags) is not equivalent to
636  *    @c kalloc_type(e_type, flags).
637  *
638  * 3. @c kalloc_type(hdr_type, e_type, count, flags)
639  *    Use this macro for variable sized allocations formed with
640  *    a header of type @c hdr_type followed by a variable sized array
641  *    with elements of type @c e_type, equivalent to this:
642  *
643  *    <code>
644  *    struct {
645  *        hdr_type hdr;
646  *        e_type   arr[];
647  *    }
648  *    </code>
649  *
650  * @param flags         @c zalloc_flags_t that get passed to zalloc_internal
651  */
652 #define kalloc_type(...)  KALLOC_DISPATCH(kalloc_type, ##__VA_ARGS__)
653 
654 /*!
655  * @macro kfree_type
656  *
657  * @abstract
658  * Frees element of a particular type
659  *
660  * @discussion
661  * This pairs with the @c kalloc_type() that was made to allocate this element.
662  * Arguments passed to @c kfree_type() must match the one passed at allocation
663  * time precisely.
664  *
665  * This macro comes in the same 3 variants kalloc_type() does:
666  *
667  * 1. @c kfree_type(type, elem)
668  * 2. @c kfree_type(e_type, count, elem)
669  * 3. @c kfree_type(hdr_type, e_type, count, elem)
670  *
671  * @param elem          The address of the element to free
672  */
673 #define kfree_type(...)  KALLOC_DISPATCH(kfree_type, ##__VA_ARGS__)
674 #define kfree_type_counted_by(type, count, elem) \
675 	kfree_type_counted_by_3(type, count, elem)
676 
677 #ifdef XNU_KERNEL_PRIVATE
678 #define kalloc_type_tag(...)     KALLOC_DISPATCH(kalloc_type_tag, ##__VA_ARGS__)
679 #define krealloc_type_tag(...)   KALLOC_DISPATCH(krealloc_type_tag, ##__VA_ARGS__)
680 #define krealloc_type(...)       KALLOC_DISPATCH(krealloc_type, ##__VA_ARGS__)
681 
682 /*
683  * kalloc_type_require can't be made available to kexts as the
684  * kalloc_type_view's zone could be NULL in the following cases:
685  * - Size greater than KALLOC_SAFE_ALLOC_SIZE
686  * - On macOS, if call is not in BootKC
687  * - All allocations in kext for armv7
688  */
689 #define kalloc_type_require(type, value) ({                                    \
690 	static _KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);         \
691 	zone_require(kt_view_var->kt_zv.zv_zone, value);                       \
692 })
693 
694 #endif
695 
696 /*!
697  * @enum kt_granule_t
698  *
699  * @brief
700  * Granule encodings used by the compiler for the type signature.
701  *
702  * @discussion
703  * Given a type, the XNU signature type system (__builtin_xnu_type_signature)
704  * produces a signature by analyzing its memory layout, in chunks of 8 bytes,
705  * which we call granules. The encoding produced for each granule is the
706  * bitwise or of the encodings of all the types of the members included
707  * in that granule.
708  *
709  * @const KT_GRANULE_PADDING
710  * Represents padding inside a record type.
711  *
712  * @const KT_GRANULE_POINTER
713  * Represents a pointer type.
714  *
715  * @const KT_GRANULE_DATA
716  * Represents a scalar type that is not a pointer.
717  *
718  * @const KT_GRANULE_DUAL
719  * Currently unused.
720  *
721  * @const KT_GRANULE_PAC
722  * Represents a pointer which is subject to PAC.
723  */
724 __options_decl(kt_granule_t, uint32_t, {
725 	KT_GRANULE_PADDING = 0,
726 	KT_GRANULE_POINTER = 1,
727 	KT_GRANULE_DATA    = 2,
728 	KT_GRANULE_DUAL    = 4,
729 	KT_GRANULE_PAC     = 8
730 });
731 
732 #define KT_GRANULE_MAX                                                \
733 	(KT_GRANULE_PADDING | KT_GRANULE_POINTER | KT_GRANULE_DATA |  \
734 	    KT_GRANULE_DUAL | KT_GRANULE_PAC)
735 
736 /*
737  * Convert a granule encoding to the index of the bit that
738  * represents such granule in the type summary.
739  *
740  * The XNU type summary (__builtin_xnu_type_summary) produces a 32-bit
741  * summary of the type signature of a given type. If the bit at index
742  * (1 << G) is set in the summary, that means that the type contains
743  * one or more granules with encoding G.
744  */
745 #define KT_SUMMARY_GRANULE_TO_IDX(g)  (1UL << (g))
746 
747 #define KT_SUMMARY_MASK_TYPE_BITS  (0xffff)
748 
749 #define KT_SUMMARY_MASK_DATA                             \
750 	(KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PADDING) |  \
751 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_DATA))
752 
753 #define KT_SUMMARY_MASK_PTR                              \
754 	(KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PADDING) |     \
755 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_POINTER) |  \
756 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PAC))
757 
758 #define KT_SUMMARY_MASK_ALL_GRANULES                        \
759 	(KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PADDING) |     \
760 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_POINTER) |  \
761 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_DATA) |     \
762 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_DUAL) |     \
763 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PAC))
764 
765 /*!
766  * @macro KT_SUMMARY_GRANULES
767  *
768  * @abstract
769  * Return the granule type summary for a given type
770  *
771  * @discussion
772  * This macro computes the type summary of a type, and it then extracts the
773  * bits which carry information about the granules in the memory layout.
774  *
775  * Note: you should never have to use __builtin_xnu_type_summary
776  * directly, as we reserve the right to use the remaining bits with
777  * different semantics.
778  *
779  * @param type          The type to analyze
780  */
781 #define KT_SUMMARY_GRANULES(type) \
782 	(__builtin_xnu_type_summary(type) & KT_SUMMARY_MASK_TYPE_BITS)
783 
784 /*!
785  * @macro KALLOC_TYPE_SIG_CHECK
786  *
787  * @abstract
788  * Return whether a given type is only made up of granules specified in mask
789  *
790  * @param mask          Granules to check for
791  * @param type          The type to analyze
792  */
793 #define KALLOC_TYPE_SIG_CHECK(mask, type) \
794 	((KT_SUMMARY_GRANULES(type) & ~(mask)) == 0)
795 
796 /*!
797  * @macro KALLOC_TYPE_IS_DATA_ONLY
798  *
799  * @abstract
800  * Return whether a given type is considered a data-only type.
801  *
802  * @param type          The type to analyze
803  */
804 #define KALLOC_TYPE_IS_DATA_ONLY(type) \
805 	KALLOC_TYPE_SIG_CHECK(KT_SUMMARY_MASK_DATA, type)
806 
807 /*!
808  * @macro KALLOC_TYPE_HAS_OVERLAPS
809  *
810  * @abstract
811  * Return whether a given type has overlapping granules.
812  *
813  * @discussion
814  * This macro returns whether the memory layout for a given type contains
815  * overlapping granules. An overlapping granule is a granule which includes
816  * members with types that have different encodings under the XNU signature
817  * type system.
818  *
819  * @param type          The type to analyze
820  */
821 #define KALLOC_TYPE_HAS_OVERLAPS(type) \
822 	((KT_SUMMARY_GRANULES(type) & ~KT_SUMMARY_MASK_ALL_GRANULES) != 0)
823 
824 /*!
825  * @macro KALLOC_TYPE_IS_COMPATIBLE_PTR
826  *
827  * @abstract
828  * Return whether pointer is compatible with a given type, in the XNU
829  * signature type system.
830  *
831  * @discussion
832  * This macro returns whether type pointed to by @c ptr is either the same
833  * type as @c type, or it has the same signature. The implementation relies
834  * on the @c __builtin_xnu_types_compatible builtin, and the value returned
835  * can be evaluated at compile time in both C and C++.
836  *
837  * Note: void pointers are treated as wildcards, and are thus compatible
838  * with any given type.
839  *
840  * @param ptr           the pointer whose type needs to be checked.
841  * @param type          the type which the pointer will be checked against.
842  */
843 #define KALLOC_TYPE_IS_COMPATIBLE_PTR(ptr, type)                         \
844 	(__builtin_xnu_types_compatible(os_get_pointee_type(ptr), type) ||   \
845 	    __builtin_xnu_types_compatible(os_get_pointee_type(ptr), void))  \
846 
847 #define KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, type) \
848 	_Static_assert(KALLOC_TYPE_IS_COMPATIBLE_PTR(ptr, type), \
849 	    "Pointer type is not compatible with specified type")
850 
851 
852 /*!
853  * @const KALLOC_ARRAY_SIZE_MAX
854  *
855  * @brief
856  * The maximum size that can be allocated with the @c KALLOC_ARRAY interface.
857  *
858  * @discussion
859  * This size is:
860  * - ~256M on 4k or PAC systems with 16k pages
861  * - ~1G on other 16k systems.
862  */
863 #if __arm64e__ || KASAN_TBI
864 #define KALLOC_ARRAY_SIZE_MAX   ((uint32_t)PAGE_MASK << PAGE_SHIFT)
865 #define KALLOC_ARRAY_GRANULE    32ul
866 #else
867 #define KALLOC_ARRAY_SIZE_MAX   ((uint32_t)UINT16_MAX << PAGE_SHIFT)
868 #define KALLOC_ARRAY_GRANULE    16ul
869 #endif
870 
871 /*!
872  * @macro KALLOC_ARRAY_TYPE_DECL
873  *
874  * @brief
875  * Declares a type used as a packed kalloc array type.
876  *
877  * @discussion
878  * This macro comes in two variants
879  *
880  * - KALLOC_ARRAY_TYPE_DECL(name, e_ty)
881  * - KALLOC_ARRAY_TYPE_DECL(name, h_ty, e_ty)
882  *
883  * The first one defines an array of elements of type @c e_ty,
884  * and the second a header of type @c h_ty followed by
885  * an array of elements of type @c e_ty.
886  *
887  * Those macros will then define the type @c ${name}_t as a typedef
888  * to a non existent structure type, in order to avoid accidental
889  * dereference of those pointers.
890  *
891  * kalloc array pointers are actually pointers that in addition to encoding
892  * the array base pointer, also encode the allocation size (only sizes
893  * up to @c KALLOC_ARRAY_SIZE_MAX bytes).
894  *
895  * Such pointers can be signed with data PAC properly, which will provide
896  * integrity of both the base pointer, and its size.
897  *
898  * kalloc arrays are useful to use instead of embedding the length
899  * of the allocation inside of itself, which tends to be driven by:
900  *
901  * - a desire to not grow the outer structure holding the pointer
902  *   to this array with an extra "length" field for optional arrays,
903  *   in order to save memory (see the @c ip_requests field in ports),
904  *
905  * - a need to be able to atomically consult the size of an allocation
906  *   with respect to loading its pointer (where address dependencies
907  *   traditionally gives this property) for lockless algorithms
908  *   (see the IPC space table).
909  *
910  * Using a kalloc array is preferable for two reasons:
911  *
912  * - embedding lengths inside the allocation is self-referential
913  *   and an appetizing target for post-exploitation strategies,
914  *
915  * - having a dependent load to get to the length loses out-of-order
916  *   opportunities for the CPU and prone to back-to-back cache misses.
917  *
918  * Holding information such as a level of usage of this array
919  * within itself is fine provided those quantities are validated
920  * against the "count" (number of elements) or "size" (allocation
921  * size in bytes) of the array before use.
922  *
923  *
924  * This macro will define a series of functions:
925  *
926  * - ${name}_count_to_size() and ${name}_size_to_count()
927  *   to convert between memory sizes and array element counts
928  *   (taking the header size into account when it exists);
929  *
930  *   Note that those functions assume the count/size are corresponding
931  *   to a valid allocation size within [0, KALLOC_ARRAY_SIZE_MAX].
932  *
933  * - ${name}_next_size() to build good allocation growth policies;
934  *
935  * - ${name}_base() returning a (bound-checked indexable) pointer
936  *   to the header of the array (or its first element when there is
937  *   no header);
938  *
939  * - ${name}_begin() returning a (bound-checked indexable)
940  *   pointer to the first element of the the array;
941  *
942  * - ${name}_contains() to check if an element index is within
943  *   the valid range of this allocation;
944  *
945  * - ${name}_next_elem() to get the next element of an array.
946  *
947  * - ${name}_get() and ${name}_get_nocheck() to return a pointer
948  *   to a given cell of the array with (resp. without) a bound
949  *   check against the array size. The bound-checked variant
950  *   returns NULL for invalid indexes.
951  *
952  * - ${name}_alloc_by_count() and ${name}_alloc_by_size()
953  *   to allocate a new array able to hold at least that many elements
954  *   (resp. bytes).
955  *
956  * - ${name}_realloc_by_count() and ${name}_realloc_by_size()
957  *   to re-allocate a new array able to hold at least that many elements
958  *   (resp. bytes).
959  *
960  * - ${name}_free() and ${name}_free_noclear() to free such an array
961  *   (resp. without nil-ing the pointer). The non-clearing variant
962  *   is to be used only when nil-ing out the pointer is otherwise
963  *   not allowed by C (const value, unable to take address of, ...),
964  *   otherwise the normal ${name}_free() must be used.
965  */
966 #define KALLOC_ARRAY_TYPE_DECL(...) \
967 	KALLOC_DISPATCH(KALLOC_ARRAY_TYPE_DECL, ##__VA_ARGS__)
968 
969 #if XNU_KERNEL_PRIVATE
970 
971 #define KALLOC_ARRAY_TYPE_DECL_(name, h_type_t, h_sz, e_type_t, e_sz) \
972 	KALLOC_TYPE_VAR_DECLARE(name ## _kt_view);                              \
973 	typedef struct name * __unsafe_indexable name ## _t;                    \
974                                                                                 \
975 	__pure2                                                                 \
976 	static inline uint32_t                                                  \
977 	name ## _count_to_size(uint32_t count)                                  \
978 	{                                                                       \
979 	        return (uint32_t)((h_sz) + (e_sz) * count);                     \
980 	}                                                                       \
981                                                                                 \
982 	__pure2                                                                 \
983 	static inline uint32_t                                                  \
984 	name ## _size_to_count(vm_size_t size)                                  \
985 	{                                                                       \
986 	        return (uint32_t)((size - (h_sz)) / (e_sz));                    \
987 	}                                                                       \
988                                                                                 \
989 	__pure2                                                                 \
990 	static inline uint32_t                                                  \
991 	name ## _size(name ## _t array)                                         \
992 	{                                                                       \
993 	        return __kalloc_array_size((vm_address_t)array);                \
994 	}                                                                       \
995                                                                                 \
996 	__pure2                                                                 \
997 	static inline uint32_t                                                  \
998 	name ## _next_size(                                                     \
999 	        uint32_t                min_count,                              \
1000 	        vm_size_t               cur_size,                               \
1001 	        uint32_t                vm_period)                              \
1002 	{                                                                       \
1003 	        vm_size_t size;                                                 \
1004                                                                                 \
1005 	        if (cur_size) {                                                 \
1006 	                size = cur_size + (e_sz) - 1;                           \
1007 	        } else {                                                        \
1008 	                size = kt_size(h_sz, e_sz, min_count) - 1;              \
1009 	        }                                                               \
1010 	        size  = kalloc_next_good_size(size, vm_period);                 \
1011 	        if (size <= KALLOC_ARRAY_SIZE_MAX) {                            \
1012 	               return (uint32_t)size;                                   \
1013 	        }                                                               \
1014 	        return 2 * KALLOC_ARRAY_SIZE_MAX; /* will fail */               \
1015 	}                                                                       \
1016                                                                                 \
1017 	__pure2                                                                 \
1018 	static inline uint32_t                                                  \
1019 	name ## _count(name ## _t array)                                        \
1020 	{                                                                       \
1021 	        return name ## _size_to_count(name ## _size(array));            \
1022 	}                                                                       \
1023                                                                                 \
1024 	__pure2                                                                 \
1025 	static inline h_type_t *__header_bidi_indexable                         \
1026 	name ## _base(name ## _t array)                                         \
1027 	{                                                                       \
1028 	        vm_address_t base = __kalloc_array_base((vm_address_t)array);   \
1029 	        uint32_t     size = __kalloc_array_size((vm_address_t)array);   \
1030                                                                                 \
1031 	        (void)size;                                                     \
1032 	        return __unsafe_forge_bidi_indexable(h_type_t *, base, size);   \
1033 	}                                                                       \
1034                                                                                 \
1035 	__pure2                                                                 \
1036 	static inline e_type_t *__header_bidi_indexable                         \
1037 	name ## _begin(name ## _t array)                                        \
1038 	{                                                                       \
1039 	        vm_address_t base = __kalloc_array_base((vm_address_t)array);   \
1040 	        uint32_t     size = __kalloc_array_size((vm_address_t)array);   \
1041                                                                                 \
1042 	        (void)size;                                                     \
1043 	        return __unsafe_forge_bidi_indexable(e_type_t *, base, size);   \
1044 	}                                                                       \
1045                                                                                 \
1046 	__pure2                                                                 \
1047 	static inline e_type_t *                                                \
1048 	name ## _next_elem(name ## _t array, e_type_t *e)                       \
1049 	{                                                                       \
1050 	        vm_address_t end = __kalloc_array_end((vm_address_t)array);     \
1051 	        vm_address_t ptr = (vm_address_t)e + sizeof(e_type_t);          \
1052                                                                                 \
1053 	        if (ptr + sizeof(e_type_t) <= end) {                            \
1054 	                return __unsafe_forge_single(e_type_t *, ptr);          \
1055 	        }                                                               \
1056 	        return NULL;                                                    \
1057 	}                                                                       \
1058                                                                                 \
1059 	__pure2                                                                 \
1060 	static inline bool                                                      \
1061 	name ## _contains(name ## _t array, vm_size_t i)                        \
1062 	{                                                                       \
1063 	        vm_size_t offs = (e_sz) + (h_sz);                               \
1064 	        vm_size_t s;                                                    \
1065                                                                                 \
1066 	        if (__improbable(os_mul_and_add_overflow(i, e_sz, offs, &s))) { \
1067 	                return false;                                           \
1068 	        }                                                               \
1069 	        if (__improbable(s > name ## _size(array))) {                   \
1070 	                return false;                                           \
1071 	        }                                                               \
1072 	        return true;                                                    \
1073 	}                                                                       \
1074                                                                                 \
1075 	__pure2                                                                 \
1076 	static inline e_type_t * __single                                       \
1077 	name ## _get_nocheck(name ## _t array, vm_size_t i)                     \
1078 	{                                                                       \
1079 	        return name ## _begin(array) + i;                               \
1080 	}                                                                       \
1081                                                                                 \
1082 	__pure2                                                                 \
1083 	static inline e_type_t * __single                                       \
1084 	name ## _get(name ## _t array, vm_size_t i)                             \
1085 	{                                                                       \
1086 	        if (__probable(name ## _contains(array, i))) {                  \
1087 	            return name ## _get_nocheck(array, i);                      \
1088 	        }                                                               \
1089 	        return NULL;                                                    \
1090 	}                                                                       \
1091                                                                                 \
1092 	static inline name ## _t                                                \
1093 	name ## _alloc_by_size(vm_size_t size, zalloc_flags_t fl)               \
1094 	{                                                                       \
1095 	        fl |= Z_KALLOC_ARRAY;                                           \
1096 	        fl = __zone_flags_mix_tag(fl, VM_ALLOC_SITE_TAG());             \
1097 	        return (name ## _t)kalloc_type_var_impl(name ## _kt_view,       \
1098 	                        size, fl, NULL);                                \
1099 	}                                                                       \
1100                                                                                 \
1101 	static inline name ## _t                                                \
1102 	name ## _alloc_by_count(uint32_t count, zalloc_flags_t fl)              \
1103 	{                                                                       \
1104 	        return name ## _alloc_by_size(kt_size(h_sz, e_sz, count), fl);  \
1105 	}                                                                       \
1106                                                                                 \
1107 	static inline name ## _t                                                \
1108 	name ## _realloc_by_size(                                               \
1109 	        name ## _t              array,                                  \
1110 	        vm_size_t               new_size,                               \
1111 	        zalloc_flags_t          fl)                                     \
1112 	{                                                                       \
1113 	        vm_address_t base = __kalloc_array_base((vm_address_t)array);   \
1114 	        vm_size_t    size = __kalloc_array_size((vm_address_t)array);   \
1115                                                                                 \
1116 	        fl |= Z_KALLOC_ARRAY;                                           \
1117 	        fl = __zone_flags_mix_tag(fl, VM_ALLOC_SITE_TAG());             \
1118 	        return (name ## _t)(krealloc_ext)(                              \
1119 	                        kt_mangle_var_view(name ## _kt_view),           \
1120 	                        (void *)base, size, new_size, fl, NULL).addr;   \
1121 	}                                                                       \
1122                                                                                 \
1123 	static inline name ## _t                                                \
1124 	name ## _realloc_by_count(                                              \
1125 	        name ## _t              array,                                  \
1126 	        uint32_t                new_count,                              \
1127 	        zalloc_flags_t          fl)                                     \
1128 	{                                                                       \
1129 	        vm_size_t new_size = kt_size(h_sz, e_sz, new_count);            \
1130                                                                                 \
1131 	        return name ## _realloc_by_size(array, new_size, fl);           \
1132 	}                                                                       \
1133                                                                                 \
1134 	static inline void                                                      \
1135 	name ## _free_noclear(name ## _t array)                                 \
1136 	{                                                                       \
1137 	        kfree_type_var_impl(name ## _kt_view,                           \
1138 	            name ## _base(array), name ## _size(array));                \
1139 	}                                                                       \
1140                                                                                 \
1141 	static inline void                                                      \
1142 	name ## _free(name ## _t *arrayp)                                       \
1143 	{                                                                       \
1144 	        name ## _t array = *arrayp;                                     \
1145                                                                                 \
1146 	        *arrayp = NULL;                                                 \
1147 	        kfree_type_var_impl(name ## _kt_view,                           \
1148 	            name ## _base(array), name ## _size(array));                \
1149 	}
1150 
1151 
1152 /*!
1153  * @macro KALLOC_ARRAY_TYPE_DEFINE()
1154  *
1155  * @description
1156  * Defines the data structures required to pair with a KALLOC_ARRAY_TYPE_DECL()
1157  * kalloc array declaration.
1158  *
1159  * @discussion
1160  * This macro comes in two variants
1161  *
1162  * - KALLOC_ARRAY_TYPE_DEFINE(name, e_ty, flags)
1163  * - KALLOC_ARRAY_TYPE_DEFINE(name, h_ty, e_ty, flags)
1164  *
1165  * Those must pair with the KALLOC_ARRAY_TYPE_DECL() form being used.
1166  * The flags must be valid @c kalloc_type_flags_t flags.
1167  */
1168 #define KALLOC_ARRAY_TYPE_DEFINE(...) \
1169 	KALLOC_DISPATCH(KALLOC_ARRAY_TYPE_DEFINE, ##__VA_ARGS__)
1170 
1171 /*!
1172  * @function kalloc_next_good_size()
1173  *
1174  * @brief
1175  * Allows to implement "allocation growth policies" that work well
1176  * with the allocator.
1177  *
1178  * @discussion
1179  * Note that if the caller tracks a number of elements for an array,
1180  * where the elements are of size S, and the current count is C,
1181  * then it is possible for kalloc_next_good_size(C * S, ..) to hit
1182  * a fixed point, clients must call with a size at least of ((C + 1) * S).
1183  *
1184  * @param size         the current "size" of the allocation (in bytes).
1185  * @param period       the "period" (power of 2) for the allocation growth
1186  *                     policy once hitting the VM sized allocations.
1187  */
1188 extern vm_size_t kalloc_next_good_size(
1189 	vm_size_t               size,
1190 	uint32_t                period);
1191 
1192 #pragma mark kalloc_array implementation details
1193 
1194 #define KALLOC_ARRAY_TYPE_DECL_2(name, e_type_t) \
1195 	KALLOC_ARRAY_TYPE_DECL_(name, e_type_t, 0, e_type_t, sizeof(e_type_t))
1196 
1197 #define KALLOC_ARRAY_TYPE_DECL_3(name, h_type_t, e_type_t) \
1198 	KALLOC_ARRAY_TYPE_DECL_(name,                                           \
1199 	    h_type_t, kt_realign_sizeof(h_type_t, e_type_t),                    \
1200 	    e_type_t, sizeof(e_type_t))                                         \
1201 
1202 #define KALLOC_ARRAY_TYPE_DEFINE_3(name, e_type_t, flags) \
1203 	KALLOC_TYPE_VAR_DEFINE_3(name ## _kt_view, e_type_t, flags)
1204 
1205 #define KALLOC_ARRAY_TYPE_DEFINE_4(name, h_type_t, e_type_t, flags) \
1206 	KALLOC_TYPE_VAR_DEFINE_4(name ## _kt_view, h_type_t, e_type_t, flags)
1207 
1208 extern struct kalloc_result __kalloc_array_decode(
1209 	vm_address_t            array) __pure2;
1210 
1211 __pure2
1212 static inline uint32_t
__kalloc_array_size(vm_address_t array)1213 __kalloc_array_size(vm_address_t array)
1214 {
1215 	vm_address_t size = __kalloc_array_decode(array).size;
1216 
1217 	__builtin_assume(size <= KALLOC_ARRAY_SIZE_MAX);
1218 	return (uint32_t)size;
1219 }
1220 
1221 __pure2
1222 static inline vm_address_t
__kalloc_array_base(vm_address_t array)1223 __kalloc_array_base(vm_address_t array)
1224 {
1225 	return (vm_address_t)__kalloc_array_decode(array).addr;
1226 }
1227 
1228 __pure2
1229 static inline vm_address_t
__kalloc_array_begin(vm_address_t array,vm_size_t hdr_size)1230 __kalloc_array_begin(vm_address_t array, vm_size_t hdr_size)
1231 {
1232 	return (vm_address_t)__kalloc_array_decode(array).addr + hdr_size;
1233 }
1234 
1235 __pure2
1236 static inline vm_address_t
__kalloc_array_end(vm_address_t array)1237 __kalloc_array_end(vm_address_t array)
1238 {
1239 	struct kalloc_result kr = __kalloc_array_decode(array);
1240 
1241 	return (vm_address_t)kr.addr + kr.size;
1242 }
1243 
1244 #else /* !XNU_KERNEL_PRIVATE */
1245 
1246 #define KALLOC_ARRAY_TYPE_DECL_(name, h_type_t, h_sz, e_type_t, e_sz) \
1247 	typedef struct name * __unsafe_indexable name ## _t
1248 
1249 #endif /* !XNU_KERNEL_PRIVATE */
1250 #pragma mark implementation details
1251 
1252 
1253 static inline void *__unsafe_indexable
kt_mangle_var_view(kalloc_type_var_view_t kt_view)1254 kt_mangle_var_view(kalloc_type_var_view_t kt_view)
1255 {
1256 	return (void *__unsafe_indexable)((uintptr_t)kt_view | 1ul);
1257 }
1258 
1259 static inline kalloc_type_var_view_t __unsafe_indexable
kt_demangle_var_view(void * ptr)1260 kt_demangle_var_view(void *ptr)
1261 {
1262 	return (kalloc_type_var_view_t __unsafe_indexable)((uintptr_t)ptr & ~1ul);
1263 }
1264 
1265 #define kt_is_var_view(ptr)  ((uintptr_t)(ptr) & 1)
1266 
1267 #define kt_realign_sizeof(h_ty, e_ty) \
1268 	((sizeof(h_ty) + _Alignof(e_ty) - 1) & -_Alignof(e_ty))
1269 
1270 static inline vm_size_t
kt_size(vm_size_t s1,vm_size_t s2,vm_size_t c2)1271 kt_size(vm_size_t s1, vm_size_t s2, vm_size_t c2)
1272 {
1273 	/* kalloc_large() will reject this size before even asking the VM  */
1274 	const vm_size_t limit = 1ull << (8 * sizeof(vm_size_t) - 1);
1275 
1276 	if (os_mul_and_add_overflow(s2, c2, s1, &s1) || (s1 & limit)) {
1277 		return limit;
1278 	}
1279 	return s1;
1280 }
1281 
1282 #define kalloc_type_2(type, flags) ({                                          \
1283 	static _KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);         \
1284 	__unsafe_forge_single(type *, kalloc_type_impl(kt_view_var, flags));   \
1285 })
1286 
1287 #define kfree_type_2(type, elem) ({                                            \
1288 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, type);                     \
1289 	static _KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);         \
1290 	kfree_type_impl(kt_view_var, os_ptr_load_and_erase(elem));             \
1291 })
1292 
1293 #define kfree_type_3(type, count, elem) ({                                     \
1294 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, type);                     \
1295 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
1296 	__auto_type __kfree_count = (count);                                   \
1297 	kfree_type_var_impl(kt_view_var, os_ptr_load_and_erase(elem),          \
1298 	    kt_size(0, sizeof(type), __kfree_count));                          \
1299 })
1300 
1301 // rdar://123257599
1302 #define kfree_type_counted_by_3(type, count_var, elem_var) ({                  \
1303 	void *__header_bidi_indexable __elem_copy = (elem_var);                \
1304 	__auto_type __kfree_count = (count_var);                               \
1305 	(elem_var) = 0;                                                        \
1306 	(count_var) = 0;                                                       \
1307 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(                                 \
1308 	    (os_get_pointee_type(elem_var) *)NULL, type);                      \
1309 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
1310 	kfree_type_var_impl(kt_view_var, __elem_copy,                          \
1311 	    kt_size(0, sizeof(type), __kfree_count));                          \
1312 })
1313 
1314 #define kfree_type_4(hdr_ty, e_ty, count, elem) ({                             \
1315 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, hdr_ty);                   \
1316 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
1317 	    KT_SHARED_ACCT);                                                   \
1318 	__auto_type __kfree_count = (count);                                   \
1319 	kfree_type_var_impl(kt_view_var,                                       \
1320 	    os_ptr_load_and_erase(elem),                                       \
1321 	    kt_size(kt_realign_sizeof(hdr_ty, e_ty), sizeof(e_ty),             \
1322 	    __kfree_count));                                                   \
1323 })
1324 
1325 #ifdef XNU_KERNEL_PRIVATE
1326 #define kalloc_type_tag_3(type, flags, tag) ({                                 \
1327 	static _KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);         \
1328 	__unsafe_forge_single(type *, kalloc_type_impl(kt_view_var,            \
1329 	    Z_VM_TAG(flags, tag)));                                            \
1330 })
1331 
1332 #define kalloc_type_tag_4(type, count, flags, tag) ({                          \
1333 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
1334 	(type *)kalloc_type_var_impl(kt_view_var,                              \
1335 	    kt_size(0, sizeof(type), count),                                   \
1336 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
1337 })
1338 #define kalloc_type_3(type, count, flags)  \
1339 	kalloc_type_tag_4(type, count, flags, VM_ALLOC_SITE_TAG())
1340 
1341 #define kalloc_type_tag_5(hdr_ty, e_ty, count, flags, tag) ({                  \
1342 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
1343 	    KT_SHARED_ACCT);                                                   \
1344 	(hdr_ty *)kalloc_type_var_impl(kt_view_var,                            \
1345 	    kt_size(kt_realign_sizeof(hdr_ty, e_ty), sizeof(e_ty), count),     \
1346 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
1347 })
1348 #define kalloc_type_4(hdr_ty, e_ty, count, flags) \
1349 	kalloc_type_tag_5(hdr_ty, e_ty, count, flags, VM_ALLOC_SITE_TAG())
1350 
1351 #define krealloc_type_tag_6(type, old_count, new_count, elem, flags, tag) ({   \
1352 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
1353 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, type);                     \
1354 	(type *)__krealloc_type(kt_view_var, elem,                             \
1355 	    kt_size(0, sizeof(type), old_count),                               \
1356 	    kt_size(0, sizeof(type), new_count),                               \
1357 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
1358 })
1359 #define krealloc_type_5(type, old_count, new_count, elem, flags) \
1360 	krealloc_type_tag_6(type, old_count, new_count, elem, flags, \
1361 	    VM_ALLOC_SITE_TAG())
1362 
1363 #define krealloc_type_tag_7(hdr_ty, e_ty, old_count, new_count, elem,          \
1364 	    flags, tag) ({                                                     \
1365 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
1366 	    KT_SHARED_ACCT);                                                   \
1367 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, hdr_ty);                   \
1368 	(hdr_ty *)__krealloc_type(kt_view_var, elem,                           \
1369 	    kt_size(kt_realign_sizeof(hdr_ty, e_ty), sizeof(e_ty), old_count), \
1370 	    kt_size(kt_realign_sizeof(hdr_ty, e_ty), sizeof(e_ty), new_count), \
1371 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
1372 })
1373 #define krealloc_type_6(hdr_ty, e_ty, old_count, new_count, elem, flags) \
1374 	krealloc_type_tag_7(hdr_ty, e_ty, old_count, new_count, elem, flags,   \
1375 	    VM_ALLOC_SITE_TAG())
1376 
1377 #else /* XNU_KERNEL_PRIVATE */
1378 
1379 #define kalloc_type_3(type, count, flags) ({                                   \
1380 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
1381 	(type *)kalloc_type_var_impl(kt_view_var,                              \
1382 	    kt_size(0, sizeof(type), count), flags, NULL);                     \
1383 })
1384 
1385 #define kalloc_type_4(hdr_ty, e_ty, count, flags) ({                           \
1386 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
1387 	    KT_SHARED_ACCT);                                                   \
1388 	(hdr_ty *)kalloc_type_var_impl(kt_view_var,                            \
1389 	    kt_size(kt_realign_sizeof(hdr_ty, e_ty), sizeof(e_ty), count),     \
1390 	    flags, NULL);                                                      \
1391 })
1392 
1393 #endif /* !XNU_KERNEL_PRIVATE */
1394 
1395 /*
1396  * All k*free macros set "elem" to NULL on free.
1397  *
1398  * Note: all values passed to k*free() might be in the element to be freed,
1399  *       temporaries must be taken, and the resetting to be done prior to free.
1400  */
1401 #ifdef XNU_KERNEL_PRIVATE
1402 
1403 #define kheap_free(heap, elem, size) ({                                        \
1404 	kalloc_heap_t __kfree_heap = (heap);                                   \
1405 	__auto_type __kfree_size = (size);                                     \
1406 	__builtin_assume(!kt_is_var_view(__kfree_heap));                       \
1407 	kfree_ext((void *)__kfree_heap,                                        \
1408 	    (void *)os_ptr_load_and_erase(elem), __kfree_size);                \
1409 })
1410 
1411 #define kheap_free_addr(heap, elem) ({                                         \
1412 	kalloc_heap_t __kfree_heap = (heap);                                   \
1413 	kfree_addr_ext(__kfree_heap, (void *)os_ptr_load_and_erase(elem));     \
1414 })
1415 
1416 #define kheap_free_bounded(heap, elem, min_sz, max_sz) ({                      \
1417 	static_assert(max_sz <= KALLOC_SAFE_ALLOC_SIZE);                       \
1418 	kalloc_heap_t __kfree_heap = (heap);                                   \
1419 	__auto_type __kfree_min_sz = (min_sz);                                 \
1420 	__auto_type __kfree_max_sz = (max_sz);                                 \
1421 	(kheap_free_bounded)(__kfree_heap,                                     \
1422 	    (void *)os_ptr_load_and_erase(elem),                               \
1423 	    __kfree_min_sz, __kfree_max_sz);                                   \
1424 })
1425 
1426 #else /* XNU_KERNEL_PRIVATE */
1427 
1428 #define kfree_data(elem, size) ({                                              \
1429 	__auto_type __kfree_size = (size);                                     \
1430 	(kfree_data)((void *)os_ptr_load_and_erase(elem), __kfree_size);       \
1431 })
1432 
1433 #define kfree_data_addr(elem) \
1434 	(kfree_data_addr)((void *)os_ptr_load_and_erase(elem))
1435 
1436 #endif /* !XNU_KERNEL_PRIVATE */
1437 
1438 #define __kfree_data_elem_count_size(elem_var, count_var, size) ({              \
1439 	void *__header_bidi_indexable __elem_copy = (elem_var);                 \
1440 	(elem_var) = 0;                                                         \
1441 	(count_var) = 0;                                                        \
1442 	kfree_data(__elem_copy, size);                                          \
1443 })
1444 
1445 #define __kfree_data_addr_count_size(addr_var, count_var) ({                    \
1446 	void *__header_bidi_indexable __addr_copy = (addr_var);                 \
1447 	(addr_var) = 0;                                                         \
1448 	(count_var) = 0;                                                        \
1449 	kfree_data_addr(__addr_copy);                                           \
1450 })
1451 
1452 /*
1453  * kfree_data_sized_by is the kfree_data equivalent that is compatible with
1454  * -fbounds-safety's __sized_by pointers. Consistently with the -fbounds-safety
1455  * semantics, `size` must be the byte size of the allocation that is freed (for
1456  * instance, 20 for an array of 5 uint32_t).
1457  */
1458 #define kfree_data_sized_by(elem, size) ({                                      \
1459 	__auto_type __size = (size);                                            \
1460 	__kfree_data_elem_count_size(elem, size, __size);                       \
1461 })
1462 
1463 #define kfree_data_addr_sized_by(addr, size) ({                                 \
1464 	__kfree_data_addr_count_size(addr, size);                               \
1465 })
1466 
1467 /*
1468  * kfree_data_counted_by is the kfree_data equivalent that is compatible with
1469  * -fbounds-safety's __counted_by pointers. Consistently with the
1470  * -fbounds-safety semantics, `count` must be the object count of the allocation
1471  * that is freed (for instance, 5 for an array of 5 uint32_t).
1472  */
1473 #define kfree_data_counted_by(elem, count) ({                                  \
1474 	__auto_type __size = (count) * sizeof(*(elem));                        \
1475 	__kfree_data_elem_count_size(elem, count, __size);                     \
1476 })
1477 
1478 #if __has_feature(address_sanitizer)
1479 # define __kalloc_no_kasan __attribute__((no_sanitize("address")))
1480 #else
1481 # define __kalloc_no_kasan
1482 #endif
1483 
1484 #define KALLOC_CONCAT(x, y) __CONCAT(x,y)
1485 
1486 #define KALLOC_COUNT_ARGS1(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, N, ...) N
1487 #define KALLOC_COUNT_ARGS(...) \
1488 	KALLOC_COUNT_ARGS1(, ##__VA_ARGS__, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
1489 #define KALLOC_DISPATCH1(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
1490 #define KALLOC_DISPATCH(base, ...) \
1491 	KALLOC_DISPATCH1(base, KALLOC_COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
1492 #define KALLOC_DISPATCH1_R(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
1493 #define KALLOC_DISPATCH_R(base, ...) \
1494 	KALLOC_DISPATCH1_R(base, KALLOC_COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
1495 
1496 #define kt_view_var \
1497 	KALLOC_CONCAT(kalloc_type_view_, __LINE__)
1498 
1499 #define KALLOC_TYPE_SEGMENT "__DATA_CONST"
1500 
1501 /*
1502  * When kalloc_type_impl is called from xnu, it calls zalloc_flags
1503  * directly and doesn't redirect zone-less sites to kheap_alloc.
1504  * Passing a size larger than KHEAP_MAX_SIZE for these allocations will
1505  * lead to a panic as the zone is null. Therefore assert that size
1506  * is less than KALLOC_SAFE_ALLOC_SIZE.
1507  */
1508 #if XNU_KERNEL_PRIVATE || defined(KALLOC_TYPE_STRICT_SIZE_CHECK)
1509 #define KALLOC_TYPE_SIZE_CHECK(size)                           \
1510 	_Static_assert(size <= KALLOC_SAFE_ALLOC_SIZE,             \
1511 	"type is too large");
1512 #else
1513 #define KALLOC_TYPE_SIZE_CHECK(size)
1514 #endif
1515 
1516 #define KALLOC_TYPE_CHECK_2(check, type) \
1517 	(KALLOC_TYPE_SIG_CHECK(check, type))
1518 
1519 #define KALLOC_TYPE_CHECK_3(check, type1, type2) \
1520 	(KALLOC_TYPE_SIG_CHECK(check, type1) && \
1521 	    KALLOC_TYPE_SIG_CHECK(check, type2))
1522 
1523 #define KALLOC_TYPE_CHECK(...) \
1524 	KALLOC_DISPATCH_R(KALLOC_TYPE_CHECK, ##__VA_ARGS__)
1525 
1526 #define KALLOC_TYPE_VM_SIZE_CHECK_1(type) \
1527 	(sizeof(type) > KHEAP_MAX_SIZE)
1528 
1529 #define KALLOC_TYPE_VM_SIZE_CHECK_2(type1, type2) \
1530 	(sizeof(type1) + sizeof(type2) > KHEAP_MAX_SIZE)
1531 
1532 #define KALLOC_TYPE_VM_SIZE_CHECK(...) \
1533 	KALLOC_DISPATCH_R(KALLOC_TYPE_VM_SIZE_CHECK, ##__VA_ARGS__)
1534 
1535 #define KALLOC_TYPE_TRAILING_DATA_CHECK(hdr_ty, elem_ty)     \
1536 	_Static_assert((KALLOC_TYPE_IS_DATA_ONLY(hdr_ty) ||  \
1537 	    !KALLOC_TYPE_IS_DATA_ONLY(elem_ty)),             \
1538 	"cannot allocate data-only array of " #elem_ty       \
1539 	" contiguously to " #hdr_ty)
1540 
1541 #ifdef __cplusplus
1542 #define KALLOC_TYPE_CAST_FLAGS(flags) static_cast<kalloc_type_flags_t>(flags)
1543 #else
1544 #define KALLOC_TYPE_CAST_FLAGS(flags) (kalloc_type_flags_t)(flags)
1545 #endif
1546 
1547 /*
1548  * Don't emit signature if type is "data-only" or is large enough that it
1549  * uses the VM.
1550  *
1551  * Note: sig_type is the type you want to emit signature for. The variable
1552  * args can be used to provide other types in the allocation, to make the
1553  * decision of whether to emit the signature.
1554  */
1555 #define KALLOC_TYPE_EMIT_SIG(sig_type, ...)                              \
1556 	(KALLOC_TYPE_CHECK(KT_SUMMARY_MASK_DATA, sig_type, ##__VA_ARGS__) || \
1557 	KALLOC_TYPE_VM_SIZE_CHECK(sig_type, ##__VA_ARGS__))?                 \
1558 	"" : __builtin_xnu_type_signature(sig_type)
1559 
1560 /*
1561  * Kalloc type flags are adjusted to indicate if the type is "data-only" or
1562  * will use the VM or is a pointer array.
1563  */
1564 #define KALLOC_TYPE_ADJUST_FLAGS(flags, ...)                                 \
1565 	KALLOC_TYPE_CAST_FLAGS((flags | KT_CHANGED | KT_CHANGED2 |               \
1566 	(KALLOC_TYPE_CHECK(KT_SUMMARY_MASK_DATA, __VA_ARGS__)? KT_DATA_ONLY: 0) |\
1567 	(KALLOC_TYPE_CHECK(KT_SUMMARY_MASK_PTR, __VA_ARGS__)? KT_PTR_ARRAY: 0) | \
1568 	(KALLOC_TYPE_VM_SIZE_CHECK(__VA_ARGS__)? KT_VM : 0)))
1569 
1570 #define _KALLOC_TYPE_DEFINE(var, type, flags)                       \
1571 	__kalloc_no_kasan                                               \
1572 	__PLACE_IN_SECTION(KALLOC_TYPE_SEGMENT ", __kalloc_type, "      \
1573 	    "regular, live_support")                                    \
1574 	struct kalloc_type_view var[1] = { {                            \
1575 	    .kt_zv.zv_name = "site." #type,                             \
1576 	    .kt_flags = KALLOC_TYPE_ADJUST_FLAGS(flags, type),          \
1577 	    .kt_size = sizeof(type),                                    \
1578 	    .kt_signature = KALLOC_TYPE_EMIT_SIG(type),                 \
1579 	} };                                                            \
1580 	KALLOC_TYPE_SIZE_CHECK(sizeof(type));
1581 
1582 #define KALLOC_TYPE_VAR_DEFINE_3(var, type, flags)                  \
1583 	__kalloc_no_kasan                                               \
1584 	__PLACE_IN_SECTION(KALLOC_TYPE_SEGMENT ", __kalloc_var, "       \
1585 	    "regular, live_support")                                    \
1586 	struct kalloc_type_var_view var[1] = { {                        \
1587 	    .kt_version = KT_V1,                                        \
1588 	    .kt_name = "site." #type,                                   \
1589 	    .kt_flags = KALLOC_TYPE_ADJUST_FLAGS(flags, type),          \
1590 	    .kt_size_type = sizeof(type),                               \
1591 	    .kt_sig_type = KALLOC_TYPE_EMIT_SIG(type),                  \
1592 	} };                                                            \
1593 	KALLOC_TYPE_SIZE_CHECK(sizeof(type));
1594 
1595 #define KALLOC_TYPE_VAR_DEFINE_4(var, hdr, type, flags)             \
1596 	__kalloc_no_kasan                                               \
1597 	__PLACE_IN_SECTION(KALLOC_TYPE_SEGMENT ", __kalloc_var, "       \
1598 	    "regular, live_support")                                    \
1599 	struct kalloc_type_var_view var[1] = { {                        \
1600 	    .kt_version = KT_V1,                                        \
1601 	    .kt_name = "site." #hdr "." #type,                          \
1602 	    .kt_flags = KALLOC_TYPE_ADJUST_FLAGS(flags, hdr, type),     \
1603 	    .kt_size_hdr = sizeof(hdr),                                 \
1604 	    .kt_size_type = sizeof(type),                               \
1605 	    .kt_sig_hdr = KALLOC_TYPE_EMIT_SIG(hdr, type),              \
1606 	    .kt_sig_type = KALLOC_TYPE_EMIT_SIG(type, hdr),             \
1607 	} };                                                            \
1608 	KALLOC_TYPE_SIZE_CHECK(sizeof(hdr));                            \
1609 	KALLOC_TYPE_SIZE_CHECK(sizeof(type));                           \
1610 	KALLOC_TYPE_TRAILING_DATA_CHECK(hdr, type);
1611 
1612 #ifndef XNU_KERNEL_PRIVATE
1613 /*
1614  * This macro is currently used by AppleImage4
1615  */
1616 #define KALLOC_TYPE_DEFINE_SITE(var, type, flags)       \
1617 	static _KALLOC_TYPE_DEFINE(var, type, flags)
1618 
1619 #endif /* !XNU_KERNEL_PRIVATE */
1620 
1621 #ifdef XNU_KERNEL_PRIVATE
1622 
1623 extern struct kalloc_result kalloc_ext(
1624 	void                   *kheap_or_kt_view __unsafe_indexable,
1625 	vm_size_t               size,
1626 	zalloc_flags_t          flags,
1627 	void                   *site);
1628 
1629 static inline struct kalloc_result
__kalloc_ext(void * kheap_or_kt_view __unsafe_indexable,vm_size_t size,zalloc_flags_t flags,void * site)1630 __kalloc_ext(
1631 	void                   *kheap_or_kt_view __unsafe_indexable,
1632 	vm_size_t               size,
1633 	zalloc_flags_t          flags,
1634 	void                   *site)
1635 {
1636 	struct kalloc_result kr;
1637 
1638 	kr    = (kalloc_ext)(kheap_or_kt_view, size, flags, site);
1639 	if (flags & Z_NOFAIL) {
1640 		__builtin_assume(kr.addr != NULL);
1641 	}
1642 	return kr;
1643 }
1644 
1645 #define kalloc_ext(hov, size, fl, site) __kalloc_ext(hov, size, fl, site)
1646 
1647 extern void kfree_ext(
1648 	void                   *kheap_or_kt_view __unsafe_indexable,
1649 	void                   *addr __unsafe_indexable,
1650 	vm_size_t               size);
1651 
1652 // rdar://87559422
1653 static inline void *__unsafe_indexable
kalloc_type_var_impl(kalloc_type_var_view_t kt_view,vm_size_t size,zalloc_flags_t flags,void * site)1654 kalloc_type_var_impl(
1655 	kalloc_type_var_view_t    kt_view,
1656 	vm_size_t                 size,
1657 	zalloc_flags_t            flags,
1658 	void                      *site)
1659 {
1660 	struct kalloc_result kr;
1661 
1662 	kr = kalloc_ext(kt_mangle_var_view(kt_view), size, flags, site);
1663 	return kr.addr;
1664 }
1665 
1666 static inline void
kfree_type_var_impl(kalloc_type_var_view_t kt_view,void * ptr __unsafe_indexable,vm_size_t size)1667 kfree_type_var_impl(
1668 	kalloc_type_var_view_t      kt_view,
1669 	void                       *ptr __unsafe_indexable,
1670 	vm_size_t                   size)
1671 {
1672 	kfree_ext(kt_mangle_var_view(kt_view), ptr, size);
1673 }
1674 
1675 #else /* XNU_KERNEL_PRIVATE */
1676 
1677 extern void *__unsafe_indexable kalloc_type_var_impl(
1678 	kalloc_type_var_view_t  kt_view,
1679 	vm_size_t               size,
1680 	zalloc_flags_t          flags,
1681 	void                   *site);
1682 
1683 extern void kfree_type_var_impl(
1684 	kalloc_type_var_view_t  kt_view,
1685 	void                   *ptr __unsafe_indexable,
1686 	vm_size_t               size);
1687 
1688 #endif /* !XNU_KERNEL_PRIVATE */
1689 
1690 __attribute__((malloc, alloc_size(2)))
1691 static inline void *
__sized_by(size)1692 __sized_by(size)
1693 __kalloc_type_var_impl(
1694 	kalloc_type_var_view_t  kt_view,
1695 	vm_size_t               size,
1696 	zalloc_flags_t          flags,
1697 	void                   *site)
1698 {
1699 	void *__unsafe_indexable addr;
1700 
1701 	addr = (kalloc_type_var_impl)(kt_view, size, flags, site);
1702 	if (flags & Z_NOFAIL) {
1703 		__builtin_assume(addr != NULL);
1704 	}
1705 	return __unsafe_forge_bidi_indexable(void *, addr, size);
1706 }
1707 
1708 #define kalloc_type_var_impl(ktv, size, fl, site) \
1709 	__kalloc_type_var_impl(ktv, size, fl, site)
1710 
1711 extern void *kalloc_type_impl_external(
1712 	kalloc_type_view_t  kt_view,
1713 	zalloc_flags_t      flags);
1714 
1715 extern void kfree_type_impl_external(
1716 	kalloc_type_view_t  kt_view,
1717 	void               *ptr __unsafe_indexable);
1718 
1719 extern void *OSObject_typed_operator_new(
1720 	kalloc_type_view_t  ktv,
1721 	vm_size_t           size);
1722 
1723 extern void OSObject_typed_operator_delete(
1724 	kalloc_type_view_t  ktv,
1725 	void               *mem __unsafe_indexable,
1726 	vm_size_t           size);
1727 
1728 #ifdef XNU_KERNEL_PRIVATE
1729 #pragma GCC visibility push(hidden)
1730 
1731 #define KALLOC_TYPE_SIZE_MASK  0xffffff
1732 #define KALLOC_TYPE_IDX_SHIFT  24
1733 #define KALLOC_TYPE_IDX_MASK   0xff
1734 
1735 static inline uint32_t
kalloc_type_get_size(uint32_t kt_size)1736 kalloc_type_get_size(uint32_t kt_size)
1737 {
1738 	return kt_size & KALLOC_TYPE_SIZE_MASK;
1739 }
1740 
1741 extern bool IOMallocType_from_vm(
1742 	kalloc_type_view_t ktv);
1743 
1744 /* Used by kern_os_* and operator new */
1745 KALLOC_HEAP_DECLARE(KERN_OS_MALLOC);
1746 
1747 extern void kheap_startup_init(kalloc_heap_t heap);
1748 extern void kheap_var_startup_init(kalloc_heap_t heap);
1749 
1750 __attribute__((malloc, alloc_size(2)))
1751 static inline void *
__sized_by(size)1752 __sized_by(size)
1753 __kheap_alloc(
1754 	kalloc_heap_t           kheap,
1755 	vm_size_t               size,
1756 	zalloc_flags_t          flags,
1757 	void                   *site)
1758 {
1759 	struct kalloc_result kr;
1760 	__builtin_assume(!kt_is_var_view(kheap));
1761 	kr = kalloc_ext(kheap, size, flags, site);
1762 	return __unsafe_forge_bidi_indexable(void *, kr.addr, size);
1763 }
1764 
1765 extern struct kalloc_result krealloc_ext(
1766 	void                   *kheap_or_kt_view __unsafe_indexable,
1767 	void                   *addr __unsafe_indexable,
1768 	vm_size_t               old_size,
1769 	vm_size_t               new_size,
1770 	zalloc_flags_t          flags,
1771 	void                   *site);
1772 
1773 static inline struct kalloc_result
__krealloc_ext(void * kheap_or_kt_view __unsafe_indexable,void * addr __sized_by (old_size),vm_size_t old_size,vm_size_t new_size,zalloc_flags_t flags,void * site)1774 __krealloc_ext(
1775 	void                   *kheap_or_kt_view __unsafe_indexable,
1776 	void                   *addr __sized_by(old_size),
1777 	vm_size_t               old_size,
1778 	vm_size_t               new_size,
1779 	zalloc_flags_t          flags,
1780 	void                   *site)
1781 {
1782 	struct kalloc_result kr = (krealloc_ext)(kheap_or_kt_view, addr, old_size,
1783 	    new_size, flags, site);
1784 	if (flags & Z_NOFAIL) {
1785 		__builtin_assume(kr.addr != NULL);
1786 	}
1787 	return kr;
1788 }
1789 
1790 #define krealloc_ext(hov, addr, old_size, new_size, fl, site) \
1791 	__krealloc_ext(hov, addr, old_size, new_size, fl, site)
1792 
1793 __attribute__((malloc, alloc_size(4)))
1794 static inline void *
__sized_by(new_size)1795 __sized_by(new_size)
1796 __kheap_realloc(
1797 	kalloc_heap_t           kheap,
1798 	void                   *addr __sized_by(old_size),
1799 	vm_size_t               old_size,
1800 	vm_size_t               new_size,
1801 	zalloc_flags_t          flags,
1802 	void                   *site)
1803 {
1804 	struct kalloc_result kr;
1805 	__builtin_assume(!kt_is_var_view(kheap));
1806 	kr = krealloc_ext(kheap, addr, old_size, new_size, flags, site);
1807 	return __unsafe_forge_bidi_indexable(void *, kr.addr, new_size);
1808 }
1809 
1810 __attribute__((malloc, alloc_size(4)))
1811 static inline void *
__sized_by(new_size)1812 __sized_by(new_size)
1813 __krealloc_type(
1814 	kalloc_type_var_view_t  kt_view,
1815 	void                   *addr __sized_by(old_size),
1816 	vm_size_t               old_size,
1817 	vm_size_t               new_size,
1818 	zalloc_flags_t          flags,
1819 	void                   *site)
1820 {
1821 	struct kalloc_result kr;
1822 	kr = krealloc_ext(kt_mangle_var_view(kt_view), addr,
1823 	    old_size, new_size, flags, site);
1824 	return __unsafe_forge_bidi_indexable(void *, kr.addr, new_size);
1825 }
1826 
1827 extern void kfree_addr_ext(
1828 	kalloc_heap_t           kheap,
1829 	void                   *addr __unsafe_indexable);
1830 
1831 extern zone_t kalloc_zone_for_size(
1832 	zone_id_t             zid,
1833 	vm_size_t             size);
1834 
1835 extern vm_size_t kalloc_large_max;
1836 SCALABLE_COUNTER_DECLARE(kalloc_large_count);
1837 SCALABLE_COUNTER_DECLARE(kalloc_large_total);
1838 
1839 extern void kern_os_typed_free(
1840 	kalloc_type_view_t    ktv,
1841 	void                 *addr __unsafe_indexable,
1842 	vm_size_t             esize);
1843 
1844 #pragma GCC visibility pop
1845 #endif  /* !XNU_KERNEL_PRIVATE */
1846 
1847 extern void kern_os_zfree(
1848 	zone_t        zone,
1849 	void         *addr __unsafe_indexable,
1850 	vm_size_t     size);
1851 
1852 __ASSUME_PTR_ABI_SINGLE_END __END_DECLS
1853 
1854 #endif  /* _KERN_KALLOC_H_ */
1855 
1856 #endif  /* KERNEL_PRIVATE */
1857