xref: /xnu-8792.81.2/tests/ipc/port_peek.c (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
1 #include <darwintest.h>
2 #include <darwintest_utils.h>
3 
4 #include <mach/mach.h>
5 #include <mach/mach_types.h>
6 #include <mach/mach_port.h>
7 #include <mach/message.h>
8 #include <mach/mach_error.h>
9 
10 
11 T_GLOBAL_META(
12 	T_META_NAMESPACE("xnu.ipc"),
13 	T_META_RUN_CONCURRENTLY(TRUE),
14 	T_META_RADAR_COMPONENT_NAME("xnu"),
15 	T_META_RADAR_COMPONENT_VERSION("IPC"));
16 
17 T_DECL(mach_port_peek, "Test mach port peeking")
18 {
19 	mach_port_t port;
20 	kern_return_t kr;
21 	struct msg {
22 		mach_msg_header_t header;
23 		char data[512];
24 		char trailer[128];
25 	} msg;
26 
27 	mach_msg_id_t outgoing_id;
28 	mach_msg_size_t send_size;
29 
30 	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
31 	T_QUIET; T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_allocate");
32 
33 	outgoing_id = 0x41414141;
34 	send_size = sizeof(msg) - 128; /* minus trailer space */
35 
36 	msg.header.msgh_local_port = MACH_PORT_NULL;
37 	msg.header.msgh_remote_port = port;
38 	msg.header.msgh_id = outgoing_id;
39 	msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MAKE_SEND, 0, 0, 0);
40 	msg.header.msgh_size = send_size;
41 
42 	kr = mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0,
43 	    MACH_PORT_NULL,
44 	    MACH_MSG_TIMEOUT_NONE,
45 	    MACH_PORT_NULL);
46 	T_ASSERT_EQ(kr, KERN_SUCCESS, "Message sent to port");
47 
48 	mach_port_seqno_t seqno = 0;
49 	mach_msg_trailer_type_t tlrtype =
50 	    MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)
51 	    | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);
52 	mach_msg_audit_trailer_t audit_trailer;
53 	mach_msg_type_number_t size = sizeof(audit_trailer);
54 	mach_msg_type_number_t incoming_size = 0;
55 	mach_msg_id_t incoming_id;
56 
57 	kr = mach_port_peek(mach_task_self(), port, tlrtype, &seqno, &incoming_size, &incoming_id, &audit_trailer, &size);
58 	T_ASSERT_EQ(kr, KERN_SUCCESS, "mach_port_peek");
59 
60 	T_ASSERT_EQ(incoming_id, outgoing_id, "Peek must return correct msgh_id");
61 
62 #define USER_HEADER_SIZE_DELTA 8 /* sizeof(mach_msg_header_t) - sizeof(mach_msg_user_header_t) */
63 	T_ASSERT_EQ(incoming_size, send_size + USER_HEADER_SIZE_DELTA, "Peek must return correct msg size");
64 
65 	kr = mach_msg(&msg.header, MACH_RCV_MSG, 0,
66 	    sizeof(msg), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
67 	T_ASSERT_EQ(kr, KERN_SUCCESS, "Message receive success after peek.");
68 }
69