]> git.saurik.com Git - apple/xnu.git/blame - tests/extract_right_soft_fail.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / extract_right_soft_fail.c
CommitLineData
c3c9b80d
A
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <darwintest.h>
5#include <mach/mach.h>
6#include <mach/mach_vm.h>
7#include <sys/sysctl.h>
8#include <spawn.h>
9#include <signal.h>
10
11#define IKOT_TASK_CONTROL 2
12
13T_GLOBAL_META(
14 T_META_NAMESPACE("xnu.ipc"),
15 T_META_RUN_CONCURRENTLY(TRUE));
16
17static void
18test_extract_immovable_task_port(pid_t pid)
19{
20 kern_return_t kr;
21 mach_port_t tport = MACH_PORT_NULL;
22 ipc_info_space_t space_info;
23 ipc_info_name_array_t table;
24 mach_msg_type_number_t tableCount;
25 ipc_info_tree_name_array_t tree; /* unused */
26 mach_msg_type_number_t treeCount; /* unused */
27
28 mach_port_t extracted;
29 mach_msg_type_name_t right;
30
31
32 kr = task_for_pid(mach_task_self(), pid, &tport);
33 T_EXPECT_MACH_SUCCESS(kr, "task_for_pid(), tport: 0x%x", tport);
34
35 T_LOG("Target pid: %d", pid);
36
37 if (pid == getpid()) {
38 /* self extraction should succeed */
39 kr = mach_port_extract_right(mach_task_self(), mach_task_self(), MACH_MSG_TYPE_COPY_SEND, &extracted, &right);
40 T_EXPECT_MACH_SUCCESS(kr, "mach_port_extract_right() on immovable port in current space should succeed");
41 } else {
42 unsigned int kotype = 0, kobject = 0;
43 mach_port_name_t tport_name = MACH_PORT_NULL;
44 kr = mach_port_space_info(tport, &space_info, &table, &tableCount, &tree, &treeCount);
45 T_EXPECT_MACH_SUCCESS(kr, "mach_port_space_info()");
46
47 for (int i = 0; i < tableCount; i++) {
48 T_LOG("Searching for task port..name: 0x%x", table[i].iin_name);
49 kr = mach_port_kernel_object(tport, table[i].iin_name, &kotype, &kobject);
50 if (KERN_SUCCESS == kr && kotype == IKOT_TASK_CONTROL) {
51 tport_name = table[i].iin_name;
52 break;
53 } else if (kr) {
54 T_LOG("mach_port_kernel_object() failed on name 0x%x, kr: 0x%x", table[i].iin_name, kr);
55 }
56 }
57
58 if (!tport_name) {
59 T_FAIL("Did not find task port in child's space");
60 }
61 T_LOG("Remote tport name: 0x%x", tport_name);
62 kr = mach_port_extract_right(tport, tport_name, MACH_MSG_TYPE_COPY_SEND, &extracted, &right);
63 T_EXPECT_EQ(kr, KERN_INVALID_CAPABILITY, "mach_port_extract_right() on immovable port in child's space should fail (no crash): 0x%x", kr);
64
65 T_LOG("Still alive..");
66 }
67}
68
69T_DECL(extract_right_soft_fail, "Test mach_port_extract_right() fail on extracting child process's task port without crash",
70 T_META_CHECK_LEAKS(false))
71{
72 uint32_t opts = 0;
73 size_t size = sizeof(&opts);
74 pid_t child_pid;
75 kern_return_t ret;
76 int status, fd[2];
77
78 T_LOG("Check if immovable control port has been enabled\n");
79 ret = sysctlbyname("kern.ipc_control_port_options", &opts, &size, NULL, 0);
80
81 if (!ret && (opts & 0x20) == 0) {
82 T_SKIP("immovable control port hard enforcement isn't enabled");
83 }
84
85 /* extracting mach_task_self() should succeed */
86 test_extract_immovable_task_port(getpid());
87
88 ret = pipe(fd);
89 T_EXPECT_NE(ret, -1, "pipe creation");
90
91
92 child_pid = fork();
93
94 if (child_pid < 0) {
95 T_FAIL("fork failed()");
96 }
97
98 if (child_pid == 0) {
99 close(fd[0]);
100 write(fd[1], "wakeup", 6);
101 close(fd[1]);
102 } else {
103 close(fd[1]);
104 char data[6];
105 read(fd[0], data, 6); /* blocks until data available */
106 close(fd[0]);
107
108 /* extracting child's immovable task port should fail without crash */
109 test_extract_immovable_task_port(child_pid);
110
111 kill(child_pid, SIGKILL);
112 wait(&status);
113 }
114}