xref: /xnu-12377.41.6/tests/unit/mocks/mock_misc.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 /*
2  * Copyright (c) 2000-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 #include "mock_misc.h"
30 #include "std_safe.h"
31 #include "unit_test_utils.h"
32 #include "dt_proxy.h"
33 
34 #include "fibers/random.h"
35 
36 #include <kern/btlog.h>
37 #include <mach/vm_types.h>
38 #include <vm/vm_sanitize_telemetry.h>
39 
40 // This initialized the darwintest asserts proxies in the mocks .dylib
41 struct dt_proxy_callbacks *dt_proxy = NULL;
42 void
set_dt_proxy_mock(struct dt_proxy_callbacks * p)43 set_dt_proxy_mock(struct dt_proxy_callbacks *p)
44 {
45 	dt_proxy = p;
46 }
47 struct dt_proxy_callbacks *
get_dt_proxy_mock(void)48 get_dt_proxy_mock(void)
49 {
50 	return dt_proxy;
51 }
52 
53 
54 // for cpu_data_startup_init
55 T_MOCK(unsigned int,
56 ml_get_cpu_count, (void))
57 {
58 	return 1;
59 }
60 
61 T_MOCK(vm_offset_t,
62 min_valid_stack_address, (void))
63 {
64 	return 0;
65 }
66 
67 T_MOCK(vm_offset_t,
68 max_valid_stack_address, (void))
69 {
70 	return 0;
71 }
72 
73 T_MOCK(u_int32_t,
74 RandomULong, (void))
75 {
76 	return (u_int32_t)random_next();
77 }
78 
79 T_MOCK(uint64_t,
80 early_random, (void))
81 {
82 	return random_next();
83 }
84 
85 // needed because in-kernel impl for some reason got to libcorecrypt dyld
86 T_MOCK(void,
87 read_erandom, (void * buffer, unsigned int numBytes))
88 {
89 	unsigned char *cbuf = (unsigned char *)buffer;
90 	for (int i = 0; i < numBytes; ++i) {
91 		cbuf[i] = (unsigned char)(random_next() % 0xFF);
92 	}
93 }
94 
95 T_MOCK(void,
96 read_random, (void * buffer, unsigned int numbytes))
97 {
98 	read_erandom(buffer, numbytes);
99 }
100 
101 T_MOCK(uint32_t,
102 PE_get_random_seed, (unsigned char *dst_random_seed, uint32_t request_size))
103 {
104 	for (uint32_t i = 0; i < request_size; i++, dst_random_seed++) {
105 		*dst_random_seed = 0;
106 	}
107 	return request_size;
108 }
109 
110 T_MOCK(bool,
111 ml_unsafe_kernel_text, (void))
112 {
113 	return true;
114 }
115 
116 
117 T_MOCK(__attribute__((noinline, not_tail_called)) void,
118 os_log_with_args, (void* oslog, uint8_t type, const char *fmt, va_list args, void *addr))
119 {
120 	char buf[PRINT_BUF_SIZE];
121 	int printed = vsnprintf(buf, PRINT_BUF_SIZE, fmt, args);
122 	if (printed > PRINT_BUF_SIZE - 1) {
123 		printed = PRINT_BUF_SIZE - 1;
124 	}
125 #if 0  // this can be switched on if we want pre-main logs
126 	buf[printed] = '\n';
127 	write(STDOUT_FILENO, buf, printed);
128 #else
129 	PT_LOG(buf);
130 #endif
131 }
132 
133 
134 // The panic() mock works in conjunction with T_ASSERT_PANIC()
135 // XNU code that panics doesn't expect panic() to return so any function that calls panic() doesn't bother
136 // to return gracefully to its caller with an error.
137 // In a unit-test we still want to call a function that is expected to panic, and then be able to run code after it.
138 // T_ASSERT_PANIC creates a setjmp() point before the call that is expected to panic.
139 // Once the panic callback panic_trap_to_debugger() is called it does a longjmp() to that jump point.
140 // This has a similar effect as C++ exceptions, except that any memory allocations performed by the code
141 // prior to the panic are going to be leaked.
142 
143 T_MOCK(void,
144 panic_trap_to_debugger, (const char *panic_format_str, va_list * panic_args,
145 unsigned int reason, void *ctx, uint64_t panic_options_mask, void *panic_data,
146 unsigned long panic_caller, const char *panic_initiator))
147 {
148 	char buf[PRINT_BUF_SIZE];
149 	vsnprintf(buf, PRINT_BUF_SIZE, panic_format_str, *panic_args);
150 	PT_LOG_OR_RAW_FMTSTR("panic! %s", buf);
151 	ut_check_expected_panic(buf); // may not return
152 	PT_FAIL("Panic was unexpected, exiting");
153 	abort();
154 }
155 
156 T_MOCK(void,
157 vm_sanitize_send_telemetry, (
158 	vm_sanitize_method_t method,
159 	vm_sanitize_checker_t checker,
160 	vm_sanitize_checker_count_t checker_count,
161 	enum vm_sanitize_subsys_error_codes ktriage_code,
162 	uint64_t arg1,
163 	uint64_t arg2,
164 	uint64_t arg3,
165 	uint64_t arg4,
166 	uint64_t future_ret,
167 	uint64_t past_ret))
168 {
169 }
170 
171 #if (DEBUG || DEVELOPMENT)
172 
173 T_MOCK(vm_size_t,
174 zone_element_info, (
175 	void *addr,
176 	vm_tag_t * ptag))
177 {
178 	return 0;
179 }
180 
181 #endif // DEBUG || DEVELOPMENT
182 
183 // added for setup_nested_submap()
184 T_MOCK(kern_return_t,
185 csm_setup_nested_address_space, (
186 	pmap_t pmap,
187 	const vm_address_t region_addr,
188 	const vm_size_t region_size))
189 {
190 	return KERN_SUCCESS;
191 }
192 
193 T_MOCK(btref_t,
194 btref_get, (
195 	void *fp,
196 	btref_get_flags_t flags))
197 {
198 	return 0;
199 }
200 
201 #if (DEBUG || DEVELOPMENT)
202 // these are used for testing the mocking framework, xnu has them only in development || debug
203 T_MOCK_DYNAMIC(size_t, kernel_func1, (int a, char b), (a, b), { return 0; });
204 T_MOCK_DYNAMIC(size_t, kernel_func2, (int a, char b), (a, b), { return 0; });
205 T_MOCK_DYNAMIC(size_t, kernel_func3, (int a, char b), (a, b), { return 0; });
206 T_MOCK_DYNAMIC(size_t, kernel_func4, (int a, char b), (a, b), { return 0; });
207 T_MOCK_DYNAMIC(size_t, kernel_func5, (int a, char b), (a, b), { return kernel_func5(a, b); });
208 T_MOCK_DYNAMIC(void, kernel_func6, (int a, char b), (a, b), { kernel_func6(a, b); });
209 T_MOCK_DYNAMIC(size_t, kernel_func7, (int a, char b), (a, b));
210 T_MOCK_DYNAMIC(void, kernel_func8, (int a, char b), (a, b));
211 #endif // DEBUG || DEVELOPMENT
212