4 #include <darwintest.h>
6 #include <mach/mach_vm.h>
7 #include <sys/sysctl.h>
11 #define IKOT_TASK_CONTROL 2
14 T_META_NAMESPACE("xnu.ipc"),
15 T_META_RUN_CONCURRENTLY(TRUE
));
18 test_extract_immovable_task_port(pid_t pid
)
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 */
28 mach_port_t extracted
;
29 mach_msg_type_name_t right
;
32 kr
= task_for_pid(mach_task_self(), pid
, &tport
);
33 T_EXPECT_MACH_SUCCESS(kr
, "task_for_pid(), tport: 0x%x", tport
);
35 T_LOG("Target pid: %d", pid
);
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");
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()");
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
;
54 T_LOG("mach_port_kernel_object() failed on name 0x%x, kr: 0x%x", table
[i
].iin_name
, kr
);
59 T_FAIL("Did not find task port in child's space");
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
);
65 T_LOG("Still alive..");
69 T_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))
73 size_t size
= sizeof(&opts
);
78 T_LOG("Check if immovable control port has been enabled\n");
79 ret
= sysctlbyname("kern.ipc_control_port_options", &opts
, &size
, NULL
, 0);
81 if (!ret
&& (opts
& 0x20) == 0) {
82 T_SKIP("immovable control port hard enforcement isn't enabled");
85 /* extracting mach_task_self() should succeed */
86 test_extract_immovable_task_port(getpid());
89 T_EXPECT_NE(ret
, -1, "pipe creation");
95 T_FAIL("fork failed()");
100 write(fd
[1], "wakeup", 6);
105 read(fd
[0], data
, 6); /* blocks until data available */
108 /* extracting child's immovable task port should fail without crash */
109 test_extract_immovable_task_port(child_pid
);
111 kill(child_pid
, SIGKILL
);