]> git.saurik.com Git - apple/xnu.git/blame - tests/task_inspect.c
xnu-6153.81.5.tar.gz
[apple/xnu.git] / tests / task_inspect.c
CommitLineData
5ba3f43e
A
1#ifdef T_NAMESPACE
2#undef T_NAMESPACE
3#endif
4
813fb2f6
A
5#include <darwintest.h>
6
7#include <mach/host_priv.h>
8#include <mach/mach.h>
9#include <mach/mach_types.h>
10#include <mach/mach_vm.h>
11#include <mach/processor_set.h>
12#include <mach/task.h>
13#include <sys/sysctl.h>
14#include <unistd.h>
15
cb323159
A
16T_GLOBAL_META(T_META_NAMESPACE("xnu.ipc"),
17 T_META_RUN_CONCURRENTLY(true));
813fb2f6
A
18
19/*
20 * Attempt to inspect kernel_task using a task_inspect_t. Interact with the
21 * kernel in the same way top(1) and lsmp(1) do.
22 */
23
24static void
25check_secure_kernel(void)
26{
27 int secure_kern = 0;
28 size_t secure_kern_size = sizeof(secure_kern);
29
30 T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.secure_kernel", &secure_kern,
0a7de745 31 &secure_kern_size, NULL, 0), NULL);
813fb2f6
A
32
33 if (secure_kern) {
34 T_SKIP("secure kernel: processor_set_tasks will not return kernel_task");
35 }
36}
37
38static void
39attempt_kernel_inspection(task_t task)
40{
41 pid_t pid = (pid_t)-1;
42 mach_msg_type_number_t i, count, thcnt;
43 struct task_basic_info_64 ti;
44 thread_act_array_t threads;
45
46 T_QUIET;
47 T_EXPECT_MACH_SUCCESS(pid_for_task(task, &pid), NULL);
48 T_LOG("Checking pid %d", pid);
49
50 if (pid != 0) {
51 return;
52 }
53
54 T_LOG("found kernel_task, attempting to inspect");
55
56 count = TASK_BASIC_INFO_64_COUNT;
57 T_EXPECT_MACH_SUCCESS(task_info(task, TASK_BASIC_INFO_64, (task_info_t)&ti,
0a7de745 58 &count), "task_info(... TASK_BASIC_INFO_64 ...)");
813fb2f6
A
59
60 T_EXPECT_MACH_SUCCESS(task_threads(task, &threads, &thcnt), "task_threads");
61 T_LOG("Found %d kernel threads.", thcnt);
62 for (i = 0; i < thcnt; i++) {
5ba3f43e 63 kern_return_t kr;
813fb2f6
A
64 thread_basic_info_data_t basic_info;
65 mach_msg_type_number_t bi_count = THREAD_BASIC_INFO_COUNT;
5ba3f43e
A
66
67 kr = thread_info(threads[i], THREAD_BASIC_INFO,
0a7de745 68 (thread_info_t)&basic_info, &bi_count);
5ba3f43e
A
69 /*
70 * Ignore threads that have gone away.
71 */
72 if (kr == MACH_SEND_INVALID_DEST) {
73 T_LOG("ignoring thread that has been destroyed");
74 continue;
75 }
76 T_EXPECT_MACH_SUCCESS(kr, "thread_info(... THREAD_BASIC_INFO ...)");
813fb2f6
A
77 (void)mach_port_deallocate(mach_task_self(), threads[i]);
78 }
79 mach_vm_deallocate(mach_task_self(),
0a7de745
A
80 (mach_vm_address_t)(uintptr_t)threads,
81 thcnt * sizeof(*threads));
813fb2f6
A
82
83 ipc_info_space_basic_t basic_info;
84 T_EXPECT_MACH_SUCCESS(mach_port_space_basic_info(task, &basic_info), "mach_port_space_basic_info");
85
86 ipc_info_space_t info_space;
87 ipc_info_name_array_t table;
88 ipc_info_tree_name_array_t tree;
89 mach_msg_type_number_t tblcnt = 0, treecnt = 0;
90 T_EXPECT_MACH_SUCCESS(mach_port_space_info(task, &info_space, &table,
0a7de745 91 &tblcnt, &tree, &treecnt), "mach_port_space_info");
813fb2f6
A
92 if (tblcnt > 0) {
93 mach_vm_deallocate(mach_task_self(),
0a7de745
A
94 (mach_vm_address_t)(uintptr_t)table,
95 tblcnt * sizeof(*table));
813fb2f6
A
96 }
97 if (treecnt > 0) {
98 mach_vm_deallocate(mach_task_self(),
0a7de745
A
99 (mach_vm_address_t)(uintptr_t)tree,
100 treecnt * sizeof(*tree));
813fb2f6
A
101 }
102
103 T_END;
104}
105
106T_DECL(inspect_kernel_task,
0a7de745
A
107 "ensure that kernel task can be inspected",
108 T_META_CHECK_LEAKS(false),
109 T_META_ASROOT(true))
813fb2f6
A
110{
111 processor_set_name_array_t psets;
0a7de745 112 processor_set_t pset;
813fb2f6
A
113 task_array_t tasks;
114 mach_msg_type_number_t i, j, tcnt, pcnt = 0;
115 mach_port_t self = mach_host_self();
116
117 check_secure_kernel();
118
119 T_ASSERT_MACH_SUCCESS(host_processor_sets(self, &psets, &pcnt),
0a7de745 120 NULL);
813fb2f6
A
121
122 for (i = 0; i < pcnt; i++) {
123 T_ASSERT_MACH_SUCCESS(host_processor_set_priv(self, psets[i], &pset), NULL);
124 T_LOG("Checking pset %d/%d", i, pcnt - 1);
125
126 tcnt = 0;
127 T_ASSERT_MACH_SUCCESS(processor_set_tasks(pset, &tasks, &tcnt), NULL);
128
129 for (j = 0; j < tcnt; j++) {
130 attempt_kernel_inspection(tasks[j]);
131 mach_port_deallocate(self, tasks[j]);
132 }
133
134 /* free tasks array */
135 mach_vm_deallocate(mach_task_self(),
0a7de745
A
136 (mach_vm_address_t)(uintptr_t)tasks,
137 tcnt * sizeof(*tasks));
813fb2f6
A
138 mach_port_deallocate(mach_task_self(), pset);
139 mach_port_deallocate(mach_task_self(), psets[i]);
140 }
141 mach_vm_deallocate(mach_task_self(),
0a7de745
A
142 (mach_vm_address_t)(uintptr_t)psets,
143 pcnt * sizeof(*psets));
813fb2f6
A
144
145 T_FAIL("could not find kernel_task in list of tasks returned");
146}