xref: /xnu-12377.1.9/osfmk/vm/vm_sanitize_internal.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /*
2  * Copyright (c) 2024 Apple 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 #ifndef _VM_SANITIZE_INTERNAL_H_
30 #define _VM_SANITIZE_INTERNAL_H_
31 
32 #include <mach/vm_types_unsafe.h>
33 #include <mach/error.h>
34 #include <stdbool.h>
35 #include <vm/vm_sanitize_telemetry.h>
36 
37 __BEGIN_DECLS
38 #pragma GCC visibility push(hidden)
39 
40 /*
41  * kern_return_t errors used internally by VM
42  */
43 
44 /*!
45  * @define VM_ERR_RETURN_NOW
46  * @abstract Communicate to a caller that they should
47  * return @c KERN_SUCCESS immediately after completing sanitization checks.
48  */
49 #define VM_ERR_RETURN_NOW (err_vm | err_sub(0) | 1)
50 
51 /*!
52  * @function vm_sanitize_get_kr
53  * @abstract When a VM sanitizer returns an error, use this to extract
54  * the real value that the sanitizers request that you return.
55  *
56  * @discussion errno-returning callers may need to transform this result further
57  *
58  * @param kr                error code set by the sanitizers
59  * @returns                 a (possibly different) error code
60  */
61 static inline
62 kern_return_t
vm_sanitize_get_kr(kern_return_t kr)63 vm_sanitize_get_kr(kern_return_t kr)
64 {
65 	if (kr == VM_ERR_RETURN_NOW) {
66 		return KERN_SUCCESS;
67 	}
68 	return kr;
69 }
70 
71 /*!
72  * @enum vm_sanitize_caller_id_t
73  *
74  * @brief
75  * IDs for callers of sanitization functions that have different
76  * set of return values.
77  */
78 __enum_closed_decl(vm_sanitize_caller_id_t, uint32_t, {
79 	VM_SANITIZE_CALLER_ID_NONE,
80 
81 	/* memory entry */
82 	VM_SANITIZE_CALLER_ID_MACH_MAKE_MEMORY_ENTRY,
83 	VM_SANITIZE_CALLER_ID_MACH_MEMORY_ENTRY_PAGE_OP,
84 	VM_SANITIZE_CALLER_ID_MACH_MEMORY_ENTRY_RANGE_OP,
85 	VM_SANITIZE_CALLER_ID_MACH_MEMORY_ENTRY_MAP_SIZE,
86 	VM_SANITIZE_CALLER_ID_MACH_MEMORY_OBJECT_MEMORY_ENTRY,
87 
88 	/* alloc/dealloc */
89 	VM_SANITIZE_CALLER_ID_VM_ALLOCATE_FIXED,
90 	VM_SANITIZE_CALLER_ID_VM_ALLOCATE_ANYWHERE,
91 	VM_SANITIZE_CALLER_ID_VM_DEALLOCATE,
92 	VM_SANITIZE_CALLER_ID_MUNMAP,
93 
94 	/* map/remap */
95 	VM_SANITIZE_CALLER_ID_VM_MAP_REMAP,
96 	VM_SANITIZE_CALLER_ID_MMAP,
97 	VM_SANITIZE_CALLER_ID_MREMAP_ENCRYPTED,
98 	VM_SANITIZE_CALLER_ID_MAP_WITH_LINKING_NP,
99 	VM_SANITIZE_CALLER_ID_ENTER_MEM_OBJ,
100 	VM_SANITIZE_CALLER_ID_ENTER_MEM_OBJ_CTL,
101 
102 	/* wire/unwire */
103 	VM_SANITIZE_CALLER_ID_VM_WIRE_USER,
104 	VM_SANITIZE_CALLER_ID_VM_UNWIRE_USER,
105 	VM_SANITIZE_CALLER_ID_VM_MAP_WIRE,
106 	VM_SANITIZE_CALLER_ID_VM_MAP_UNWIRE,
107 	VM_SANITIZE_CALLER_ID_VSLOCK,
108 	VM_SANITIZE_CALLER_ID_VSUNLOCK,
109 
110 	/* copyin/copyout */
111 	VM_SANITIZE_CALLER_ID_VM_MAP_COPY_OVERWRITE,
112 	VM_SANITIZE_CALLER_ID_VM_MAP_COPYIN,
113 	VM_SANITIZE_CALLER_ID_VM_MAP_READ_USER,
114 	VM_SANITIZE_CALLER_ID_VM_MAP_WRITE_USER,
115 
116 	/* inherit */
117 	VM_SANITIZE_CALLER_ID_VM_MAP_INHERIT,
118 	VM_SANITIZE_CALLER_ID_MINHERIT,
119 
120 	/* protect */
121 	VM_SANITIZE_CALLER_ID_VM_MAP_PROTECT,
122 	VM_SANITIZE_CALLER_ID_MPROTECT,
123 	VM_SANITIZE_CALLER_ID_USERACC,
124 
125 	/* behavior */
126 	VM_SANITIZE_CALLER_ID_VM_BEHAVIOR_SET,
127 	VM_SANITIZE_CALLER_ID_MADVISE,
128 
129 	/* msync */
130 	VM_SANITIZE_CALLER_ID_VM_MAP_MSYNC,
131 	VM_SANITIZE_CALLER_ID_MSYNC,
132 
133 	/* machine attribute */
134 	VM_SANITIZE_CALLER_ID_VM_MAP_MACHINE_ATTRIBUTE,
135 
136 	/* page info */
137 	VM_SANITIZE_CALLER_ID_VM_MAP_PAGE_RANGE_INFO,
138 	VM_SANITIZE_CALLER_ID_VM_MAP_PAGE_RANGE_QUERY,
139 	VM_SANITIZE_CALLER_ID_MINCORE,
140 
141 	/* single */
142 	VM_SANITIZE_CALLER_ID_MACH_VM_DEFERRED_RECLAMATION_BUFFER_INIT,
143 	VM_SANITIZE_CALLER_ID_MACH_VM_RANGE_CREATE,
144 	VM_SANITIZE_CALLER_ID_SHARED_REGION_MAP_AND_SLIDE_2_NP,
145 
146 	/* test */
147 	VM_SANITIZE_CALLER_ID_TEST
148 });
149 
150 /*!
151  * @enum vm_sanitize_flags_t
152  *
153  * @brief
154  * Flags that influence the sanitization being performed.
155  *
156  * @const VM_SANITIZE_FLAGS_NONE
157  * Default value.
158  *
159  * @const VM_SANITIZE_FLAGS_CHECK_ALIGNED_START
160  * Checks that the start address is aligned to map page size.
161  *
162  * @const VM_SANITIZE_FLAGS_SIZE_ZERO_SUCCEEDS
163  * In sanitizers that have a @c size parameter, the sanitizer will ask
164  * the caller to return @c KERN_SUCCESS when @c size @c == @c 0.
165  *
166  * Exactly one of @c VM_SANITIZE_FLAGS_SIZE_ZERO_* must be passed to sanitizers
167  * that return a sanitized size.
168  *
169  * @const VM_SANITIZE_FLAGS_SIZE_ZERO_FAILS
170  * In sanitizers that have a @c size parameter, the sanitizer will ask
171  * the caller to return @c KERN_INVALID_ARGUMENT when @c size @c == @c 0.
172  *
173  * Exactly one of @c VM_SANITIZE_FLAGS_SIZE_ZERO_* must be passed to sanitizers
174  * that return a sanitized size.
175  *
176  * @const VM_SANITIZE_FLAGS_SIZE_ZERO_FALLTHROUGH
177  * In sanitizers that have a @c size parameter, the sanitizer will not ask
178  * the caller to return when @c size @c == @c 0, thus falling through into
179  * the caller's implementation.
180  *
181  * Exactly one of @c VM_SANITIZE_FLAGS_SIZE_ZERO_* must be passed to sanitizers
182  * that return a sanitized size.
183  *
184  * @const VM_SANITIZE_FLAGS_GET_UNALIGNED_VALUES
185  * Return unaligned start/end/size rather than realigned values.
186  *
187  * @const VM_SANITIZE_FLAGS_REALIGN_START
188  * Ignore the misaligned bits of the start address when sanitizing an address.
189  *
190  * @const VM_SANITIZE_FLAGS_CHECK_USER_MEM_MAP_FLAGS
191  * Reject non user allowed mem map flags for memory entry.
192  *
193  * @const VM_SANITIZE_FLAGS_CANONICALIZE
194  * Canonicalize address for KASAN_TBI
195  *
196  * @const VM_SANITIZE_FLAGS_CHECK_ALIGNED_SIZE
197  * Checks that the size is aligned to map page size.
198  *
199  * @const VM_SANITIZE_FLAGS_CHECK_ADDR_RANGE
200  * Checks that computing values within the range [start, end) does not overflow
201  * into bits above the supported VA bits for the system. These bits may be used
202  * by the kernel or hardware to store additional values.
203  */
204 
205 __options_closed_decl(vm_sanitize_flags_t, uint32_t, {
206 	VM_SANITIZE_FLAGS_NONE                     = 0x00000000,
207 	VM_SANITIZE_FLAGS_CHECK_ALIGNED_START      = 0x00000001,
208 	VM_SANITIZE_FLAGS_SIZE_ZERO_SUCCEEDS       = 0x00000002,
209 	VM_SANITIZE_FLAGS_SIZE_ZERO_FAILS          = 0x00000004,
210 	VM_SANITIZE_FLAGS_SIZE_ZERO_FALLTHROUGH    = 0x00000008,
211 	VM_SANITIZE_FLAGS_GET_UNALIGNED_VALUES     = 0x00000010,
212 	VM_SANITIZE_FLAGS_REALIGN_START            = 0x00000020,
213 	VM_SANITIZE_FLAGS_CHECK_USER_MEM_MAP_FLAGS = 0x00000040,
214 	VM_SANITIZE_FLAGS_CANONICALIZE             = 0x00000080,
215 	VM_SANITIZE_FLAGS_CHECK_ALIGNED_SIZE       = 0x00000100,
216 	VM_SANITIZE_FLAGS_CHECK_ADDR_RANGE         = 0x00000200,
217 });
218 
219 #define __vm_sanitize_bits_one_of(flags) \
220 	((flags) != 0 && ((flags) & ((flags) - 1)) == 0)
221 
222 #define __vm_sanitize_assert_one_of(arg, mask) \
223 	__attribute__((diagnose_if(!__vm_sanitize_bits_one_of((arg) & (mask)), \
224 	    "`" #arg "` must have one of these flags `" #mask "`", "error")))
225 
226 #define __vm_sanitize_require_size_zero_flag(arg) \
227 	__vm_sanitize_assert_one_of(arg,          \
228 	    VM_SANITIZE_FLAGS_SIZE_ZERO_SUCCEEDS | VM_SANITIZE_FLAGS_SIZE_ZERO_FAILS | VM_SANITIZE_FLAGS_SIZE_ZERO_FALLTHROUGH)
229 
230 /*
231  * Error compat rewrite result:
232  * compat_kr: the more-compatible return value
233  * should_rewrite: true if compat_kr should be returned
234  * should_telemeter: true if compat_kr should be telemetered
235  */
236 typedef struct {
237 	kern_return_t compat_kr;
238 	bool should_rewrite;
239 	bool should_telemeter;
240 } vm_sanitize_compat_rewrite_t;
241 
242 typedef vm_sanitize_compat_rewrite_t (*vm_sanitize_err_compat_addr_size_fn)(kern_return_t kr,
243     vm_address_t addr, vm_size_t size, vm_offset_t pgmask, vm_map_t map_or_null);
244 typedef vm_sanitize_compat_rewrite_t (*vm_sanitize_err_compat_cur_and_max_prots_fn)(kern_return_t kr,
245     vm_prot_t *cur_inout, vm_prot_t *max_inout, vm_prot_t extra_mask);
246 
247 typedef const struct vm_sanitize_caller {
248 	vm_sanitize_caller_id_t              vmsc_caller_id;
249 	const char                          *vmsc_caller_name;
250 	vm_sanitize_method_t                 vmsc_telemetry_id;
251 	enum vm_sanitize_subsys_error_codes  vmsc_ktriage_id;
252 
253 	vm_sanitize_err_compat_addr_size_fn    err_compat_addr_size;
254 	vm_sanitize_err_compat_cur_and_max_prots_fn err_compat_prot_cur_max;
255 } *vm_sanitize_caller_t;
256 
257 /*
258  * Macros to declare and define callers of sanitization functions
259  */
260 #define VM_SANITIZE_DECL_CALLER(name) \
261 	extern vm_sanitize_caller_t const VM_SANITIZE_CALLER_ ## name;
262 
263 #define VM_SANITIZE_DEFINE_CALLER(name, ... /* error compat functions */)       \
264 	static const struct vm_sanitize_caller vm_sanitize_caller_storage_ ## name = { \
265 	    .vmsc_caller_id = VM_SANITIZE_CALLER_ID_ ## name,        \
266 	    .vmsc_caller_name = #name,                       \
267 	    .vmsc_telemetry_id = VM_SANITIZE_METHOD_ ## name,     \
268 	    .vmsc_ktriage_id = KDBG_TRIAGE_VM_SANITIZE_ ## name,  \
269 	    __VA_ARGS__                                     \
270 	}; \
271 	vm_sanitize_caller_t const VM_SANITIZE_CALLER_ ## name = &vm_sanitize_caller_storage_ ## name
272 
273 /*
274  * Declaration of callers of VM sanitization functions
275  */
276 /* memory entry */
277 VM_SANITIZE_DECL_CALLER(MACH_MAKE_MEMORY_ENTRY);
278 VM_SANITIZE_DECL_CALLER(MACH_MEMORY_ENTRY_PAGE_OP);
279 VM_SANITIZE_DECL_CALLER(MACH_MEMORY_ENTRY_RANGE_OP);
280 VM_SANITIZE_DECL_CALLER(MACH_MEMORY_ENTRY_MAP_SIZE);
281 VM_SANITIZE_DECL_CALLER(MACH_MEMORY_OBJECT_MEMORY_ENTRY);
282 
283 /* alloc/dealloc */
284 VM_SANITIZE_DECL_CALLER(VM_ALLOCATE_FIXED);
285 VM_SANITIZE_DECL_CALLER(VM_ALLOCATE_ANYWHERE);
286 VM_SANITIZE_DECL_CALLER(VM_DEALLOCATE);
287 VM_SANITIZE_DECL_CALLER(MUNMAP);
288 
289 /* map/remap */
290 VM_SANITIZE_DECL_CALLER(VM_MAP_REMAP);
291 VM_SANITIZE_DECL_CALLER(MMAP);
292 VM_SANITIZE_DECL_CALLER(MREMAP_ENCRYPTED);
293 VM_SANITIZE_DECL_CALLER(MAP_WITH_LINKING_NP);
294 VM_SANITIZE_DECL_CALLER(ENTER_MEM_OBJ);
295 VM_SANITIZE_DECL_CALLER(ENTER_MEM_OBJ_CTL);
296 
297 /* wire/unwire */
298 VM_SANITIZE_DECL_CALLER(VM_WIRE_USER);
299 VM_SANITIZE_DECL_CALLER(VM_UNWIRE_USER);
300 VM_SANITIZE_DECL_CALLER(VM_MAP_WIRE);
301 VM_SANITIZE_DECL_CALLER(VM_MAP_UNWIRE);
302 VM_SANITIZE_DECL_CALLER(VSLOCK);
303 VM_SANITIZE_DECL_CALLER(VSUNLOCK);
304 
305 /* copyin/copyout */
306 VM_SANITIZE_DECL_CALLER(VM_MAP_COPY_OVERWRITE);
307 VM_SANITIZE_DECL_CALLER(VM_MAP_COPYIN);
308 VM_SANITIZE_DECL_CALLER(VM_MAP_READ_USER);
309 VM_SANITIZE_DECL_CALLER(VM_MAP_WRITE_USER);
310 
311 /* inherit */
312 VM_SANITIZE_DECL_CALLER(MACH_VM_INHERIT);
313 VM_SANITIZE_DECL_CALLER(VM_INHERIT);
314 VM_SANITIZE_DECL_CALLER(VM32_INHERIT);
315 VM_SANITIZE_DECL_CALLER(VM_MAP_INHERIT);
316 VM_SANITIZE_DECL_CALLER(MINHERIT);
317 
318 /* protect */
319 VM_SANITIZE_DECL_CALLER(MACH_VM_PROTECT);
320 VM_SANITIZE_DECL_CALLER(VM_PROTECT);
321 VM_SANITIZE_DECL_CALLER(VM32_PROTECT);
322 VM_SANITIZE_DECL_CALLER(VM_MAP_PROTECT);
323 VM_SANITIZE_DECL_CALLER(MPROTECT);
324 VM_SANITIZE_DECL_CALLER(USERACC);
325 
326 /* behavior */
327 VM_SANITIZE_DECL_CALLER(VM_BEHAVIOR_SET);
328 VM_SANITIZE_DECL_CALLER(MADVISE);
329 
330 /* msync */
331 VM_SANITIZE_DECL_CALLER(VM_MAP_MSYNC);
332 VM_SANITIZE_DECL_CALLER(MSYNC);
333 
334 /* machine attribute */
335 VM_SANITIZE_DECL_CALLER(VM_MAP_MACHINE_ATTRIBUTE);
336 
337 /* page info */
338 VM_SANITIZE_DECL_CALLER(VM_MAP_PAGE_RANGE_INFO);
339 VM_SANITIZE_DECL_CALLER(VM_MAP_PAGE_RANGE_QUERY);
340 VM_SANITIZE_DECL_CALLER(MINCORE);
341 
342 /* single */
343 VM_SANITIZE_DECL_CALLER(MACH_VM_DEFERRED_RECLAMATION_BUFFER_INIT);
344 VM_SANITIZE_DECL_CALLER(MACH_VM_RANGE_CREATE);
345 VM_SANITIZE_DECL_CALLER(SHARED_REGION_MAP_AND_SLIDE_2_NP);
346 
347 /* test */
348 VM_SANITIZE_DECL_CALLER(TEST);
349 
350 /*
351  * Macro that extracts the inner struct member from a wrapped type. Should be
352  * used in all cases, including validation functions, when accessing the
353  * inner struct member.
354  */
355 #define VM_SANITIZE_UNSAFE_UNWRAP(_val) (_val).UNSAFE
356 
357 /*
358  * Macro to check if unsafe value is a specific safe value
359  */
360 #define VM_SANITIZE_UNSAFE_IS_EQUAL(_var, _val) ((_var).UNSAFE == (_val))
361 
362 /*
363  * Macro to check if unsafe value is zero
364  */
365 #define VM_SANITIZE_UNSAFE_IS_ZERO(_var) VM_SANITIZE_UNSAFE_IS_EQUAL(_var, 0)
366 
367 /*
368  * returns whether a given unsafe value fits a given type
369  */
370 #define VM_SANITIZE_UNSAFE_FITS(_var, type_t) ({ \
371 	__auto_type __tmp = (_var).UNSAFE; \
372 	__tmp == (type_t)__tmp;            \
373 })
374 
375 /*
376  * Macro that sets a value of unsafe type to a value of safe type.
377  * This is safe to do because we are only forcing ourselves to perform
378  * checks on a value we already have direct access to.
379  */
380 #define VM_SANITIZE_UT_SET(_var, _val) ((_var).UNSAFE) = (_val)
381 
382 /*!
383  * @function vm_sanitize_wrap_addr
384  *
385  * @abstract
386  * Function that wraps unsanitized safe address into unsafe address
387  *
388  * @param val               safe address
389  * @returns                 unsafe address
390  */
391 __attribute__((always_inline, warn_unused_result))
392 vm_addr_struct_t vm_sanitize_wrap_addr(vm_address_t val);
393 
394 /*!
395  * @function vm_sanitize_wrap_addr_ref
396  *
397  * @abstract
398  * Function that wraps a safe address pointer,
399  * into unsafe address pointer.
400  *
401  * @param val               safe address ref
402  * @returns                 unsafe address reference
403  */
404 #define vm_sanitize_wrap_addr_ref(var)  _Generic(var, \
405 	mach_vm_address_t *: (vm_addr_struct_t *)(var), \
406 	vm_address_t *:      (vm_addr_struct_t *)(var), \
407 	default:             (var))
408 
409 /*!
410  * @function vm_sanitize_wrap_size
411  *
412  * @abstract
413  * Function that wraps unsanitized safe size into unsafe size
414  *
415  * @param val               safe size
416  * @returns                 unsafe size
417  */
418 __attribute__((always_inline, warn_unused_result))
419 vm_size_struct_t vm_sanitize_wrap_size(vm_size_t val);
420 
421 /*
422  * bsd doesn't use 32bit interfaces and the types aren't even defined for them,
423  * so we just expose this to MACH.
424  */
425 #ifdef MACH_KERNEL_PRIVATE
426 /*!
427  * @function vm32_sanitize_wrap_size
428  *
429  * @abstract
430  * Function that wraps unsanitized 32bit safe size into 32bit unsafe size
431  *
432  * @param val               safe size
433  * @returns                 unsafe size
434  */
435 __attribute__((always_inline, warn_unused_result))
436 vm32_size_struct_t vm32_sanitize_wrap_size(vm32_size_t val);
437 #endif /* MACH_KERNEL_PRIVATE */
438 
439 /*!
440  * @function vm_sanitize_wrap_prot
441  *
442  * @abstract
443  * Function that wraps unsanitized safe protection into unsafe protection
444  *
445  * @param val               safe protection
446  * @returns                 unsafe protection
447  */
448 __attribute__((always_inline, warn_unused_result))
449 vm_prot_ut vm_sanitize_wrap_prot(vm_prot_t val);
450 
451 /*!
452  * @function vm_sanitize_wrap_prot_ref
453  *
454  * @abstract
455  * Function that wraps a safe protection pointer into unsafe protection pointer.
456  *
457  * @param val               safe protection pointer
458  * @returns                 unsafe protection pointer
459  */
460 __attribute__((always_inline, warn_unused_result))
461 static inline vm_prot_ut *
vm_sanitize_wrap_prot_ref(vm_prot_t * val)462 vm_sanitize_wrap_prot_ref(vm_prot_t *val)
463 {
464 	return (vm_prot_ut *)val;
465 }
466 
467 /*!
468  * @function vm_sanitize_wrap_inherit
469  *
470  * @abstract
471  * Function that wraps unsanitized safe vm_inherit into unsafe vm_inherit
472  *
473  * @param val               safe vm_inherit
474  * @returns                 unsafe vm_inherit
475  */
476 __attribute__((always_inline, warn_unused_result))
477 vm_inherit_ut vm_sanitize_wrap_inherit(vm_inherit_t val);
478 
479 /*!
480  * @function vm_sanitize_wrap_behavior
481  *
482  * @abstract
483  * Function that wraps a safe vm_behavior into an unsafe vm_behavior
484  *
485  * @param val               safe vm_behavior
486  * @returns                 unsafe vm_behavior
487  */
488 __attribute__((always_inline, warn_unused_result))
489 vm_behavior_ut vm_sanitize_wrap_behavior(vm_behavior_t val);
490 
491 #ifdef  MACH_KERNEL_PRIVATE
492 
493 /*!
494  * @function vm_sanitize_expand_addr_to_64
495  *
496  * @abstract
497  * Function used by the vm32 functions to cast 32bit unsafe address
498  * to 64bit unsafe address
499  *
500  * @param val               32bit unsafe address
501  * @returns                 64bit unsafe address
502  */
503 __attribute__((always_inline, warn_unused_result))
504 vm_addr_struct_t vm_sanitize_expand_addr_to_64(vm32_address_ut val);
505 
506 /*!
507  * @function vm_sanitize_expand_size_to_64
508  *
509  * @abstract
510  * Function used by the vm32 functions to cast 32bit unsafe size
511  * to 64bit unsafe size
512  *
513  * @param val               32bit unsafe size
514  * @returns                 64bit unsafe size
515  */
516 __attribute__((always_inline, warn_unused_result))
517 vm_size_struct_t vm_sanitize_expand_size_to_64(vm32_size_ut val);
518 
519 /*!
520  * @function vm_sanitize_trunc_addr_to_32
521  *
522  * @abstract
523  * Function used by the vm32 functions to cast 64bit unsafe address
524  * to 32bit unsafe address
525  *
526  * @param val               64bit unsafe address
527  * @returns                 32bit unsafe address
528  */
529 __attribute__((always_inline, warn_unused_result))
530 vm32_address_ut vm_sanitize_trunc_addr_to_32(vm_addr_struct_t val);
531 
532 /*!
533  * @function vm_sanitize_trunc_size_to_32
534  *
535  * @abstract
536  * Function used by the vm32 functions to cast 64bit unsafe size
537  * to 32bit unsafe size
538  *
539  * @param val               64bit unsafe size
540  * @returns                 32bit unsafe size
541  */
542 __attribute__((always_inline, warn_unused_result))
543 vm32_size_ut vm_sanitize_trunc_size_to_32(vm_size_struct_t val);
544 
545 /*!
546  * @function vm_sanitize_add_overflow()
547  *
548  * @abstract
549  * Computes the sum of an address and a size checking for overflow,
550  * staying in the unsafe world.
551  *
552  * @param addr_u            unsafe address
553  * @param size_u            unsafe size
554  * @param addr_out_u        unsafe result
555  * @returns whether the operation overflowed
556  */
557 __attribute__((always_inline, warn_unused_result, overloadable))
558 bool vm_sanitize_add_overflow(
559 	vm32_address_ut         addr_u,
560 	vm32_size_ut            size_u,
561 	vm32_address_ut        *addr_out_u);
562 
563 #endif  /* MACH_KERNEL_PRIVATE */
564 
565 /*!
566  * @function vm_sanitize_add_overflow()
567  *
568  * @abstract
569  * Computes the sum of an address and a size checking for overflow,
570  * staying in the unsafe world.
571  *
572  * @param addr_u            unsafe address
573  * @param size_u            unsafe size
574  * @param addr_out_u        unsafe result
575  * @returns whether the operation overflowed
576  */
577 __attribute__((always_inline, warn_unused_result, overloadable))
578 bool vm_sanitize_add_overflow(
579 	vm_addr_struct_t        addr_u,
580 	vm_size_struct_t        size_u,
581 	vm_addr_struct_t       *addr_out_u);
582 
583 /*!
584  * @function vm_sanitize_add_overflow()
585  *
586  * @abstract
587  * Computes the sum of two sizes checking for overflow,
588  * staying in the unsafe world.
589  *
590  * @param size1_u           unsafe size 1
591  * @param size2_u           unsafe size 2
592  * @param size_out_u        unsafe result
593  * @returns whether the operation overflowed
594  */
595 __attribute__((always_inline, warn_unused_result, overloadable))
596 bool vm_sanitize_add_overflow(
597 	vm_size_struct_t        size1_u,
598 	vm_size_struct_t        size2_u,
599 	vm_size_struct_t       *size_out_u);
600 
601 /*!
602  * @function vm_sanitize_compute_ut_end
603  *
604  * @abstract
605  * Computes and returns unsafe end from unsafe start and size
606  *
607  * @param addr_u            unsafe start
608  * @param size_u            unsafe size
609  * @returns                 unsafe end
610  */
611 __attribute__((always_inline, warn_unused_result))
612 vm_addr_struct_t vm_sanitize_compute_ut_end(
613 	vm_addr_struct_t        addr_u,
614 	vm_size_struct_t        size_u);
615 
616 /*!
617  * @function vm_sanitize_compute_ut_size
618  *
619  * @abstract
620  * Computes and returns unsafe size from unsafe start and end
621  *
622  * @param addr_u            unsafe start
623  * @param end_u             unsafe end
624  * @returns                 unsafe size
625  */
626 __attribute__((always_inline, warn_unused_result))
627 vm_size_struct_t vm_sanitize_compute_ut_size(
628 	vm_addr_struct_t        addr_u,
629 	vm_addr_struct_t        end_u);
630 
631 /*!
632  * @function vm_sanitize_addr
633  *
634  * @abstract
635  * Sanitization function that takes unsafe address, and returns a truncated
636  * address.
637  *
638  * @param map               map the address belongs to
639  * @param addr_u            unsafe address to sanitize
640  * @returns                 a sanitized address
641  */
642 __attribute__((always_inline, warn_unused_result))
643 mach_vm_address_t vm_sanitize_addr(
644 	vm_map_t                map,
645 	vm_addr_struct_t        addr_u);
646 
647 /*!
648  * @function vm_sanitize_offset_in_page
649  *
650  * @abstract
651  * Sanitization function that takes unsafe address,
652  * and returns the offset in the page for this address.
653  *
654  * @param mask              page mask to use
655  * @param addr_u            unsafe address to sanitize
656  * @returns                 a sanitized offset in page
657  */
658 __attribute__((always_inline, warn_unused_result))
659 mach_vm_offset_t vm_sanitize_offset_in_page(
660 	vm_map_offset_t         mask,
661 	vm_addr_struct_t        addr_u);
662 
663 /*
664  * @function vm_sanitize_offset_in_page
665  *
666  * @abstract
667  * Sanitization function that takes unsafe address,
668  * and returns the offset in the page for this address.
669  *
670  * @param map               map the address belongs to
671  * @param addr_u            unsafe address to sanitize
672  * @returns                 a sanitized offset in page
673  */
674 __attribute__((always_inline, warn_unused_result, overloadable))
675 static inline mach_vm_offset_t
vm_sanitize_offset_in_page(vm_map_t map,vm_addr_struct_t addr_u)676 vm_sanitize_offset_in_page(
677 	vm_map_t                map,
678 	vm_addr_struct_t        addr_u)
679 {
680 	return vm_sanitize_offset_in_page(vm_map_page_mask(map), addr_u);
681 }
682 
683 /*!
684  * @function vm_sanitize_offset
685  *
686  * @abstract
687  * Sanitization function that takes unsafe offset and validates
688  * that it is within addr and end provided.
689  *
690  * @param offset_u          unsafe offset to sanitize
691  * @param vm_sanitize_caller        caller of the sanitization function
692  * @param addr              sanitized start address
693  * @param end               sanitized end address
694  * @param offset            sanitized offset
695  * @returns                 return code indicating success/failure of sanitization
696  */
697 __attribute__((always_inline, warn_unused_result))
698 kern_return_t vm_sanitize_offset(
699 	vm_addr_struct_t        offset_u,
700 	vm_sanitize_caller_t    vm_sanitize_caller,
701 	vm_map_address_t        addr,
702 	vm_map_address_t        end,
703 	vm_map_offset_t        *offset);
704 
705 /*!
706  * @function vm_sanitize_mask
707  *
708  * @abstract
709  * Sanitization function that takes unsafe mask and sanitizes it.
710  *
711  * @param mask_u            unsafe mask to sanitize
712  * @param vm_sanitize_caller        caller of the sanitization function
713  * @param mask              sanitized mask
714  * @returns                 return code indicating success/failure of sanitization
715  */
716 __attribute__((always_inline, warn_unused_result))
717 kern_return_t vm_sanitize_mask(
718 	vm_addr_struct_t        mask_u,
719 	vm_sanitize_caller_t    vm_sanitize_caller,
720 	vm_map_offset_t        *mask);
721 
722 /*!
723  * @function vm_sanitize_object_size
724  *
725  * @abstract
726  * Sanitization function that takes unsafe VM object size and safely rounds it
727  * up wrt a VM object.
728  *
729  * @param size_u            unsafe size to sanitize
730  * @param vm_sanitize_caller        caller of the sanitization function
731  * @param flags             flags that influence sanitization performed
732  * @param size              sanitized object size
733  * @returns                 return code indicating success/failure of sanitization
734  */
735 __attribute__((always_inline, warn_unused_result))
736 kern_return_t vm_sanitize_object_size(
737 	vm_size_struct_t        size_u,
738 	vm_sanitize_caller_t    vm_sanitize_caller,
739 	vm_sanitize_flags_t     flags,
740 	vm_object_offset_t     *size)
741 __vm_sanitize_require_size_zero_flag(flags);
742 
743 /*!
744  * @function vm_sanitize_size
745  *
746  * @abstract
747  * Sanitization function that takes unsafe size and safely rounds it up.
748  *
749  * @param offset_u          an offset/address which marks the beginning of the
750  *                          memory region of size @c size_u. Overflow checks
751  *                          will be performed on @c size_u+offset_u, and the
752  *                          low bits of @c offset_u may influence the rounding
753  *                          of @c size_u to ensure the returned size covers all
754  *                          pages that intersect with the region that starts at
755  *                          @c offset_u and has size @c size_u.
756  * @param size_u            unsafe size to sanitize
757  * @param vm_sanitize_caller        caller of the sanitization function
758  * @param map               map the address belongs to
759  * @param flags             flags that influence sanitization performed
760  * @param size              sanitized size
761  * @returns                 return code indicating success/failure of sanitization
762  */
763 __attribute__((always_inline, warn_unused_result))
764 kern_return_t vm_sanitize_size(
765 	vm_addr_struct_t        offset_u,
766 	vm_size_struct_t        size_u,
767 	vm_sanitize_caller_t    vm_sanitize_caller,
768 	vm_map_t                map,
769 	vm_sanitize_flags_t     flags,
770 	mach_vm_size_t         *size)
771 __vm_sanitize_require_size_zero_flag(flags);
772 
773 /*!
774  * @function vm_sanitize_addr_size
775  *
776  * @abstract
777  * Sanitization function that takes unsafe address and size and returns
778  * sanitized start, end and size via out parameters.
779  *
780  * @param addr_u            unsafe address to sanitize
781  * @param size_u            unsafe size to sanitize
782  * @param vm_sanitize_caller        caller of the sanitization function
783  * @param mask              page mask to use
784  * @param map_or_null       optional map, used for error compat for some callers
785  * @param flags             flags that influence sanitization performed
786  * @param addr              sanitized start
787  * @param end               sanitized end
788  * @param size              sanitized size
789  * @returns                 return code indicating success/failure of sanitization
790  */
791 __attribute__((always_inline, warn_unused_result))
792 kern_return_t vm_sanitize_addr_size(
793 	vm_addr_struct_t        addr_u,
794 	vm_size_struct_t        size_u,
795 	vm_sanitize_caller_t    vm_sanitize_caller,
796 	mach_vm_offset_t        mask,
797 	vm_map_t                map_or_null,
798 	vm_sanitize_flags_t     flags,
799 	vm_map_offset_t        *addr,
800 	vm_map_offset_t        *end,
801 	vm_map_size_t          *size)
802 __vm_sanitize_require_size_zero_flag(flags);
803 
804 /*!
805  * @function vm_sanitize_addr_size
806  *
807  * @abstract
808  * Sanitization function that takes unsafe address and size and returns
809  * sanitized start, end and size via out parameters.
810  *
811  * @param addr_u            unsafe address to sanitize
812  * @param size_u            unsafe size to sanitize
813  * @param vm_sanitize_caller        caller of the sanitization function
814  * @param mask              page mask to use
815  * @param flags             flags that influence sanitization performed
816  * @param addr              sanitized start
817  * @param end               sanitized end
818  * @param size              sanitized size
819  * @returns                 return code indicating success/failure of sanitization
820  */
821 __attribute__((always_inline, warn_unused_result, overloadable))
822 static inline kern_return_t
vm_sanitize_addr_size(vm_addr_struct_t addr_u,vm_size_struct_t size_u,vm_sanitize_caller_t vm_sanitize_caller,mach_vm_offset_t mask,vm_sanitize_flags_t flags,vm_map_offset_t * addr,vm_map_offset_t * end,vm_map_size_t * size)823 vm_sanitize_addr_size(
824 	vm_addr_struct_t        addr_u,
825 	vm_size_struct_t        size_u,
826 	vm_sanitize_caller_t    vm_sanitize_caller,
827 	mach_vm_offset_t        mask,
828 	vm_sanitize_flags_t     flags,
829 	vm_map_offset_t        *addr,
830 	vm_map_offset_t        *end,
831 	vm_map_size_t          *size)
832 __vm_sanitize_require_size_zero_flag(flags)
833 {
834 	return vm_sanitize_addr_size(addr_u, size_u, vm_sanitize_caller, mask,
835 	           VM_MAP_NULL, flags, addr, end, size);
836 }
837 
838 
839 /*!
840  * @function vm_sanitize_addr_size
841  *
842  * @abstract
843  * Sanitization function that takes unsafe address and size and returns
844  * sanitized start, end and size via out parameters.
845  *
846  * @param addr_u            unsafe address to sanitize
847  * @param size_u            unsafe size to sanitize
848  * @param vm_sanitize_caller        caller of the sanitization function
849  * @param map               map the address belongs to
850  * @param flags             flags that influence sanitization performed
851  * @param addr              sanitized start
852  * @param end               sanitized end
853  * @param size              sanitized size
854  * @returns                 return code indicating success/failure of sanitization
855  */
856 __attribute__((always_inline, warn_unused_result, overloadable))
857 static inline kern_return_t
vm_sanitize_addr_size(vm_addr_struct_t addr_u,vm_size_struct_t size_u,vm_sanitize_caller_t vm_sanitize_caller,vm_map_t map,vm_sanitize_flags_t flags,vm_map_offset_t * addr,vm_map_offset_t * end,vm_map_size_t * size)858 vm_sanitize_addr_size(
859 	vm_addr_struct_t        addr_u,
860 	vm_size_struct_t        size_u,
861 	vm_sanitize_caller_t    vm_sanitize_caller,
862 	vm_map_t                map,
863 	vm_sanitize_flags_t     flags,
864 	vm_map_offset_t        *addr,
865 	vm_map_offset_t        *end,
866 	vm_map_size_t          *size)
867 __vm_sanitize_require_size_zero_flag(flags)
868 {
869 	mach_vm_offset_t mask = vm_map_page_mask(map);
870 
871 	return vm_sanitize_addr_size(addr_u, size_u, vm_sanitize_caller, mask,
872 	           map, flags, addr, end, size);
873 }
874 
875 /*!
876  * @function vm_sanitize_addr_end
877  *
878  * @abstract
879  * Sanitization function that takes unsafe address and end and returns
880  * sanitized start, end and size via out parameters.
881  *
882  * @param addr_u            unsafe address to sanitize
883  * @param end_u             unsafe end to sanitize
884  * @param vm_sanitize_caller        caller of the sanitization function
885  * @param mask              page mask to use
886  * @param map_or_null       optional map, used for error compat for some callers
887  * @param flags             flags that influence sanitization performed
888  * @param start             sanitized start
889  * @param end               sanitized end
890  * @param size              sanitized size
891  * @returns                 return code indicating success/failure of sanitization
892  */
893 __attribute__((always_inline, warn_unused_result))
894 kern_return_t vm_sanitize_addr_end(
895 	vm_addr_struct_t        addr_u,
896 	vm_addr_struct_t        end_u,
897 	vm_sanitize_caller_t    vm_sanitize_caller,
898 	mach_vm_offset_t        mask,
899 	vm_map_t                map_or_null,
900 	vm_sanitize_flags_t     flags,
901 	vm_map_offset_t        *start,
902 	vm_map_offset_t        *end,
903 	vm_map_size_t          *size)
904 __vm_sanitize_require_size_zero_flag(flags);
905 
906 /*!
907  * @function vm_sanitize_addr_end
908  *
909  * @abstract
910  * Sanitization function that takes unsafe address and end and returns
911  * sanitized start, end and size via out parameters.
912  *
913  * @param addr_u            unsafe address to sanitize
914  * @param end_u             unsafe end to sanitize
915  * @param vm_sanitize_caller        caller of the sanitization function
916  * @param mask              page mask to use
917  * @param flags             flags that influence sanitization performed
918  * @param start             sanitized start
919  * @param end               sanitized end
920  * @param size              sanitized size
921  * @returns                 return code indicating success/failure of sanitization
922  */
923 __attribute__((always_inline, warn_unused_result, overloadable))
924 static inline kern_return_t
vm_sanitize_addr_end(vm_addr_struct_t addr_u,vm_addr_struct_t end_u,vm_sanitize_caller_t vm_sanitize_caller,mach_vm_offset_t mask,vm_sanitize_flags_t flags,vm_map_offset_t * start,vm_map_offset_t * end,vm_map_size_t * size)925 vm_sanitize_addr_end(
926 	vm_addr_struct_t        addr_u,
927 	vm_addr_struct_t        end_u,
928 	vm_sanitize_caller_t    vm_sanitize_caller,
929 	mach_vm_offset_t        mask,
930 	vm_sanitize_flags_t     flags,
931 	vm_map_offset_t        *start,
932 	vm_map_offset_t        *end,
933 	vm_map_size_t          *size)
934 __vm_sanitize_require_size_zero_flag(flags)
935 {
936 	return vm_sanitize_addr_end(addr_u, end_u, vm_sanitize_caller, mask,
937 	           VM_MAP_NULL, flags, start, end, size);
938 }
939 
940 /*!
941  * @function vm_sanitize_addr_end
942  *
943  * @abstract
944  * Sanitization function that takes unsafe address and end and returns
945  * sanitized start, end and size via out parameters.
946  *
947  * @param addr_u            unsafe address to sanitize
948  * @param end_u             unsafe end to sanitize
949  * @param vm_sanitize_caller        caller of the sanitization function
950  * @param map               map the address belongs to
951  * @param flags             flags that influence sanitization performed
952  * @param start             sanitized start
953  * @param end               sanitized end
954  * @param size              sanitized size
955  * @returns                 return code indicating success/failure of sanitization
956  */
957 __attribute__((always_inline, warn_unused_result, overloadable))
958 static inline kern_return_t
vm_sanitize_addr_end(vm_addr_struct_t addr_u,vm_addr_struct_t end_u,vm_sanitize_caller_t vm_sanitize_caller,vm_map_t map,vm_sanitize_flags_t flags,vm_map_offset_t * start,vm_map_offset_t * end,vm_map_size_t * size)959 vm_sanitize_addr_end(
960 	vm_addr_struct_t        addr_u,
961 	vm_addr_struct_t        end_u,
962 	vm_sanitize_caller_t    vm_sanitize_caller,
963 	vm_map_t                map,
964 	vm_sanitize_flags_t     flags,
965 	vm_map_offset_t        *start,
966 	vm_map_offset_t        *end,
967 	vm_map_size_t          *size)
968 __vm_sanitize_require_size_zero_flag(flags)
969 {
970 	mach_vm_offset_t mask = vm_map_page_mask(map);
971 
972 	return vm_sanitize_addr_end(addr_u, end_u, vm_sanitize_caller, mask,
973 	           map, flags, start, end, size);
974 }
975 
976 /*!
977  * @function vm_sanitize_prot
978  *
979  * @abstract
980  * Sanitization function that takes unsafe protections and sanitizes it.
981  *
982  * @param prot_u            unsafe protections
983  * @param vm_sanitize_caller        caller of the sanitization function
984  * @param map               map in which protections are going to be changed
985  * @param extra_mask        extra mask to allow on top of (VM_PROT_ALL | VM_PROT_ALLEXEC)
986  * @param prot              sanitized protections
987  * @returns                 return code indicating success/failure of sanitization
988  */
989 __attribute__((always_inline, warn_unused_result))
990 kern_return_t vm_sanitize_prot(
991 	vm_prot_ut              prot_u,
992 	vm_sanitize_caller_t    vm_sanitize_caller,
993 	vm_map_t                map,
994 	vm_prot_t               extra_mask,
995 	vm_prot_t              *prot);
996 
997 __attribute__((always_inline, warn_unused_result, overloadable))
998 static inline kern_return_t
vm_sanitize_prot(vm_prot_ut prot_u,vm_sanitize_caller_t vm_sanitize_caller,vm_map_t map,vm_prot_t * prot)999 vm_sanitize_prot(
1000 	vm_prot_ut              prot_u,
1001 	vm_sanitize_caller_t    vm_sanitize_caller,
1002 	vm_map_t                map,
1003 	vm_prot_t              *prot)
1004 {
1005 	return vm_sanitize_prot(prot_u, vm_sanitize_caller, map, VM_PROT_NONE, prot);
1006 }
1007 
1008 /*!
1009  * @function vm_sanitize_cur_and_max_prots
1010  *
1011  * @abstract
1012  * Sanitization function that takes a pair of unsafe current and max protections
1013  * and sanitizes it.
1014  *
1015  * @param cur_prot_u        unsafe current protections
1016  * @param max_prot_u        unsafe max protections
1017  * @param vm_sanitize_caller        caller of the sanitization function
1018  * @param map               map in which protections are going to be changed
1019  * @param extra_mask        extra mask to allow on top of (VM_PROT_ALL | VM_PROT_ALLEXEC)
1020  * @param cur_prot          sanitized current protections
1021  * @param max_prot          sanitized max protections
1022  * @returns                 return code indicating success/failure of sanitization
1023  */
1024 __attribute__((always_inline, warn_unused_result))
1025 kern_return_t vm_sanitize_cur_and_max_prots(
1026 	vm_prot_ut              cur_prot_u,
1027 	vm_prot_ut              max_prot_u,
1028 	vm_sanitize_caller_t    vm_sanitize_caller,
1029 	vm_map_t                map,
1030 	vm_prot_t               extra_mask,
1031 	vm_prot_t              *cur_prot,
1032 	vm_prot_t              *max_prot);
1033 
1034 __attribute__((always_inline, warn_unused_result, overloadable))
1035 static inline kern_return_t
vm_sanitize_cur_and_max_prots(vm_prot_ut cur_prot_u,vm_prot_ut max_prot_u,vm_sanitize_caller_t vm_sanitize_caller,vm_map_t map,vm_prot_t * cur_prot,vm_prot_t * max_prot)1036 vm_sanitize_cur_and_max_prots(
1037 	vm_prot_ut              cur_prot_u,
1038 	vm_prot_ut              max_prot_u,
1039 	vm_sanitize_caller_t    vm_sanitize_caller,
1040 	vm_map_t                map,
1041 	vm_prot_t              *cur_prot,
1042 	vm_prot_t              *max_prot)
1043 {
1044 	return vm_sanitize_cur_and_max_prots(cur_prot_u, max_prot_u, vm_sanitize_caller, map,
1045 	           VM_PROT_NONE, cur_prot, max_prot);
1046 }
1047 
1048 /*!
1049  * @function vm_sanitize_memory_entry_perm
1050  *
1051  * @abstract
1052  * Sanitization function that takes unsafe memory entry permissions and
1053  * sanitizes it.
1054  *
1055  * @param perm_u            unsafe permissions to sanitize
1056  * @param vm_sanitize_caller        caller of the sanitization function
1057  * @param flags             flags that influence sanitization performed
1058  * @param extra_mask        extra mask to allow on top of VM_PROT_ALL
1059  * @param perm              sanitized memory entry permissions
1060  * @returns                 return code indicating success/failure of sanitization
1061  */
1062 __attribute__((always_inline, warn_unused_result))
1063 kern_return_t vm_sanitize_memory_entry_perm(
1064 	vm_prot_ut              perm_u,
1065 	vm_sanitize_caller_t    vm_sanitize_caller,
1066 	vm_sanitize_flags_t     flags,
1067 	vm_prot_t               extra_mask,
1068 	vm_prot_t              *perm);
1069 
1070 /*!
1071  * @function vm_sanitize_prot_bsd
1072  *
1073  * @abstract
1074  * Sanitization function that takes unsafe protections and sanitizes it.
1075  *
1076  * @discussion
1077  * Use this function for BSD callers as it strips invalid protections instead
1078  * of returning an error.
1079  *
1080  * @param prot_u            unsafe protections
1081  * @param vm_sanitize_caller        caller of the sanitization function
1082  * @returns                 sanitized protections
1083  */
1084 __attribute__((always_inline, warn_unused_result))
1085 vm_prot_t vm_sanitize_prot_bsd(
1086 	vm_prot_ut              prot_u,
1087 	vm_sanitize_caller_t    vm_sanitize_caller);
1088 
1089 /*!
1090  * @function vm_sanitize_inherit
1091  *
1092  * @abstract
1093  * Sanitization function that takes unsafe vm_inherit and sanitizes it.
1094  *
1095  * @param inherit_u         unsafe vm_inherit
1096  * @param vm_sanitize_caller        caller of the sanitization function
1097  * @param inherit           sanitized vm_inherit
1098  * @returns                 return code indicating success/failure of sanitization
1099  */
1100 __attribute__((always_inline, warn_unused_result))
1101 kern_return_t vm_sanitize_inherit(
1102 	vm_inherit_ut           inherit_u,
1103 	vm_sanitize_caller_t    vm_sanitize_caller,
1104 	vm_inherit_t           *inherit);
1105 
1106 /*!
1107  * @function vm_sanitize_behavior
1108  *
1109  * @abstract
1110  * Sanitization function that takes an unsafe vm_behavior and sanitizes it.
1111  *
1112  * @param behavior_u         unsafe vm_behavior
1113  * @param vm_sanitize_caller caller of the sanitization function
1114  * @param behavior           sanitized vm_behavior
1115  * @returns                  return code indicating success/failure of sanitization
1116  */
1117 __attribute__((always_inline, warn_unused_result))
1118 kern_return_t vm_sanitize_behavior(
1119 	vm_behavior_ut           behavior_u,
1120 	vm_sanitize_caller_t    vm_sanitize_caller __unused,
1121 	vm_behavior_t           *behavior);
1122 
1123 #pragma GCC visibility pop
1124 __END_DECLS
1125 #endif /* _VM_SANITIZE_INTERNAL_H_ */
1126