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