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. 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 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 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 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 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