This is xnu-11215.1.10. See this file in:
/*
 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. The rights granted to you under the License
 * may not be used to create, or enable the creation or redistribution of,
 * unlawful or unlicensed copies of an Apple operating system, or to
 * circumvent, violate, or enable the circumvention or violation of, any
 * terms of an Apple operating system software license agreement.
 *
 * Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 */

#ifndef _KASAN_H_
#define _KASAN_H_

#if KERNEL_PRIVATE

#include <mach/mach_types.h>
#include <sys/queue.h>

typedef uintptr_t uptr;

#if KASAN

#if KASAN_CLASSIC
#include "kasan-classic.h"
#elif KASAN_TBI
#include "kasan-tbi.h"
#else
#error "No kasan model specified"
#endif

/*
 * When mapping shadow memory, decide whether the created mapping can be later
 * updated/poisoned or whether it should just stay marked accessible for its
 * lifetime (and catch incorrect attempts at poisoning it).
 *
 * Consumed by: kasan_map_shadow()
 */
#define KASAN_CANNOT_POISON             true
#define KASAN_MAY_POISON                false

__BEGIN_DECLS

void kasan_map_shadow(vm_offset_t, vm_size_t, bool);

/* KASAN enable/disable and general initialization. */
void kasan_init(void);
void kasan_late_init(void);
void kasan_reserve_memory(void *);
void kasan_notify_stolen(vm_offset_t);

/*
 * Helper functions to run the necessary initialization and cleanup
 * at every KEXT load/unload.
 */
void kasan_load_kext(vm_offset_t, vm_size_t, const void *);
void kasan_unload_kext(vm_offset_t, vm_size_t);

/*
 * API for the kernel to communicate to KASAN that a new range needs to be
 * accounted for in the shadow table.
 */
void kasan_notify_address(vm_offset_t, vm_size_t);
void kasan_notify_address_nopoison(vm_offset_t, vm_size_t);

/*
 * Control the shadow table state for a given range.
 */
void kasan_poison(vm_offset_t, vm_size_t, vm_size_t, vm_size_t, uint8_t);
void kasan_unpoison(void *, vm_size_t);
void kasan_poison_range(vm_offset_t, vm_size_t, uint8_t);
void kasan_unpoison_stack(vm_offset_t, vm_size_t);
void kasan_unpoison_curstack(bool);
bool kasan_check_shadow(vm_address_t, vm_size_t, uint8_t);
void kasan_unpoison_cxx_array_cookie(void *);

/* Fakestack */
void kasan_fakestack_drop(thread_t); /* mark all fakestack entries for thread as unused */
void kasan_fakestack_gc(thread_t);   /* free and poison all unused fakestack objects for thread */
void kasan_fakestack_suspend(void);
void kasan_fakestack_resume(void);
void kasan_unpoison_fakestack(thread_t);

/* KDP support */
typedef int (*pmap_traverse_callback)(vm_map_offset_t, vm_map_offset_t, void *);
int kasan_traverse_mappings(pmap_traverse_callback, void *);
void kasan_kdp_disable(void);

/* Tests API */
struct kasan_test {
	int (* func)(struct kasan_test *);
	void (* cleanup)(struct kasan_test *);
	const char *name;
	int result;
	void *data;
	size_t datasz;
};
void __kasan_runtests(struct kasan_test *, int numtests);

#if XNU_KERNEL_PRIVATE
extern unsigned shadow_pages_total;

#if __arm64__
void kasan_notify_address_zero(vm_offset_t, vm_size_t);
#elif __x86_64__
extern void kasan_map_low_fixed_regions(void);
extern unsigned shadow_stolen_idx;
#endif /* __arm64__ */

#endif /* XNU_KERNEL_PRIVATE */

#if HIBERNATION
/*
 * hibernate_write_image() needs to know the current extent of the shadow table
 */
extern vm_offset_t shadow_pnext, shadow_ptop;
#endif /* HIBERNATION */

/* thread interface */
struct kasan_thread_data {
	LIST_HEAD(fakestack_header_list, fakestack_header) fakestack_head;
};
struct kasan_thread_data *kasan_get_thread_data(thread_t);
void kasan_init_thread(struct kasan_thread_data *);

/*
 * ASAN callbacks - inserted by the compiler
 */

extern int __asan_option_detect_stack_use_after_return;
extern const uintptr_t __asan_shadow_memory_dynamic_address;

#define KASAN_DECLARE_FOREACH_WIDTH(ret, func, ...) \
	ret func ## 1(__VA_ARGS__); \
	ret func ## 2(__VA_ARGS__); \
	ret func ## 4(__VA_ARGS__); \
	ret func ## 8(__VA_ARGS__); \
	ret func ## 16(__VA_ARGS__)

KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_load, uptr);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_store, uptr);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_store, uptr);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_exp_load, uptr, int32_t);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_exp_store, uptr, int32_t);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_exp_load, uptr, int32_t);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_exp_store, uptr, int32_t);
KASAN_DECLARE_FOREACH_WIDTH(void, __asan_load, uptr);

void __asan_report_load_n(uptr, unsigned long);
void __asan_report_store_n(uptr, unsigned long);
void __asan_handle_no_return(void);
uptr __asan_stack_malloc_0(size_t);
uptr __asan_stack_malloc_1(size_t);
uptr __asan_stack_malloc_2(size_t);
uptr __asan_stack_malloc_3(size_t);
uptr __asan_stack_malloc_4(size_t);
uptr __asan_stack_malloc_5(size_t);
uptr __asan_stack_malloc_6(size_t);
uptr __asan_stack_malloc_7(size_t);
uptr __asan_stack_malloc_8(size_t);
uptr __asan_stack_malloc_9(size_t);
uptr __asan_stack_malloc_10(size_t);
void __asan_stack_free_0(uptr, size_t);
void __asan_stack_free_1(uptr, size_t);
void __asan_stack_free_2(uptr, size_t);
void __asan_stack_free_3(uptr, size_t);
void __asan_stack_free_4(uptr, size_t);
void __asan_stack_free_5(uptr, size_t);
void __asan_stack_free_6(uptr, size_t);
void __asan_stack_free_7(uptr, size_t);
void __asan_stack_free_8(uptr, size_t);
void __asan_stack_free_9(uptr, size_t);
void __asan_stack_free_10(uptr, size_t);
void __asan_poison_cxx_array_cookie(uptr);
uptr __asan_load_cxx_array_cookie(uptr *);
void __asan_poison_stack_memory(uptr, size_t);
void __asan_unpoison_stack_memory(uptr, size_t);
void __asan_alloca_poison(uptr, uptr);
void __asan_allocas_unpoison(uptr, uptr);
void __asan_loadN(uptr, size_t);
void __asan_storeN(uptr, size_t);
void __sanitizer_ptr_sub(uptr, uptr);
void __sanitizer_ptr_cmp(uptr, uptr);
void __sanitizer_annotate_contiguous_container(const void *, const void *,
    const void *, const void *n);

void __asan_exp_loadN(uptr, size_t, int32_t);
void __asan_exp_storeN(uptr, size_t, int32_t);
void __asan_report_exp_load_n(uptr, unsigned long, int32_t);
void __asan_report_exp_store_n(uptr, unsigned long, int32_t);

void __asan_set_shadow_00(uptr, size_t);
void __asan_set_shadow_f1(uptr, size_t);
void __asan_set_shadow_f2(uptr, size_t);
void __asan_set_shadow_f3(uptr, size_t);
void __asan_set_shadow_f5(uptr, size_t);
void __asan_set_shadow_f8(uptr, size_t);

void __asan_init_v5(void);
void __asan_register_globals(uptr, uptr);
void __asan_unregister_globals(uptr, uptr);
void __asan_register_elf_globals(uptr, uptr, uptr);
void __asan_unregister_elf_globals(uptr, uptr, uptr);

void __asan_before_dynamic_init(uptr);
void __asan_after_dynamic_init(void);
void __asan_init(void);
void __asan_unregister_image_globals(uptr);
void __asan_register_image_globals(uptr);

void __hwasan_tag_memory(uintptr_t, unsigned char, uintptr_t);
unsigned char __hwasan_generate_tag(void);

__END_DECLS

#endif /* KASAN */

#if __has_feature(address_sanitizer)
#define NOKASAN __attribute__ ((no_sanitize_address))
#elif __has_feature(hwaddress_sanitizer)
#define NOKASAN __attribute__((no_sanitize("kernel-hwaddress")))
#else /* address_sanitizer || hwaddress_sanitizer */
#define NOKASAN
#endif

/*
 * KASAN provides a description of each global variable in the
 * __DATA.__asan_globals section. This description is walked for xnu at boot
 * and at each KEXT load/unload operation, to allow the KASAN implementation
 * to perform the necessary redzoning around each variable.
 *
 * Consumed in OSKext.cpp, so must stay outside KASAN-specific defines.
 */
#define KASAN_GLOBAL_SEGNAME  "__DATA"
#define KASAN_GLOBAL_SECTNAME "__asan_globals"

#endif /* KERNEL_PRIVATE */
#endif /* _KASAN_H_ */