]> git.saurik.com Git - apple/xnu.git/blob - tests/scm_rights_leak.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / scm_rights_leak.c
1 /*
2 * Copyright (c) 2021 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <sys/socket.h>
30 #include <sys/un.h>
31
32 #include <stdlib.h>
33 #include <unistd.h>
34
35 #include <darwintest.h>
36
37 #define MAX_SOCK 10
38
39 T_DECL(scm_rights_leak, "test leak of file pointers by peeking SCM_RIGHTS")
40 {
41 int pair[2];
42
43 T_ASSERT_POSIX_SUCCESS(socketpair(AF_UNIX, SOCK_STREAM, 0, pair),
44 NULL);
45
46 struct cmsghdr *cmsg;
47 T_ASSERT_NOTNULL(cmsg = calloc(1, MAX_SOCK * sizeof(int)), "calloc");
48 cmsg->cmsg_len = CMSG_LEN(MAX_SOCK * sizeof(int));
49 cmsg->cmsg_level = SOL_SOCKET;
50 cmsg->cmsg_type = SCM_RIGHTS;
51
52 int *sock_fds = (int *)(void *)CMSG_DATA(cmsg);
53 for (int i = 0; i < MAX_SOCK; i++) {
54 T_ASSERT_POSIX_SUCCESS(sock_fds[i] = socket(AF_UNIX, SOCK_DGRAM, 0), NULL);
55 }
56 for (int i = 0; i < MAX_SOCK; i++) {
57 fprintf(stderr, "sock_fds[%d] %i\n", i, sock_fds[i]);
58 }
59
60 struct iovec iovec[1];
61 char data = 'x';
62 iovec[0].iov_base = &data;
63 iovec[0].iov_len = 1;
64
65 struct msghdr mh;
66 mh.msg_name = 0;
67 mh.msg_namelen = 0;
68 mh.msg_iov = iovec;
69 mh.msg_iovlen = 1;
70 mh.msg_control = cmsg;
71 mh.msg_controllen = cmsg->cmsg_len;
72 mh.msg_flags = 0;
73
74 ssize_t ssize;
75 ssize = sendmsg(pair[0], &mh, 0);
76 T_ASSERT_EQ(ssize, (ssize_t)1, "sendmsg");
77
78 struct cmsghdr *rcmsg;
79 T_EXPECT_POSIX_SUCCESS_(rcmsg = calloc(2048, 1), "calloc");
80
81 mh.msg_name = 0;
82 mh.msg_namelen = 0;
83 mh.msg_iov = iovec;
84 mh.msg_iovlen = 1;
85 mh.msg_control = rcmsg;
86 mh.msg_controllen = 2048;
87 mh.msg_flags = 0;
88
89 ssize = recvmsg(pair[1], &mh, MSG_PEEK);
90 T_ASSERT_POSIX_SUCCESS(ssize, "recvmsg");
91 uintptr_t *r_ptrs = (uintptr_t *)(void *)CMSG_DATA(rcmsg);
92 socklen_t nptrs = (rcmsg->cmsg_len - CMSG_LEN(0)) / sizeof(uintptr_t);
93 for (socklen_t i = 0; i < nptrs; i++) {
94 T_EXPECT_EQ(r_ptrs[i], (uintptr_t)0, "r_ptrs[%u] 0x%lx\n", i, r_ptrs[i]);
95 }
96
97 ssize = recvmsg(pair[1], &mh, 0);
98 T_ASSERT_POSIX_SUCCESS(ssize, "recvmsg");
99 int *r_fds = (int *)(void *)CMSG_DATA(rcmsg);
100 for (int i = 0; i < MAX_SOCK; i++) {
101 T_EXPECT_NE(r_fds[i], 0, "r_fds[%d] %i\n", i, r_fds[i]);
102 }
103
104 free(cmsg);
105 free(rcmsg);
106 close(pair[0]);
107 close(pair[1]);
108 }