xref: /xnu-8020.140.41/osfmk/kern/kalloc.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
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 #if __LP64__
81 #define KALLOC_SAFE_ALLOC_SIZE  (16u * 1024u)
82 #else
83 #define KALLOC_SAFE_ALLOC_SIZE  (8u * 1024u)
84 #endif
85 
86 #if XNU_KERNEL_PRIVATE
87 /*!
88  * @typedef kalloc_heap_t
89  *
90  * @abstract
91  * A kalloc heap view represents a sub-accounting context
92  * for a given kalloc heap.
93  */
94 typedef struct kalloc_heap {
95 	struct kheap_zones *kh_zones;
96 	zone_stats_t        kh_stats;
97 	const char         *kh_name __unsafe_indexable;
98 	struct kalloc_heap *kh_next;
99 	zone_kheap_id_t     kh_heap_id;
100 	vm_tag_t            kh_tag;
101 	uint16_t            kh_type_hash;
102 } *kalloc_heap_t;
103 
104 /*!
105  * @macro KALLOC_HEAP_DECLARE
106  *
107  * @abstract
108  * (optionally) declare a kalloc heap view in a header.
109  *
110  * @discussion
111  * Unlike kernel zones, new full blown heaps cannot be instantiated.
112  * However new accounting views of the base heaps can be made.
113  */
114 #define KALLOC_HEAP_DECLARE(var) \
115 	extern struct kalloc_heap var[1]
116 
117 /**
118  * @const KHEAP_ANY
119  *
120  * @brief
121  * A value that represents either the default or kext heap for codepaths that
122  * need to allow @c kheap_free() to either one.
123  *
124  * @discussion
125  * When the memory provenance is not known, this value can be used to free
126  * memory indiscriminately.
127  *
128  * Note: code using this constant can likely be used as a gadget to free
129  * arbitrary memory and its use is strongly discouraged.
130  */
131 #define KHEAP_ANY  ((struct kalloc_heap *)NULL)
132 
133 /**
134  * @const KHEAP_DATA_BUFFERS
135  *
136  * @brief
137  * The builtin heap for bags of pure bytes.
138  *
139  * @discussion
140  * This set of kalloc zones should contain pure bags of bytes with no pointers
141  * or length/offset fields.
142  *
143  * The zones forming the heap aren't sequestered from each other, however the
144  * entire heap lives in a different submap from any other kernel allocation.
145  *
146  * The main motivation behind this separation is due to the fact that a lot of
147  * these objects have been used by attackers to spray the heap to make it more
148  * predictable while exploiting use-after-frees or overflows.
149  *
150  * Common attributes that make these objects useful for spraying includes
151  * control of:
152  * - Data in allocation
153  * - Time of alloc and free (lifetime)
154  * - Size of allocation
155  */
156 KALLOC_HEAP_DECLARE(KHEAP_DATA_BUFFERS);
157 
158 /**
159  * @const KHEAP_DEFAULT
160  *
161  * @brief
162  * The builtin default core kernel kalloc heap.
163  *
164  * @discussion
165  * This set of kalloc zones should contain other objects that don't have their
166  * own security mitigations. The individual zones are themselves sequestered.
167  */
168 KALLOC_HEAP_DECLARE(KHEAP_DEFAULT);
169 
170 /**
171  * @const KHEAP_KT_VAR
172  *
173  * @brief
174  * Temporary heap for variable sized kalloc type allocations
175  *
176  * @discussion
177  * This heap will be removed when logic for kalloc_type_var_views is added
178  *
179  */
180 KALLOC_HEAP_DECLARE(KHEAP_KT_VAR);
181 
182 /*!
183  * @macro KALLOC_HEAP_DEFINE
184  *
185  * @abstract
186  * Defines a given kalloc heap view and what it points to.
187  *
188  * @discussion
189  * Kalloc heaps are views over one of the pre-defined builtin heaps
190  * (such as @c KHEAP_DATA_BUFFERS or @c KHEAP_DEFAULT). Instantiating
191  * a new one allows for accounting of allocations through this view.
192  *
193  * Kalloc heap views are initialized during the @c STARTUP_SUB_ZALLOC phase,
194  * as the last rank. If views on zones are created, these must have been
195  * created before this stage.
196  *
197  * @param var           the name for the zone view.
198  * @param name          a string describing the zone view.
199  * @param heap_id       a @c KHEAP_ID_* constant.
200  */
201 #define KALLOC_HEAP_DEFINE(var, name, heap_id) \
202 	SECURITY_READ_ONLY_LATE(struct kalloc_heap) var[1] = { { \
203 	    .kh_name = name, \
204 	    .kh_heap_id = heap_id, \
205 	} }; \
206 	STARTUP_ARG(ZALLOC, STARTUP_RANK_LAST, kheap_startup_init, var)
207 
208 
209 /*
210  * Allocations of type SO_NAME are known to not have pointers for
211  * most platforms -- for macOS this is not guaranteed
212  */
213 #if XNU_TARGET_OS_OSX
214 #define KHEAP_SONAME KHEAP_DEFAULT
215 #else /* XNU_TARGET_OS_OSX */
216 #define KHEAP_SONAME KHEAP_DATA_BUFFERS
217 #endif /* XNU_TARGET_OS_OSX */
218 
219 #endif /* XNU_KERNEL_PRIVATE */
220 
221 /*!
222  * @enum kalloc_type_flags_t
223  *
224  * @brief
225  * Flags that can be passed to @c KALLOC_TYPE_DEFINE
226  *
227  * @discussion
228  * These flags can be used to request for a specific accounting
229  * behavior.
230  *
231  * @const KT_DEFAULT
232  * Passing this flag will provide default accounting behavior
233  * i.e shared accounting unless toggled with KT_OPTIONS_ACCT is
234  * set in kt boot-arg.
235  *
236  * @const KT_PRIV_ACCT
237  * Passing this flag will provide individual stats for your
238  * @c kalloc_type_view that is defined.
239  *
240  * @const KT_SHARED_ACCT
241  * Passing this flag will accumulate stats as a part of the
242  * zone that your @c kalloc_type_view points to.
243  *
244  * @const KT_DATA_ONLY
245  * Represents that the type is "data-only". Adopters should not
246  * set this flag manually, it is meant for the compiler to set
247  * automatically when KALLOC_TYPE_CHECK(DATA) passes.
248  *
249  * @const KT_VM
250  * Represents that the type is large enough to use the VM. Adopters
251  * should not set this flag manually, it is meant for the compiler
252  * to set automatically when KALLOC_TYPE_VM_SIZE_CHECK passes.
253  *
254  * @const KT_PTR_ARRAY
255  * Represents that the type is an array of pointers. Adopters should not
256  * set this flag manually, it is meant for the compiler to set
257  * automatically when KALLOC_TYPE_CHECK(PTR) passes.
258  *
259  * @const KT_CHANGED*
260  * Represents a change in the version of the kalloc_type_view. This
261  * is required inorder to decouple requiring kexts to be rebuilt to
262  * use the new defintions right away. This flags should not be used
263  * manually at a callsite, it is meant for internal use only. Future
264  * changes to kalloc_type_view defintion should toggle this flag.
265  *
266  #if XNU_KERNEL_PRIVATE
267  *
268  * @const KT_SLID
269  * To indicate that strings in the view were slid during early boot.
270  *
271  * @const KT_PROCESSED
272  * This flag is set once the view is parse during early boot. Views
273  * that are not in BootKC on macOS aren't parsed and therefore will
274  * not have this flag set. The runtime can use this as an indication
275  * to appropriately redirect the call.
276  *
277  * @const KT_HASH
278  * Hash of signature used by kmem_*_guard to determine range and
279  * direction for allocation
280  #endif
281  */
282 __options_decl(kalloc_type_flags_t, uint32_t, {
283 	KT_DEFAULT        = 0x0001,
284 	KT_PRIV_ACCT      = 0x0002,
285 	KT_SHARED_ACCT    = 0x0004,
286 	KT_DATA_ONLY      = 0x0008,
287 	KT_VM             = 0x0010,
288 	KT_CHANGED        = 0x0020,
289 	KT_CHANGED2       = 0x0040,
290 	KT_PTR_ARRAY      = 0x0080,
291 #if XNU_KERNEL_PRIVATE
292 	KT_SLID           = 0x4000,
293 	KT_PROCESSED      = 0x8000,
294 	KT_HASH           = 0xffff0000,
295 #endif
296 });
297 
298 /*!
299  * @typedef kalloc_type_view_t
300  *
301  * @abstract
302  * A kalloc type view is a structure used to redirect callers
303  * of @c kalloc_type to a particular zone based on the signature of
304  * their type.
305  *
306  * @discussion
307  * These structures are automatically created under the hood for every
308  * @c kalloc_type and @c kfree_type callsite. They are ingested during startup
309  * and are assigned zones based on the security policy for their signature.
310  *
311  * These structs are protected by the kernel lockdown and can't be initialized
312  * dynamically. They must be created using @c KALLOC_TYPE_DEFINE() or
313  * @c kalloc_type or @c kfree_type.
314  *
315  */
316 struct kalloc_type_view {
317 	struct zone_view        kt_zv;
318 	const char             *kt_signature __unsafe_indexable;
319 	kalloc_type_flags_t     kt_flags;
320 	uint32_t                kt_size;
321 	void                   *unused1;
322 	void                   *unused2;
323 };
324 
325 typedef struct kalloc_type_view *kalloc_type_view_t;
326 
327 /*
328  * "Heaps" or sets of zones, used for variable size kalloc_type allocations
329  * are defined by the constants below.
330  *
331  * KHEAP_START_SIZE: Size of the first sequential zone.
332  * KHEAP_MAX_SIZE  : Size of the last sequential zone.
333  * KHEAP_STEP_WIDTH: Number of zones created at every step (power of 2).
334  * KHEAP_STEP_START: Size of the first step.
335  * We also create some extra initial zones that don't follow the sequence
336  * for sizes 8 (on armv7 only), 16 and 32.
337  *
338  * idx step_increment   zone_elem_size
339  * 0       -                  16
340  * 1       -                  32
341  * 2       16                 48
342  * 3       16                 64
343  * 4       32                 96
344  * 5       32                 128
345  * 6       64                 192
346  * 7       64                 256
347  * 8       128                384
348  * 9       128                512
349  * 10      256                768
350  * 11      256                1024
351  * 12      512                1536
352  * 13      512                2048
353  * 14      1024               3072
354  * 15      1024               4096
355  * 16      2048               6144
356  * 17      2048               8192
357  * 18      4096               12288
358  * 19      4096               16384
359  * 20      8192               24576
360  * 21      8192               32768
361  */
362 #define kalloc_log2down(mask)   (31 - __builtin_clz(mask))
363 #define KHEAP_START_SIZE        32
364 #if !defined(__LP64__)
365 #define KHEAP_MAX_SIZE          8 * 1024
366 #define KHEAP_EXTRA_ZONES       3
367 #elif  __x86_64__
368 #define KHEAP_MAX_SIZE          16 * 1024
369 #define KHEAP_EXTRA_ZONES       2
370 #else
371 #define KHEAP_MAX_SIZE          32 * 1024
372 #define KHEAP_EXTRA_ZONES       2
373 #endif
374 #define KHEAP_STEP_WIDTH        2
375 #define KHEAP_STEP_START        16
376 #define KHEAP_START_IDX         kalloc_log2down(KHEAP_START_SIZE)
377 #define KHEAP_NUM_STEPS         (kalloc_log2down(KHEAP_MAX_SIZE) - \
378 	                                kalloc_log2down(KHEAP_START_SIZE))
379 #define KHEAP_NUM_ZONES         (KHEAP_NUM_STEPS * KHEAP_STEP_WIDTH + \
380 	                                KHEAP_EXTRA_ZONES)
381 
382 /*!
383  * @enum kalloc_type_version_t
384  *
385  * @brief
386  * Enum that holds versioning information for @c kalloc_type_var_view
387  *
388  * @const KT_V1
389  * Version 1
390  *
391  */
392 __options_decl(kalloc_type_version_t, uint16_t, {
393 	KT_V1             = 0x0001,
394 });
395 
396 /*!
397  * @typedef kalloc_type_var_view_t
398  *
399  * @abstract
400  * This structure is analoguous to @c kalloc_type_view but handles
401  * @c kalloc_type callsites that are variable in size.
402  *
403  * @discussion
404  * These structures are automatically created under the hood for every
405  * variable sized @c kalloc_type and @c kfree_type callsite. They are ingested
406  * during startup and are assigned zones based on the security policy for
407  * their signature.
408  *
409  * These structs are protected by the kernel lockdown and can't be initialized
410  * dynamically. They must be created using @c KALLOC_TYPE_VAR_DEFINE() or
411  * @c kalloc_type or @c kfree_type.
412  *
413  */
414 struct kalloc_type_var_view {
415 	kalloc_type_version_t   kt_version;
416 	uint16_t                kt_size_hdr;
417 	/*
418 	 * Temporary: Needs to be 32bits cause we have many structs that use
419 	 * IONew/Delete that are larger than 32K.
420 	 */
421 	uint32_t                kt_size_type;
422 	zone_stats_t            kt_stats;
423 	const char             *kt_name __unsafe_indexable;
424 	zone_view_t             kt_next;
425 	zone_id_t               kt_heap_start;
426 	uint8_t                 kt_zones[KHEAP_NUM_ZONES];
427 	const char             *kt_sig_hdr __unsafe_indexable;
428 	const char             *kt_sig_type __unsafe_indexable;
429 	kalloc_type_flags_t     kt_flags;
430 };
431 
432 typedef struct kalloc_type_var_view *kalloc_type_var_view_t;
433 
434 /*!
435  * @macro KALLOC_TYPE_DECLARE
436  *
437  * @abstract
438  * (optionally) declares a kalloc type view (in a header).
439  *
440  * @param var           the name for the kalloc type view.
441  */
442 #define KALLOC_TYPE_DECLARE(var) \
443 	extern struct kalloc_type_view var[1]
444 
445 /*!
446  * @macro KALLOC_TYPE_DEFINE
447  *
448  * @abstract
449  * Defines a given kalloc type view with prefered accounting
450  *
451  * @discussion
452  * This macro allows you to define a kalloc type with private
453  * accounting. The defined kalloc_type_view can be used with
454  * kalloc_type_impl/kfree_type_impl to allocate/free memory.
455  * zalloc/zfree can also be used from inside xnu. However doing
456  * so doesn't handle freeing a NULL pointer or the use of tags.
457  *
458  * @param var           the name for the kalloc type view.
459  * @param type          the type of your allocation.
460  * @param flags         a @c KT_* flag.
461  */
462 #define KALLOC_TYPE_DEFINE(var, type, flags) \
463 	_KALLOC_TYPE_DEFINE(var, type, flags)
464 
465 /*!
466  * @macro KALLOC_TYPE_VAR_DECLARE
467  *
468  * @abstract
469  * (optionally) declares a kalloc type var view (in a header).
470  *
471  * @param var           the name for the kalloc type var view.
472  */
473 #define KALLOC_TYPE_VAR_DECLARE(var) \
474 	extern struct kalloc_type_var_view var[1]
475 
476 /*!
477  * @macro KALLOC_TYPE_VAR_DEFINE
478  *
479  * @abstract
480  * Defines a given kalloc type view with prefered accounting for
481  * variable sized typed allocations.
482  *
483  * @discussion
484  * As the views aren't yet being ingested, individual stats aren't
485  * available. The defined kalloc_type_var_view should be used with
486  * kalloc_type_var_impl/kfree_type_var_impl to allocate/free memory.
487  *
488  * This macro comes in 2 variants:
489  *
490  * 1. @c KALLOC_TYPE_VAR_DEFINE(var, e_ty, flags)
491  * 2. @c KALLOC_TYPE_VAR_DEFINE(var, h_ty, e_ty, flags)
492  *
493  * @param var           the name for the kalloc type var view.
494  * @param h_ty          the type of header in the allocation.
495  * @param e_ty          the type of repeating part in the allocation.
496  * @param flags         a @c KT_* flag.
497  */
498 #define KALLOC_TYPE_VAR_DEFINE(...) KALLOC_DISPATCH(KALLOC_TYPE_VAR_DEFINE, ##__VA_ARGS__)
499 
500 #ifdef XNU_KERNEL_PRIVATE
501 
502 /*
503  * These versions allow specifying the kalloc heap to allocate memory
504  * from
505  */
506 #define kheap_alloc_tag(kalloc_heap, size, flags, itag) \
507 	__kheap_alloc(kalloc_heap, size, __zone_flags_mix_tag(flags, itag), NULL)
508 #define kheap_alloc(kalloc_heap, size, flags) \
509 	kheap_alloc_tag(kalloc_heap, size, flags, VM_ALLOC_SITE_TAG())
510 
511 /*
512  * These versions should be used for allocating pure data bytes that
513  * do not contain any pointers
514  */
515 #define kalloc_data_tag(size, flags, itag) \
516 	kheap_alloc_tag(KHEAP_DATA_BUFFERS, size, flags, itag)
517 #define kalloc_data(size, flags) \
518 	kheap_alloc(KHEAP_DATA_BUFFERS, size, flags)
519 
520 #define krealloc_data_tag(elem, old_size, new_size, flags, itag) \
521 	__kheap_realloc(KHEAP_DATA_BUFFERS, elem, old_size, new_size, \
522 	    __zone_flags_mix_tag(flags, itag), NULL)
523 #define krealloc_data(elem, old_size, new_size, flags) \
524 	krealloc_data_tag(elem, old_size, new_size, flags, \
525 	    VM_ALLOC_SITE_TAG())
526 
527 #define kfree_data(elem, size) \
528 	kheap_free(KHEAP_DATA_BUFFERS, elem, size);
529 
530 #define kfree_data_addr(elem) \
531 	kheap_free_addr(KHEAP_DATA_BUFFERS, elem);
532 
533 extern void
534 kheap_free_bounded(
535 	kalloc_heap_t heap,
536 	void         *addr __unsafe_indexable,
537 	vm_size_t     min_sz,
538 	vm_size_t     max_sz);
539 
540 extern void
541 kalloc_data_require(
542 	void         *data __unsafe_indexable,
543 	vm_size_t     size);
544 
545 extern void
546 kalloc_non_data_require(
547 	void         *data __unsafe_indexable,
548 	vm_size_t     size);
549 
550 #else /* XNU_KERNEL_PRIVATE */
551 
552 extern void *__sized_by(size)
553 kalloc(
554 	vm_size_t           size) __attribute__((malloc, alloc_size(1)));
555 
556 extern void *__sized_by(size)
557 kalloc_data(
558 	vm_size_t           size,
559 	zalloc_flags_t      flags) __attribute__((malloc, alloc_size(1)));
560 
561 extern void *__sized_by(new_size)
562 krealloc_data(
563 	void               *ptr __unsafe_indexable,
564 	vm_size_t           old_size,
565 	vm_size_t           new_size,
566 	zalloc_flags_t      flags) __attribute__((malloc, alloc_size(3)));
567 
568 extern void
569 kfree(
570 	void               *data __unsafe_indexable,
571 	vm_size_t           size);
572 
573 extern void
574 kfree_data(
575 	void               *ptr __unsafe_indexable,
576 	vm_size_t           size);
577 
578 extern void
579 kfree_data_addr(
580 	void               *ptr __unsafe_indexable);
581 
582 #endif /* !XNU_KERNEL_PRIVATE */
583 
584 /*!
585  * @macro kalloc_type
586  *
587  * @abstract
588  * Allocates element of a particular type
589  *
590  * @discussion
591  * This family of allocators segregate kalloc allocations based on their type.
592  *
593  * This macro comes in 3 variants:
594  *
595  * 1. @c kalloc_type(type, flags)
596  *    Use this macro for fixed sized allocation of a particular type.
597  *
598  * 2. @c kalloc_type(e_type, count, flags)
599  *    Use this macro for variable sized allocations that form an array,
600  *    do note that @c kalloc_type(e_type, 1, flags) is not equivalent to
601  *    @c kalloc_type(e_type, flags).
602  *
603  * 3. @c kalloc_type(hdr_type, e_type, count, flags)
604  *    Use this macro for variable sized allocations formed with
605  *    a header of type @c hdr_type followed by a variable sized array
606  *    with elements of type @c e_type, equivalent to this:
607  *
608  *    <code>
609  *    struct {
610  *        hdr_type hdr;
611  *        e_type   arr[];
612  *    }
613  *    </code>
614  *
615  * @param flags         @c zalloc_flags_t that get passed to zalloc_internal
616  */
617 #define kalloc_type(...)  KALLOC_DISPATCH(kalloc_type, ##__VA_ARGS__)
618 
619 /*!
620  * @macro kfree_type
621  *
622  * @abstract
623  * Allocates element of a particular type
624  *
625  * @discussion
626  * This pairs with the @c kalloc_type() that was made to allocate this element.
627  * Arguments passed to @c kfree_type() must match the one passed at allocation
628  * time precisely.
629  *
630  * This macro comes in the same 3 variants kalloc_type() does:
631  *
632  * 1. @c kfree_type(type, elem)
633  * 2. @c kfree_type(e_type, count, elem)
634  * 3. @c kfree_type(hdr_type, e_type, count, elem)
635  *
636  * @param elem          The address of the element to free
637  */
638 #define kfree_type(...)  KALLOC_DISPATCH(kfree_type, ##__VA_ARGS__)
639 
640 #ifdef XNU_KERNEL_PRIVATE
641 #define kalloc_type_tag(...)     KALLOC_DISPATCH(kalloc_type_tag, ##__VA_ARGS__)
642 #define krealloc_type_tag(...)   KALLOC_DISPATCH(krealloc_type_tag, ##__VA_ARGS__)
643 #define krealloc_type(...)       KALLOC_DISPATCH(krealloc_type, ##__VA_ARGS__)
644 
645 /*
646  * kalloc_type_require can't be made available to kexts as the
647  * kalloc_type_view's zone could be NULL in the following cases:
648  * - Size greater than KALLOC_SAFE_ALLOC_SIZE
649  * - On macOS, if call is not in BootKC
650  * - All allocations in kext for armv7
651  */
652 #define kalloc_type_require(type, value) ({                                    \
653 	static KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);          \
654 	zone_require(kt_view_var->kt_zv, value);                               \
655 })
656 
657 #endif
658 
659 /*!
660  * @enum kt_granule_t
661  *
662  * @brief
663  * Granule encodings used by the compiler for the type signature.
664  *
665  * @discussion
666  * Given a type, the XNU signature type system (__builtin_xnu_type_signature)
667  * produces a signature by analyzing its memory layout, in chunks of 8 bytes,
668  * which we call granules. The encoding produced for each granule is the
669  * bitwise or of the encodings of all the types of the members included
670  * in that granule.
671  *
672  * @const KT_GRANULE_PADDING
673  * Represents padding inside a record type.
674  *
675  * @const KT_GRANULE_POINTER
676  * Represents a pointer type.
677  *
678  * @const KT_GRANULE_DATA
679  * Represents a scalar type that is not a pointer.
680  *
681  * @const KT_GRANULE_DUAL
682  * Currently unused.
683  *
684  * @const KT_GRANULE_PAC
685  * Represents a pointer which is subject to PAC.
686  */
687 __options_decl(kt_granule_t, uint32_t, {
688 	KT_GRANULE_PADDING = 0,
689 	KT_GRANULE_POINTER = 1,
690 	KT_GRANULE_DATA    = 2,
691 	KT_GRANULE_DUAL    = 4,
692 	KT_GRANULE_PAC     = 8
693 });
694 
695 #define KT_GRANULE_MAX                                                \
696 	(KT_GRANULE_PADDING | KT_GRANULE_POINTER | KT_GRANULE_DATA |  \
697 	    KT_GRANULE_DUAL | KT_GRANULE_PAC)
698 
699 /*
700  * Convert a granule encoding to the index of the bit that
701  * represents such granule in the type summary.
702  *
703  * The XNU type summary (__builtin_xnu_type_summary) produces a 32-bit
704  * summary of the type signature of a given type. If the bit at index
705  * (1 << G) is set in the summary, that means that the type contains
706  * one or more granules with encoding G.
707  */
708 #define KT_SUMMARY_GRANULE_TO_IDX(g)  (1UL << g)
709 
710 #define KT_SUMMARY_MASK_TYPE_BITS  (0xffff)
711 
712 #define KT_SUMMARY_MASK_DATA                             \
713 	(KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PADDING) |  \
714 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_DATA))
715 
716 #define KT_SUMMARY_MASK_PTR                              \
717 	(KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PADDING) |     \
718 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_POINTER) |  \
719 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PAC))
720 
721 #define KT_SUMMARY_MASK_ALL_GRANULES                        \
722 	(KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PADDING) |     \
723 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_POINTER) |  \
724 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_DATA) |     \
725 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_DUAL) |     \
726 	    KT_SUMMARY_GRANULE_TO_IDX(KT_GRANULE_PAC))
727 
728 /*!
729  * @macro KT_SUMMARY_GRANULES
730  *
731  * @abstract
732  * Return the granule type summary for a given type
733  *
734  * @discussion
735  * This macro computes the type summary of a type, and it then extracts the
736  * bits which carry information about the granules in the memory layout.
737  *
738  * Note: you should never have to use __builtin_xnu_type_summary
739  * directly, as we reserve the right to use the remaining bits with
740  * different semantics.
741  *
742  * @param type          The type to analyze
743  */
744 #define KT_SUMMARY_GRANULES(type) \
745     (__builtin_xnu_type_summary(type) & KT_SUMMARY_MASK_TYPE_BITS)
746 
747 /*!
748  * @macro KALLOC_TYPE_IS_DATA_ONLY
749  *
750  * @abstract
751  * Return whether a given type is considered a data-only type.
752  *
753  * @param type          The type to analyze
754  */
755 #define KALLOC_TYPE_IS_DATA_ONLY(type) \
756     ((KT_SUMMARY_GRANULES(type) & ~KT_SUMMARY_MASK_DATA) == 0)
757 
758 /*!
759  * @macro KALLOC_TYPE_SIG_CHECK
760  *
761  * @abstract
762  * Return whether a given type is only made up of granules specified in mask
763  *
764  * @param mask          Granules to check for
765  * @param type          The type to analyze
766  */
767 #define KALLOC_TYPE_SIG_CHECK(mask, type) \
768     ((KT_SUMMARY_GRANULES(type) & ~(mask)) == 0)
769 
770 /*!
771  * @macro KALLOC_TYPE_HAS_OVERLAPS
772  *
773  * @abstract
774  * Return whether a given type has overlapping granules.
775  *
776  * @discussion
777  * This macro returns whether the memory layout for a given type contains
778  * overlapping granules. An overlapping granule is a granule which includes
779  * members with types that have different encodings under the XNU signature
780  * type system.
781  *
782  * @param type          The type to analyze
783  */
784 #define KALLOC_TYPE_HAS_OVERLAPS(type) \
785 	((KT_SUMMARY_GRANULES(type) & ~KT_SUMMARY_MASK_ALL_GRANULES) != 0)
786 
787 /*!
788  * @macro KALLOC_TYPE_IS_COMPATIBLE_PTR
789  *
790  * @abstract
791  * Return whether pointer is compatible with a given type, in the XNU
792  * signature type system.
793  *
794  * @discussion
795  * This macro returns whether type pointed to by @c ptr is either the same
796  * type as @c type, or it has the same signature. The implementation relies
797  * on the @c __builtin_xnu_types_compatible builtin, and the value returned
798  * can be evaluated at compile time in both C and C++.
799  *
800  * Note: void pointers are treated as wildcards, and are thus compatible
801  * with any given type.
802  *
803  * @param ptr           the pointer whose type needs to be checked.
804  * @param type          the type which the pointer will be checked against.
805  */
806 #define KALLOC_TYPE_IS_COMPATIBLE_PTR(ptr, type)                   \
807 	_Pragma("clang diagnostic push")                               \
808 	_Pragma("clang diagnostic ignored \"-Wvoid-ptr-dereference\"") \
809 	(__builtin_xnu_types_compatible(__typeof__(*ptr), type) ||     \
810 	    __builtin_xnu_types_compatible(__typeof__(*ptr), void))    \
811 	_Pragma("clang diagnostic pop")
812 
813 #define KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(ptr, type)                  \
814 	_Static_assert(KALLOC_TYPE_IS_COMPATIBLE_PTR(ptr, type),           \
815 	    "Pointer type is not compatible with specified type")
816 
817 #pragma mark implementation details
818 
819 
820 static inline void *
kt_mangle_var_view(kalloc_type_var_view_t kt_view)821 kt_mangle_var_view(kalloc_type_var_view_t kt_view)
822 {
823 	return (void *)((uintptr_t)kt_view | 1ul);
824 }
825 
826 static inline kalloc_type_var_view_t
kt_demangle_var_view(void * ptr)827 kt_demangle_var_view(void *ptr)
828 {
829 	return (kalloc_type_var_view_t)((uintptr_t)ptr & ~1ul);
830 }
831 
832 #define kt_is_var_view(ptr)  ((uintptr_t)(ptr) & 1)
833 
834 static inline vm_size_t
kt_size(vm_size_t s1,vm_size_t s2,vm_size_t c2)835 kt_size(vm_size_t s1, vm_size_t s2, vm_size_t c2)
836 {
837 	/* kalloc_large() will reject this size before even asking the VM  */
838 	const vm_size_t limit = 1ull << (8 * sizeof(vm_size_t) - 1);
839 
840 	if (os_mul_and_add_overflow(s2, c2, s1, &s1) || (s1 & limit)) {
841 		return limit;
842 	}
843 	return s1;
844 }
845 
846 #define kalloc_type_2(type, flags) ({                                          \
847 	static KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);          \
848 	__unsafe_forge_single(type *, kalloc_type_impl(kt_view_var, flags));   \
849 })
850 
851 #define kfree_type_2(type, elem) ({                                            \
852 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, type);                     \
853 	static KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);          \
854 	kfree_type_impl(kt_view_var, os_ptr_load_and_erase(elem));             \
855 })
856 
857 #define kfree_type_3(type, count, elem) ({                                     \
858 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, type);                     \
859 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
860 	__auto_type __kfree_count = (count);                                   \
861 	kfree_type_var_impl(kt_view_var, os_ptr_load_and_erase(elem),          \
862 	    kt_size(0, sizeof(type), __kfree_count));                          \
863 })
864 
865 #define kfree_type_4(hdr_ty, e_ty, count, elem) ({                             \
866 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, hdr_ty);                   \
867 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
868 	    KT_SHARED_ACCT);                                                   \
869 	__auto_type __kfree_count = (count);                                   \
870 	kfree_type_var_impl(kt_view_var,                                       \
871 	    os_ptr_load_and_erase(elem),                                       \
872 	    kt_size(sizeof(hdr_ty), sizeof(e_ty), __kfree_count));             \
873 })
874 
875 #ifdef XNU_KERNEL_PRIVATE
876 #define kalloc_type_tag_3(type, flags, tag) ({                                 \
877 	static KALLOC_TYPE_DEFINE(kt_view_var, type, KT_SHARED_ACCT);          \
878 	__unsafe_forge_single(type *, zalloc_flags(kt_view_var,                \
879 	    Z_VM_TAG(flags, tag)));                                            \
880 })
881 
882 #define kalloc_type_tag_4(type, count, flags, tag) ({                          \
883 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
884 	(type *)kalloc_type_var_impl(kt_view_var,                              \
885 	    kt_size(0, sizeof(type), count),                                   \
886 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
887 })
888 #define kalloc_type_3(type, count, flags)  \
889 	kalloc_type_tag_4(type, count, flags, VM_ALLOC_SITE_TAG())
890 
891 #define kalloc_type_tag_5(hdr_ty, e_ty, count, flags, tag) ({                  \
892 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
893 	    KT_SHARED_ACCT);                                                   \
894 	(hdr_ty *)kalloc_type_var_impl(kt_view_var,                            \
895 	    kt_size(sizeof(hdr_ty), sizeof(e_ty), count),                      \
896 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
897 })
898 #define kalloc_type_4(hdr_ty, e_ty, count, flags) \
899 	kalloc_type_tag_5(hdr_ty, e_ty, count, flags, VM_ALLOC_SITE_TAG())
900 
901 #define krealloc_type_tag_6(type, old_count, new_count, elem, flags, tag) ({   \
902 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
903 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, type);                     \
904 	(type *)__krealloc_type(kt_view_var, elem,                             \
905 	    kt_size(0, sizeof(type), old_count),                               \
906 	    kt_size(0, sizeof(type), new_count),                               \
907 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
908 })
909 #define krealloc_type_5(type, old_count, new_count, elem, flags) \
910 	krealloc_type_tag_6(type, old_count, new_count, elem, flags, \
911 	    VM_ALLOC_SITE_TAG())
912 
913 #define krealloc_type_tag_7(hdr_ty, e_ty, old_count, new_count, elem,          \
914 	    flags, tag) ({                                                     \
915 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
916 	    KT_SHARED_ACCT);                                                   \
917 	KALLOC_TYPE_ASSERT_COMPATIBLE_POINTER(elem, hdr_ty);                   \
918 	(hdr_ty *)__krealloc_type(kt_view_var, elem,                           \
919 	    kt_size(sizeof(hdr_ty), sizeof(e_ty), old_count),                  \
920 	    kt_size(sizeof(hdr_ty), sizeof(e_ty), new_count),                  \
921 	    __zone_flags_mix_tag(flags, tag), NULL);                           \
922 })
923 #define krealloc_type_6(hdr_ty, e_ty, old_count, new_count, elem, flags) \
924 	krealloc_type_tag_7(hdr_ty, e_ty, old_count, new_count, elem, flags,   \
925 	    VM_ALLOC_SITE_TAG())
926 
927 #else /* XNU_KERNEL_PRIVATE */
928 
929 #define kalloc_type_3(type, count, flags) ({                                   \
930 	_Static_assert((flags) == Z_WAITOK, "kexts can only pass Z_WAITOK");   \
931 	static KALLOC_TYPE_VAR_DEFINE_3(kt_view_var, type, KT_SHARED_ACCT);    \
932 	(type *)kalloc_type_var_impl(kt_view_var,                              \
933 	    kt_size(0, sizeof(type), count), flags, NULL);                     \
934 })
935 
936 #define kalloc_type_4(hdr_ty, e_ty, count, flags) ({                           \
937 	_Static_assert((flags) == Z_WAITOK, "kexts can only pass Z_WAITOK");   \
938 	static KALLOC_TYPE_VAR_DEFINE_4(kt_view_var, hdr_ty, e_ty,             \
939 	    KT_SHARED_ACCT);                                                   \
940 	(hdr_ty *)kalloc_type_var_impl(kt_view_var, kt_size(sizeof(hdr_ty),    \
941 	    sizeof(e_ty), count), flags, NULL);                                \
942 })
943 
944 #endif /* !XNU_KERNEL_PRIVATE */
945 
946 /*
947  * All k*free macros set "elem" to NULL on free.
948  *
949  * Note: all values passed to k*free() might be in the element to be freed,
950  *       temporaries must be taken, and the resetting to be done prior to free.
951  */
952 #ifdef XNU_KERNEL_PRIVATE
953 
954 #define kheap_free(heap, elem, size) ({                                        \
955 	kalloc_heap_t __kfree_heap = (heap);                                   \
956 	__auto_type __kfree_size = (size);                                     \
957 	__builtin_assume(!kt_is_var_view(__kfree_heap));                       \
958 	kfree_ext((void *)__kfree_heap,                                        \
959 	    (void *)os_ptr_load_and_erase(elem), __kfree_size);                \
960 })
961 
962 #define kheap_free_addr(heap, elem) ({                                         \
963 	kalloc_heap_t __kfree_heap = (heap);                                   \
964 	kfree_addr_ext(__kfree_heap, (void *)os_ptr_load_and_erase(elem));     \
965 })
966 
967 #define kheap_free_bounded(heap, elem, min_sz, max_sz) ({                      \
968 	static_assert(max_sz <= KALLOC_SAFE_ALLOC_SIZE);                       \
969 	kalloc_heap_t __kfree_heap = (heap);                                   \
970 	__auto_type __kfree_min_sz = (min_sz);                                 \
971 	__auto_type __kfree_max_sz = (max_sz);                                 \
972 	(kheap_free_bounded)(__kfree_heap,                                     \
973 	    (void *)os_ptr_load_and_erase(elem),                               \
974 	    __kfree_min_sz, __kfree_max_sz);                                   \
975 })
976 
977 #else /* XNU_KERNEL_PRIVATE */
978 
979 #define kfree_data(elem, size) ({                                              \
980 	__auto_type __kfree_size = (size);                                     \
981 	(kfree_data)((void *)os_ptr_load_and_erase(elem), __kfree_size);       \
982 })
983 
984 #define kfree_data_addr(elem) \
985 	(kfree_data_addr)((void *)os_ptr_load_and_erase(elem))
986 
987 #endif /* !XNU_KERNEL_PRIVATE */
988 
989 #if __has_feature(address_sanitizer)
990 # define __kalloc_no_kasan __attribute__((no_sanitize("address")))
991 #else
992 # define __kalloc_no_kasan
993 #endif
994 
995 #define KALLOC_CONCAT(x, y) __CONCAT(x,y)
996 
997 #define KALLOC_COUNT_ARGS1(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, N, ...) N
998 #define KALLOC_COUNT_ARGS(...) \
999 	KALLOC_COUNT_ARGS1(, ##__VA_ARGS__, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
1000 #define KALLOC_DISPATCH1(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
1001 #define KALLOC_DISPATCH(base, ...) \
1002 	KALLOC_DISPATCH1(base, KALLOC_COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
1003 #define KALLOC_DISPATCH1_R(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
1004 #define KALLOC_DISPATCH_R(base, ...) \
1005 	KALLOC_DISPATCH1_R(base, KALLOC_COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
1006 
1007 #define kt_view_var \
1008 	KALLOC_CONCAT(kalloc_type_view_, __LINE__)
1009 
1010 #if __LP64__
1011 #define KALLOC_TYPE_SEGMENT "__DATA_CONST"
1012 #else
1013 #define KALLOC_TYPE_SEGMENT "__DATA"
1014 #endif
1015 
1016 /*
1017  * When kalloc_type_impl is called from xnu, it calls zalloc_flags
1018  * directly and doesn't redirect zone-less sites to kheap_alloc.
1019  * Passing a size larger than KHEAP_MAX_SIZE for these allocations will
1020  * lead to a panic as the zone is null. Therefore assert that size
1021  * is less than KALLOC_SAFE_ALLOC_SIZE.
1022  */
1023 #ifdef XNU_KERNEL_PRIVATE
1024 #define KALLOC_TYPE_SIZE_CHECK(size)                           \
1025 	_Static_assert(size <= KALLOC_SAFE_ALLOC_SIZE,             \
1026 	"type is too large");
1027 #else
1028 #define KALLOC_TYPE_SIZE_CHECK(size)
1029 #endif
1030 
1031 #define KALLOC_TYPE_CHECK_2(check, type) \
1032 	(KALLOC_TYPE_SIG_CHECK(check, type))
1033 
1034 #define KALLOC_TYPE_CHECK_3(check, type1, type2) \
1035 	(KALLOC_TYPE_SIG_CHECK(check, type1) && \
1036 	    KALLOC_TYPE_SIG_CHECK(check, type2))
1037 
1038 #define KALLOC_TYPE_CHECK(...) \
1039 	KALLOC_DISPATCH_R(KALLOC_TYPE_CHECK, ##__VA_ARGS__)
1040 
1041 #define KALLOC_TYPE_VM_SIZE_CHECK_1(type) \
1042 	(sizeof(type) > KHEAP_MAX_SIZE)
1043 
1044 #define KALLOC_TYPE_VM_SIZE_CHECK_2(type1, type2) \
1045 	(sizeof(type1) + sizeof(type2) > KHEAP_MAX_SIZE)
1046 
1047 #define KALLOC_TYPE_VM_SIZE_CHECK(...) \
1048 	KALLOC_DISPATCH_R(KALLOC_TYPE_VM_SIZE_CHECK, ##__VA_ARGS__)
1049 
1050 #ifdef __cplusplus
1051 #define KALLOC_TYPE_CAST_FLAGS(flags) static_cast<kalloc_type_flags_t>(flags)
1052 #else
1053 #define KALLOC_TYPE_CAST_FLAGS(flags) (kalloc_type_flags_t)(flags)
1054 #endif
1055 
1056 /*
1057  * Don't emit signature if type is "data-only" or is large enough that it
1058  * uses the VM.
1059  *
1060  * Note: sig_type is the type you want to emit signature for. The variable
1061  * args can be used to provide other types in the allocation, to make the
1062  * decision of whether to emit the signature.
1063  */
1064 #define KALLOC_TYPE_EMIT_SIG(sig_type, ...)                              \
1065 	(KALLOC_TYPE_CHECK(KT_SUMMARY_MASK_DATA, sig_type, ##__VA_ARGS__) || \
1066 	KALLOC_TYPE_VM_SIZE_CHECK(sig_type, ##__VA_ARGS__))?                 \
1067 	"" : __builtin_xnu_type_signature(sig_type)
1068 
1069 /*
1070  * Kalloc type flags are adjusted to indicate if the type is "data-only" or
1071  * will use the VM or is a pointer array.
1072  */
1073 #define KALLOC_TYPE_ADJUST_FLAGS(flags, ...)                                 \
1074 	KALLOC_TYPE_CAST_FLAGS((flags | KT_CHANGED | KT_CHANGED2 |               \
1075 	(KALLOC_TYPE_CHECK(KT_SUMMARY_MASK_DATA, __VA_ARGS__)? KT_DATA_ONLY: 0) |\
1076 	(KALLOC_TYPE_CHECK(KT_SUMMARY_MASK_PTR, __VA_ARGS__)? KT_PTR_ARRAY: 0) | \
1077 	(KALLOC_TYPE_VM_SIZE_CHECK(__VA_ARGS__)? KT_VM : 0)))
1078 
1079 #define _KALLOC_TYPE_DEFINE(var, type, flags)                       \
1080 	__kalloc_no_kasan                                               \
1081 	__PLACE_IN_SECTION(KALLOC_TYPE_SEGMENT ", __kalloc_type")       \
1082 	struct kalloc_type_view var[1] = { {                            \
1083 	    .kt_zv.zv_name = "site." #type,                             \
1084 	    .kt_flags = KALLOC_TYPE_ADJUST_FLAGS(flags, type),          \
1085 	    .kt_size = sizeof(type),                                    \
1086 	    .kt_signature = KALLOC_TYPE_EMIT_SIG(type),                 \
1087 	} };                                                            \
1088 	KALLOC_TYPE_SIZE_CHECK(sizeof(type));
1089 
1090 #define KALLOC_TYPE_VAR_DEFINE_3(var, type, flags)                  \
1091 	__kalloc_no_kasan                                               \
1092 	__PLACE_IN_SECTION(KALLOC_TYPE_SEGMENT ", __kalloc_var")        \
1093 	struct kalloc_type_var_view var[1] = { {                        \
1094 	    .kt_version = KT_V1,                                        \
1095 	    .kt_name = "site." #type,                                   \
1096 	    .kt_flags = KALLOC_TYPE_ADJUST_FLAGS(flags, type),          \
1097 	    .kt_size_type = sizeof(type),                               \
1098 	    .kt_sig_type = KALLOC_TYPE_EMIT_SIG(type),                  \
1099 	} };                                                            \
1100 	KALLOC_TYPE_SIZE_CHECK(sizeof(type));
1101 
1102 #define KALLOC_TYPE_VAR_DEFINE_4(var, hdr, type, flags)             \
1103 	__kalloc_no_kasan                                               \
1104 	__PLACE_IN_SECTION(KALLOC_TYPE_SEGMENT ", __kalloc_var")        \
1105 	struct kalloc_type_var_view var[1] = { {                        \
1106 	    .kt_version = KT_V1,                                        \
1107 	    .kt_name = "site." #hdr "." #type,                          \
1108 	    .kt_flags = KALLOC_TYPE_ADJUST_FLAGS(flags, hdr, type),     \
1109 	    .kt_size_hdr = sizeof(hdr),                                 \
1110 	    .kt_size_type = sizeof(type),                               \
1111 	    .kt_sig_hdr = KALLOC_TYPE_EMIT_SIG(hdr, type),              \
1112 	    .kt_sig_type = KALLOC_TYPE_EMIT_SIG(type, hdr),             \
1113 	} };                                                            \
1114 	KALLOC_TYPE_SIZE_CHECK(sizeof(hdr));                            \
1115 	KALLOC_TYPE_SIZE_CHECK(sizeof(type));
1116 
1117 #ifndef XNU_KERNEL_PRIVATE
1118 /*
1119  * This macro is currently used by AppleImage4
1120  */
1121 #define KALLOC_TYPE_DEFINE_SITE(var, type, flags)       \
1122 	static _KALLOC_TYPE_DEFINE(var, type, flags)
1123 
1124 #endif /* !XNU_KERNEL_PRIVATE */
1125 
1126 #ifdef XNU_KERNEL_PRIVATE
1127 
1128 #define kalloc_type_impl(kt_view, flags) \
1129 	zalloc_flags(kt_view, flags)
1130 
1131 static inline void
kfree_type_impl(kalloc_type_view_t kt_view,void * __unsafe_indexable ptr)1132 kfree_type_impl(kalloc_type_view_t kt_view, void *__unsafe_indexable ptr)
1133 {
1134 	if (NULL == ptr) {
1135 		return;
1136 	}
1137 	zfree(kt_view, ptr);
1138 }
1139 
1140 #define kalloc_type_var_impl(kt_view, size, flags, site) \
1141 	kalloc_ext(kt_mangle_var_view(kt_view), size, flags, site).addr
1142 
1143 #define kfree_type_var_impl(kt_view, ptr, size) \
1144 	kfree_ext(kt_mangle_var_view(kt_view), ptr, size)
1145 
1146 #else /* XNU_KERNEL_PRIVATE */
1147 
1148 extern void *__unsafe_indexable
1149 kalloc_type_impl(
1150 	kalloc_type_view_t  kt_view,
1151 	zalloc_flags_t      flags);
1152 
1153 extern void
1154 kfree_type_impl(
1155 	kalloc_type_view_t  kt_view,
1156 	void                *ptr __unsafe_indexable);
1157 
1158 __attribute__((malloc, alloc_size(2)))
1159 extern void *__sized_by(size)
1160 kalloc_type_var_impl(
1161 	kalloc_type_var_view_t  kt_view,
1162 	vm_size_t               size,
1163 	zalloc_flags_t          flags,
1164 	void                   *site);
1165 
1166 extern void
1167 kfree_type_var_impl(
1168 	kalloc_type_var_view_t  kt_view,
1169 	void                   *ptr __unsafe_indexable,
1170 	vm_size_t               size);
1171 
1172 #endif /* !XNU_KERNEL_PRIVATE */
1173 
1174 void *
1175 kalloc_type_impl_external(
1176 	kalloc_type_view_t  kt_view,
1177 	zalloc_flags_t      flags);
1178 
1179 void
1180 kfree_type_impl_external(
1181 	kalloc_type_view_t  kt_view,
1182 	void               *ptr __unsafe_indexable);
1183 
1184 extern void *
1185 OSObject_typed_operator_new(
1186 	kalloc_type_view_t  ktv,
1187 	vm_size_t           size);
1188 
1189 extern void
1190 OSObject_typed_operator_delete(
1191 	kalloc_type_view_t  ktv,
1192 	void               *mem __unsafe_indexable,
1193 	vm_size_t           size);
1194 
1195 #ifdef XNU_KERNEL_PRIVATE
1196 #pragma GCC visibility push(hidden)
1197 
1198 #define KALLOC_TYPE_SIZE_MASK  0xffffff
1199 #define KALLOC_TYPE_IDX_SHIFT  24
1200 #define KALLOC_TYPE_IDX_MASK   0xff
1201 
1202 static inline uint32_t
kalloc_type_get_size(uint32_t kt_size)1203 kalloc_type_get_size(uint32_t kt_size)
1204 {
1205 	return kt_size & KALLOC_TYPE_SIZE_MASK;
1206 }
1207 
1208 bool
1209 IOMallocType_from_vm(
1210 	kalloc_type_view_t ktv);
1211 
1212 /* Used by kern_os_* and operator new */
1213 KALLOC_HEAP_DECLARE(KERN_OS_MALLOC);
1214 
1215 extern void
1216 kheap_startup_init(
1217 	kalloc_heap_t heap);
1218 
1219 extern struct kalloc_result
1220 kalloc_ext(
1221 	void                   *kheap_or_kt_view,
1222 	vm_size_t               size,
1223 	zalloc_flags_t          flags,
1224 	void                   *site);
1225 
1226 __attribute__((malloc, alloc_size(2)))
1227 static inline void *
__sized_by(size)1228 __sized_by(size)
1229 __kheap_alloc(
1230 	kalloc_heap_t           kheap,
1231 	vm_size_t               size,
1232 	zalloc_flags_t          flags,
1233 	void                   *site)
1234 {
1235 	struct kalloc_result kr;
1236 	__builtin_assume(!kt_is_var_view(kheap));
1237 	kr = kalloc_ext(kheap, size, flags, site);
1238 	return __unsafe_forge_bidi_indexable(void *, kr.addr, size);
1239 }
1240 
1241 extern struct kalloc_result
1242 krealloc_ext(
1243 	void                   *kheap_or_kt_view,
1244 	void                   *addr __unsafe_indexable,
1245 	vm_size_t               old_size,
1246 	vm_size_t               new_size,
1247 	zalloc_flags_t          flags,
1248 	void                   *site);
1249 
1250 __attribute__((malloc, alloc_size(4)))
1251 static inline void *
__sized_by(new_size)1252 __sized_by(new_size)
1253 __kheap_realloc(
1254 	kalloc_heap_t           kheap,
1255 	void                   *addr __unsafe_indexable,
1256 	vm_size_t               old_size,
1257 	vm_size_t               new_size,
1258 	zalloc_flags_t          flags,
1259 	void                   *site)
1260 {
1261 	struct kalloc_result kr;
1262 	__builtin_assume(!kt_is_var_view(kheap));
1263 	kr = krealloc_ext(kheap, addr, old_size, new_size, flags, site);
1264 	return __unsafe_forge_bidi_indexable(void *, kr.addr, new_size);
1265 }
1266 
1267 __attribute__((malloc, alloc_size(4)))
1268 static inline void *
__sized_by(new_size)1269 __sized_by(new_size)
1270 __krealloc_type(
1271 	kalloc_type_var_view_t  kt_view,
1272 	void                   *addr __unsafe_indexable,
1273 	vm_size_t               old_size,
1274 	vm_size_t               new_size,
1275 	zalloc_flags_t          flags,
1276 	void                   *site)
1277 {
1278 	struct kalloc_result kr;
1279 	kr = krealloc_ext(kt_mangle_var_view(kt_view), addr,
1280 	    old_size, new_size, flags, site);
1281 	return __unsafe_forge_bidi_indexable(void *, kr.addr, new_size);
1282 }
1283 
1284 extern void
1285 kfree_addr_ext(
1286 	kalloc_heap_t           kheap,
1287 	void                   *addr __unsafe_indexable);
1288 
1289 extern void
1290 kfree_ext(
1291 	void                   *kheap_or_kt_view,
1292 	void                   *addr __unsafe_indexable,
1293 	vm_size_t               size);
1294 
1295 extern zone_t
1296 kalloc_heap_zone_for_size(
1297 	kalloc_heap_t         heap,
1298 	vm_size_t             size);
1299 
1300 extern vm_size_t kalloc_large_max;
1301 SCALABLE_COUNTER_DECLARE(kalloc_large_count);
1302 SCALABLE_COUNTER_DECLARE(kalloc_large_total);
1303 
1304 extern void
1305 kern_os_typed_free(
1306 	kalloc_type_view_t    ktv,
1307 	void                 *addr __unsafe_indexable,
1308 	vm_size_t             esize);
1309 
1310 #pragma GCC visibility pop
1311 #endif  /* !XNU_KERNEL_PRIVATE */
1312 
1313 extern void
1314 kern_os_zfree(
1315 	zone_t        zone,
1316 	void         *addr __unsafe_indexable,
1317 	vm_size_t     size);
1318 
1319 __ASSUME_PTR_ABI_SINGLE_END __END_DECLS
1320 
1321 #endif  /* _KERN_KALLOC_H_ */
1322 
1323 #endif  /* KERNEL_PRIVATE */
1324