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