xref: /xnu-8796.101.5/tests/mach_port_mod_refs.c (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1 #include <darwintest.h>
2 #include <mach/mach.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 
6 T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true),
7     T_META_NAMESPACE("xnu.ipc"),
8     T_META_RADAR_COMPONENT_NAME("xnu"),
9     T_META_RADAR_COMPONENT_VERSION("IPC"));
10 
11 T_DECL(mach_port_mod_refs, "mach_port_mod_refs"){
12 	mach_port_t port_set;
13 	mach_port_t port;
14 	task_exc_guard_behavior_t old, new;
15 	int ret;
16 
17 	ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &port_set);
18 	T_ASSERT_MACH_SUCCESS(ret, "mach_port_allocate MACH_PORT_RIGHT_PORT_SET");
19 
20 	ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
21 	T_ASSERT_MACH_SUCCESS(ret, "mach_port_allocate MACH_PORT_RIGHT_RECEIVE");
22 
23 	/*
24 	 * Disable [optional] Mach port guard exceptions to avoid fatal crash
25 	 */
26 	ret = task_get_exc_guard_behavior(mach_task_self(), &old);
27 	T_ASSERT_MACH_SUCCESS(ret, "task_get_exc_guard_behavior");
28 	new = (old & ~TASK_EXC_GUARD_MP_DELIVER);
29 	ret = task_set_exc_guard_behavior(mach_task_self(), new);
30 	T_ASSERT_MACH_SUCCESS(ret, "task_set_exc_guard_behavior new");
31 
32 	/*
33 	 * Test all known variants of port rights on each type of port
34 	 */
35 
36 	/* can't subtract a send right if it doesn't exist */
37 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1);
38 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs SEND: -1 on a RECV right");
39 
40 	/* can't subtract a send once right if it doesn't exist */
41 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND_ONCE, -1);
42 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs SEND_ONCE: -1 on a RECV right");
43 
44 	/* can't subtract a PORT SET right if it's not a port set */
45 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_PORT_SET, -1);
46 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs PORT_SET: -1 on a RECV right");
47 
48 	/* can't subtract a dead name right if it doesn't exist */
49 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_DEAD_NAME, -1);
50 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs DEAD_NAME: -1 on a RECV right");
51 
52 	/* can't subtract a LABELH right if it doesn't exist */
53 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_LABELH, -1);
54 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs LABELH: -1 on a RECV right");
55 
56 	/* can't subtract an invalid right-type */
57 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_NUMBER, -1);
58 	T_ASSERT_EQ(ret, KERN_INVALID_VALUE, "mach_port_mod_refs NUMBER: -1 on a RECV right");
59 
60 	/* can't subtract an invalid right-type */
61 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_NUMBER + 1, -1);
62 	T_ASSERT_EQ(ret, KERN_INVALID_VALUE, "mach_port_mod_refs NUMBER+1: -1 on a RECV right");
63 
64 
65 	/* can't subtract a send right if it doesn't exist */
66 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_SEND, -1);
67 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs SEND: -1 on a PORT_SET right");
68 
69 	/* can't subtract a send once right if it doesn't exist */
70 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_SEND_ONCE, -1);
71 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs SEND_ONCE: -1 on a PORT_SET right");
72 
73 	/* can't subtract a receive right if it's a port set */
74 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_RECEIVE, -1);
75 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs RECV: -1 on a PORT_SET right");
76 
77 	/* can't subtract a dead name right if it doesn't exist */
78 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_DEAD_NAME, -1);
79 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs DEAD_NAME: -1 on a PORT_SET right");
80 
81 	/* can't subtract a LABELH right if it doesn't exist */
82 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_LABELH, -1);
83 	T_ASSERT_EQ(ret, KERN_INVALID_RIGHT, "mach_port_mod_refs LABELH: -1 on a PORT_SET right");
84 
85 	/* can't subtract an invalid right-type */
86 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_NUMBER, -1);
87 	T_ASSERT_EQ(ret, KERN_INVALID_VALUE, "mach_port_mod_refs NUMBER: -1 on a PORT_SET right");
88 
89 	/* can't subtract an invalid right-type */
90 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_NUMBER + 1, -1);
91 	T_ASSERT_EQ(ret, KERN_INVALID_VALUE, "mach_port_mod_refs NUMBER+1: -1 on a PORT_SET right");
92 
93 	/* restore the old guard behavior */
94 	ret = task_set_exc_guard_behavior(mach_task_self(), old);
95 	T_ASSERT_MACH_SUCCESS(ret, "task_set_exc_guard_behavior old");
96 
97 	/*
98 	 * deallocate the ports/sets
99 	 */
100 	ret = mach_port_mod_refs(mach_task_self(), port_set, MACH_PORT_RIGHT_PORT_SET, -1);
101 	T_ASSERT_MACH_SUCCESS(ret, "mach_port_mod_refs(PORT_SET, -1)");
102 
103 	ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1);
104 	T_ASSERT_MACH_SUCCESS(ret, "mach_port_mod_refs(RECV_RIGHT, -1)");
105 }
106