1 // Test that ioctl works in capability mode.
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <sys/socket.h>
5 #include <fcntl.h>
6 #include <sys/ioctl.h>
7
8 #include "capsicum.h"
9 #include "capsicum-test.h"
10
11 // Ensure that ioctl() works consistently for both regular file descriptors and
12 // capability-wrapped ones.
TEST(Ioctl,Basic)13 TEST(Ioctl, Basic) {
14 cap_rights_t rights_ioctl;
15 cap_rights_init(&rights_ioctl, CAP_IOCTL);
16 cap_rights_t rights_many;
17 cap_rights_init(&rights_many, CAP_READ, CAP_WRITE, CAP_SEEK, CAP_FSTAT, CAP_FSYNC);
18
19 int fd = open("/etc/passwd", O_RDONLY);
20 EXPECT_OK(fd);
21 int fd_no = dup(fd);
22 EXPECT_OK(fd_no);
23 EXPECT_OK(cap_rights_limit(fd, &rights_ioctl));
24 EXPECT_OK(cap_rights_limit(fd_no, &rights_many));
25
26 // Check that CAP_IOCTL is required.
27 int bytes;
28 EXPECT_OK(ioctl(fd, FIONREAD, &bytes));
29 EXPECT_NOTCAPABLE(ioctl(fd_no, FIONREAD, &bytes));
30
31 int one = 1;
32 EXPECT_OK(ioctl(fd, FIOCLEX, &one));
33 EXPECT_NOTCAPABLE(ioctl(fd_no, FIOCLEX, &one));
34
35 close(fd);
36 close(fd_no);
37 }
38
TEST(Ioctl,SubRightNormalFD)39 TEST(Ioctl, SubRightNormalFD) {
40 int fd = open("/etc/passwd", O_RDONLY);
41 EXPECT_OK(fd);
42
43 // Restrict the ioctl(2) subrights of a normal FD.
44 cap_ioctl_t ioctl_nread = FIONREAD;
45 EXPECT_OK(cap_ioctls_limit(fd, &ioctl_nread, 1));
46 int bytes;
47 EXPECT_OK(ioctl(fd, FIONREAD, &bytes));
48 int one = 1;
49 EXPECT_NOTCAPABLE(ioctl(fd, FIOCLEX, &one));
50
51 // Expect to have all primary rights.
52 cap_rights_t rights;
53 EXPECT_OK(cap_rights_get(fd, &rights));
54 cap_rights_t all;
55 CAP_ALL(&all);
56 EXPECT_RIGHTS_EQ(&all, &rights);
57 cap_ioctl_t ioctls[16];
58 memset(ioctls, 0, sizeof(ioctls));
59 ssize_t nioctls = cap_ioctls_get(fd, ioctls, 16);
60 EXPECT_OK(nioctls);
61 EXPECT_EQ(1, nioctls);
62 EXPECT_EQ((cap_ioctl_t)FIONREAD, ioctls[0]);
63
64 // Can't widen the subrights.
65 cap_ioctl_t both_ioctls[2] = {FIONREAD, FIOCLEX};
66 EXPECT_NOTCAPABLE(cap_ioctls_limit(fd, both_ioctls, 2));
67
68 close(fd);
69 }
70
TEST(Ioctl,PreserveSubRights)71 TEST(Ioctl, PreserveSubRights) {
72 int fd = open("/etc/passwd", O_RDONLY);
73 EXPECT_OK(fd);
74 cap_rights_t rights;
75 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_SEEK, CAP_IOCTL);
76 EXPECT_OK(cap_rights_limit(fd, &rights));
77 cap_ioctl_t ioctl_nread = FIONREAD;
78 EXPECT_OK(cap_ioctls_limit(fd, &ioctl_nread, 1));
79
80 cap_rights_t cur_rights;
81 cap_ioctl_t ioctls[16];
82 ssize_t nioctls;
83 EXPECT_OK(cap_rights_get(fd, &cur_rights));
84 EXPECT_RIGHTS_EQ(&rights, &cur_rights);
85 nioctls = cap_ioctls_get(fd, ioctls, 16);
86 EXPECT_OK(nioctls);
87 EXPECT_EQ(1, nioctls);
88 EXPECT_EQ((cap_ioctl_t)FIONREAD, ioctls[0]);
89
90 // Limiting the top-level rights leaves the subrights unaffected...
91 cap_rights_clear(&rights, CAP_READ);
92 EXPECT_OK(cap_rights_limit(fd, &rights));
93 nioctls = cap_ioctls_get(fd, ioctls, 16);
94 EXPECT_OK(nioctls);
95 EXPECT_EQ(1, nioctls);
96 EXPECT_EQ((cap_ioctl_t)FIONREAD, ioctls[0]);
97
98 // ... until we remove CAP_IOCTL
99 cap_rights_clear(&rights, CAP_IOCTL);
100 EXPECT_OK(cap_rights_limit(fd, &rights));
101 nioctls = cap_ioctls_get(fd, ioctls, 16);
102 EXPECT_OK(nioctls);
103 EXPECT_EQ(0, nioctls);
104 EXPECT_EQ(-1, cap_ioctls_limit(fd, &ioctl_nread, 1));
105
106 close(fd);
107 }
108
TEST(Ioctl,SubRights)109 TEST(Ioctl, SubRights) {
110 int fd = open("/etc/passwd", O_RDONLY);
111 EXPECT_OK(fd);
112
113 cap_ioctl_t ioctls[16];
114 ssize_t nioctls;
115 memset(ioctls, 0, sizeof(ioctls));
116 nioctls = cap_ioctls_get(fd, ioctls, 16);
117 EXPECT_OK(nioctls);
118 EXPECT_EQ(CAP_IOCTLS_ALL, nioctls);
119
120 cap_rights_t rights_ioctl;
121 cap_rights_init(&rights_ioctl, CAP_IOCTL);
122 EXPECT_OK(cap_rights_limit(fd, &rights_ioctl));
123
124 nioctls = cap_ioctls_get(fd, ioctls, 16);
125 EXPECT_OK(nioctls);
126 EXPECT_EQ(CAP_IOCTLS_ALL, nioctls);
127
128 // Check operations that need CAP_IOCTL with subrights pristine => OK.
129 int bytes;
130 EXPECT_OK(ioctl(fd, FIONREAD, &bytes));
131 int one = 1;
132 EXPECT_OK(ioctl(fd, FIOCLEX, &one));
133
134 // Check operations that need CAP_IOCTL with all relevant subrights => OK.
135 cap_ioctl_t both_ioctls[2] = {FIONREAD, FIOCLEX};
136 EXPECT_OK(cap_ioctls_limit(fd, both_ioctls, 2));
137 EXPECT_OK(ioctl(fd, FIONREAD, &bytes));
138 EXPECT_OK(ioctl(fd, FIOCLEX, &one));
139
140
141 // Check what happens if we ask for subrights but don't have the space for them.
142 cap_ioctl_t before = 0xBBBBBBBB;
143 cap_ioctl_t one_ioctl = 0;
144 cap_ioctl_t after = 0xAAAAAAAA;
145 nioctls = cap_ioctls_get(fd, &one_ioctl, 1);
146 EXPECT_EQ(2, nioctls);
147 EXPECT_EQ(0xBBBBBBBB, before);
148 EXPECT_TRUE(one_ioctl == FIONREAD || one_ioctl == FIOCLEX);
149 EXPECT_EQ(0xAAAAAAAA, after);
150
151 // Check operations that need CAP_IOCTL with particular subrights.
152 int fd_nread = dup(fd);
153 int fd_clex = dup(fd);
154 cap_ioctl_t ioctl_nread = FIONREAD;
155 cap_ioctl_t ioctl_clex = FIOCLEX;
156 EXPECT_OK(cap_ioctls_limit(fd_nread, &ioctl_nread, 1));
157 EXPECT_OK(cap_ioctls_limit(fd_clex, &ioctl_clex, 1));
158 EXPECT_OK(ioctl(fd_nread, FIONREAD, &bytes));
159 EXPECT_NOTCAPABLE(ioctl(fd_clex, FIONREAD, &bytes));
160 EXPECT_OK(ioctl(fd_clex, FIOCLEX, &one));
161 EXPECT_NOTCAPABLE(ioctl(fd_nread, FIOCLEX, &one));
162
163 // Also check we can retrieve the subrights.
164 memset(ioctls, 0, sizeof(ioctls));
165 nioctls = cap_ioctls_get(fd_nread, ioctls, 16);
166 EXPECT_OK(nioctls);
167 EXPECT_EQ(1, nioctls);
168 EXPECT_EQ((cap_ioctl_t)FIONREAD, ioctls[0]);
169 memset(ioctls, 0, sizeof(ioctls));
170 nioctls = cap_ioctls_get(fd_clex, ioctls, 16);
171 EXPECT_OK(nioctls);
172 EXPECT_EQ(1, nioctls);
173 EXPECT_EQ((cap_ioctl_t)FIOCLEX, ioctls[0]);
174 // And that we can't widen the subrights.
175 EXPECT_NOTCAPABLE(cap_ioctls_limit(fd_nread, both_ioctls, 2));
176 EXPECT_NOTCAPABLE(cap_ioctls_limit(fd_clex, both_ioctls, 2));
177 close(fd_nread);
178 close(fd_clex);
179
180 // Check operations that need CAP_IOCTL with no subrights => ENOTCAPABLE.
181 EXPECT_OK(cap_ioctls_limit(fd, NULL, 0));
182 EXPECT_NOTCAPABLE(ioctl(fd, FIONREAD, &bytes));
183 EXPECT_NOTCAPABLE(ioctl(fd, FIOCLEX, &one));
184
185 close(fd);
186 }
187
TEST(Ioctl,TooManySubRights)188 TEST(Ioctl, TooManySubRights) {
189 int fd = open("/etc/passwd", O_RDONLY);
190 EXPECT_OK(fd);
191
192 cap_ioctl_t ioctls[CAP_IOCTLS_LIMIT_MAX + 1];
193 for (int ii = 0; ii <= CAP_IOCTLS_LIMIT_MAX; ii++) {
194 ioctls[ii] = ii + 1;
195 }
196
197 cap_rights_t rights_ioctl;
198 cap_rights_init(&rights_ioctl, CAP_IOCTL);
199 EXPECT_OK(cap_rights_limit(fd, &rights_ioctl));
200
201 // Can only limit to a certain number of ioctls
202 EXPECT_EQ(-1, cap_ioctls_limit(fd, ioctls, CAP_IOCTLS_LIMIT_MAX + 1));
203 EXPECT_EQ(EINVAL, errno);
204 EXPECT_OK(cap_ioctls_limit(fd, ioctls, CAP_IOCTLS_LIMIT_MAX));
205
206 close(fd);
207 }
208