1de503941SPawel Jakub Dawidek /*- 2de503941SPawel Jakub Dawidek * Copyright (c) 2012 The FreeBSD Foundation 3de503941SPawel Jakub Dawidek * 4de503941SPawel Jakub Dawidek * This software was developed by Pawel Jakub Dawidek under sponsorship from 5de503941SPawel Jakub Dawidek * the FreeBSD Foundation. 6de503941SPawel Jakub Dawidek * 7de503941SPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 8de503941SPawel Jakub Dawidek * modification, are permitted provided that the following conditions 9de503941SPawel Jakub Dawidek * are met: 10de503941SPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 11de503941SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 12de503941SPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 13de503941SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 14de503941SPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 15de503941SPawel Jakub Dawidek * 16de503941SPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17de503941SPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18de503941SPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19de503941SPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20de503941SPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21de503941SPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22de503941SPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23de503941SPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24de503941SPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25de503941SPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26de503941SPawel Jakub Dawidek * SUCH DAMAGE. 27de503941SPawel Jakub Dawidek */ 28de503941SPawel Jakub Dawidek 29de503941SPawel Jakub Dawidek #include <sys/param.h> 30b881b8beSRobert Watson #include <sys/capsicum.h> 31de503941SPawel Jakub Dawidek #include <sys/ioctl.h> 32de503941SPawel Jakub Dawidek #include <sys/procdesc.h> 33de503941SPawel Jakub Dawidek #include <sys/socket.h> 34de503941SPawel Jakub Dawidek #include <sys/wait.h> 35de503941SPawel Jakub Dawidek 36de503941SPawel Jakub Dawidek #include <err.h> 37de503941SPawel Jakub Dawidek #include <errno.h> 38de503941SPawel Jakub Dawidek #include <limits.h> 39de503941SPawel Jakub Dawidek #include <stdio.h> 40de503941SPawel Jakub Dawidek #include <stdlib.h> 41de503941SPawel Jakub Dawidek #include <unistd.h> 42de503941SPawel Jakub Dawidek 43de503941SPawel Jakub Dawidek #include "misc.h" 44de503941SPawel Jakub Dawidek 45de503941SPawel Jakub Dawidek static void 46de503941SPawel Jakub Dawidek ioctl_tests_0(int fd) 47de503941SPawel Jakub Dawidek { 48de503941SPawel Jakub Dawidek unsigned long cmds[2]; 49de503941SPawel Jakub Dawidek 502328a74aSPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, NULL, 0) == CAP_IOCTLS_ALL); 51de503941SPawel Jakub Dawidek 52de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 53de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == 0); 54de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 55de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == 0); 56de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 57de503941SPawel Jakub Dawidek 58de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 59de503941SPawel Jakub Dawidek cmds[1] = FIONCLEX; 60de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == 0); 61de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 62de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == nitems(cmds)); 63de503941SPawel Jakub Dawidek CHECK((cmds[0] == FIOCLEX && cmds[1] == FIONCLEX) || 64de503941SPawel Jakub Dawidek (cmds[0] == FIONCLEX && cmds[1] == FIOCLEX)); 65de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 66de503941SPawel Jakub Dawidek cmds[1] = FIONCLEX; 67de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == 0); 68de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 69de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, 1) == nitems(cmds)); 70de503941SPawel Jakub Dawidek CHECK(cmds[0] == FIOCLEX || cmds[0] == FIONCLEX); 71de503941SPawel Jakub Dawidek CHECK(cmds[1] == 0); 72de503941SPawel Jakub Dawidek 73de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 74de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == 0); 75de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 76de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == 0); 77de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 78de503941SPawel Jakub Dawidek 79de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 80de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, 1) == 0); 81de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 82de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 83de503941SPawel Jakub Dawidek CHECK(cmds[0] == FIOCLEX); 84de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 85de503941SPawel Jakub Dawidek cmds[1] = FIONCLEX; 86de503941SPawel Jakub Dawidek errno = 0; 87de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1); 88de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 89de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 90de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 91de503941SPawel Jakub Dawidek CHECK(cmds[0] == FIOCLEX); 92de503941SPawel Jakub Dawidek 93de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 94de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == 0); 95de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 96de503941SPawel Jakub Dawidek errno = 0; 97de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == -1); 98de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 99de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 100de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, 0) == 0); 101de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 102de503941SPawel Jakub Dawidek 103de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, NULL, 0) == 0); 104de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 105de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 106de503941SPawel Jakub Dawidek errno = 0; 107de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, 1) == -1); 108de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 109de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 110de503941SPawel Jakub Dawidek 111de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 112de503941SPawel Jakub Dawidek errno = 0; 113de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == -1); 114de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 115de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 116de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 117de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 118de503941SPawel Jakub Dawidek errno = 0; 119de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == -1); 120de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 121de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 122de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, 0) == 0); 123de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 124de503941SPawel Jakub Dawidek } 125de503941SPawel Jakub Dawidek 126de503941SPawel Jakub Dawidek static void 127de503941SPawel Jakub Dawidek ioctl_tests_1(int fd) 128de503941SPawel Jakub Dawidek { 129de503941SPawel Jakub Dawidek unsigned long cmds[2]; 130*d7795033SMariusz Zaborski cap_rights_t rights; 131de503941SPawel Jakub Dawidek 132de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 133de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, 1) == 0); 134de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 135de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 136de503941SPawel Jakub Dawidek CHECK(cmds[0] == FIOCLEX); 137de503941SPawel Jakub Dawidek CHECK(cmds[1] == 0); 138de503941SPawel Jakub Dawidek 139*d7795033SMariusz Zaborski CAP_ALL(&rights); 140*d7795033SMariusz Zaborski cap_rights_clear(&rights, CAP_IOCTL); 141*d7795033SMariusz Zaborski 142*d7795033SMariusz Zaborski CHECK(cap_rights_limit(fd, &rights) == 0); 143de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 144de503941SPawel Jakub Dawidek 145de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 146de503941SPawel Jakub Dawidek cmds[1] = FIONCLEX; 147de503941SPawel Jakub Dawidek errno = 0; 148de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1); 149de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 150de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 151de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 152de503941SPawel Jakub Dawidek errno = 0; 153de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, 1) == -1); 154de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 155de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 156de503941SPawel Jakub Dawidek 157de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 158de503941SPawel Jakub Dawidek errno = 0; 159de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == -1); 160de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 161de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 162de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 163de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 164de503941SPawel Jakub Dawidek errno = 0; 165de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == -1); 166de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 167de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 168de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, 0) == 0); 169de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 170de503941SPawel Jakub Dawidek } 171de503941SPawel Jakub Dawidek 172de503941SPawel Jakub Dawidek static void 173de503941SPawel Jakub Dawidek ioctl_tests_2(int fd) 174de503941SPawel Jakub Dawidek { 175de503941SPawel Jakub Dawidek unsigned long cmds[2]; 176*d7795033SMariusz Zaborski cap_rights_t rights; 177de503941SPawel Jakub Dawidek 178*d7795033SMariusz Zaborski CAP_ALL(&rights); 179*d7795033SMariusz Zaborski cap_rights_clear(&rights, CAP_IOCTL); 180*d7795033SMariusz Zaborski 181*d7795033SMariusz Zaborski CHECK(cap_rights_limit(fd, &rights) == 0); 182de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 183de503941SPawel Jakub Dawidek 184de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 185de503941SPawel Jakub Dawidek cmds[1] = FIONCLEX; 186de503941SPawel Jakub Dawidek errno = 0; 187de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1); 188de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 189de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 190de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 191de503941SPawel Jakub Dawidek errno = 0; 192de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, 1) == -1); 193de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 194de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 195de503941SPawel Jakub Dawidek 196de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 197de503941SPawel Jakub Dawidek errno = 0; 198de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == -1); 199de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 200de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 201de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 202de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 203de503941SPawel Jakub Dawidek errno = 0; 204de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == -1); 205de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 206de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 207de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, 0) == 0); 208de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 209de503941SPawel Jakub Dawidek } 210de503941SPawel Jakub Dawidek 211de503941SPawel Jakub Dawidek static void 212de503941SPawel Jakub Dawidek ioctl_tests_send_0(int sock) 213de503941SPawel Jakub Dawidek { 214de503941SPawel Jakub Dawidek unsigned long cmds[2]; 215de503941SPawel Jakub Dawidek int fd; 216de503941SPawel Jakub Dawidek 217de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 218de503941SPawel Jakub Dawidek CHECK(descriptor_send(sock, fd) == 0); 219de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 220de503941SPawel Jakub Dawidek 221de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 222de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 223de503941SPawel Jakub Dawidek cmds[1] = FIONCLEX; 224de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == 0); 225de503941SPawel Jakub Dawidek CHECK(descriptor_send(sock, fd) == 0); 226de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 227de503941SPawel Jakub Dawidek 228de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 229de503941SPawel Jakub Dawidek cmds[0] = FIOCLEX; 230de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, cmds, 1) == 0); 231de503941SPawel Jakub Dawidek CHECK(descriptor_send(sock, fd) == 0); 232de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 233de503941SPawel Jakub Dawidek 234de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 235de503941SPawel Jakub Dawidek CHECK(cap_ioctls_limit(fd, NULL, 0) == 0); 236de503941SPawel Jakub Dawidek CHECK(descriptor_send(sock, fd) == 0); 237de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 238de503941SPawel Jakub Dawidek } 239de503941SPawel Jakub Dawidek 240de503941SPawel Jakub Dawidek static void 241de503941SPawel Jakub Dawidek ioctl_tests_recv_0(int sock) 242de503941SPawel Jakub Dawidek { 243de503941SPawel Jakub Dawidek unsigned long cmds[2]; 244de503941SPawel Jakub Dawidek int fd; 245de503941SPawel Jakub Dawidek 246de503941SPawel Jakub Dawidek CHECK(descriptor_recv(sock, &fd) == 0); 247de503941SPawel Jakub Dawidek 2482328a74aSPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, NULL, 0) == CAP_IOCTLS_ALL); 249de503941SPawel Jakub Dawidek 250de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 251de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == 0); 252de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 253de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == 0); 254de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 255de503941SPawel Jakub Dawidek 256de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 257de503941SPawel Jakub Dawidek 258de503941SPawel Jakub Dawidek CHECK(descriptor_recv(sock, &fd) == 0); 259de503941SPawel Jakub Dawidek 260de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 261de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == nitems(cmds)); 262de503941SPawel Jakub Dawidek CHECK((cmds[0] == FIOCLEX && cmds[1] == FIONCLEX) || 263de503941SPawel Jakub Dawidek (cmds[0] == FIONCLEX && cmds[1] == FIOCLEX)); 264de503941SPawel Jakub Dawidek 265de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 266de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == 0); 267de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 268de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == 0); 269de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 270de503941SPawel Jakub Dawidek 271de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 272de503941SPawel Jakub Dawidek 273de503941SPawel Jakub Dawidek CHECK(descriptor_recv(sock, &fd) == 0); 274de503941SPawel Jakub Dawidek 275de503941SPawel Jakub Dawidek cmds[0] = cmds[1] = 0; 276de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 277de503941SPawel Jakub Dawidek CHECK(cmds[0] == FIOCLEX); 278de503941SPawel Jakub Dawidek 279de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 280de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == 0); 281de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 282de503941SPawel Jakub Dawidek errno = 0; 283de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == -1); 284de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 285de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 286de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, 0) == 0); 287de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 288de503941SPawel Jakub Dawidek 289de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 290de503941SPawel Jakub Dawidek 291de503941SPawel Jakub Dawidek CHECK(descriptor_recv(sock, &fd) == 0); 292de503941SPawel Jakub Dawidek 293de503941SPawel Jakub Dawidek CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 294de503941SPawel Jakub Dawidek 295de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 296de503941SPawel Jakub Dawidek errno = 0; 297de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIOCLEX) == -1); 298de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 299de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 300de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 301de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 302de503941SPawel Jakub Dawidek errno = 0; 303de503941SPawel Jakub Dawidek CHECK(ioctl(fd, FIONCLEX) == -1); 304de503941SPawel Jakub Dawidek CHECK(errno == ENOTCAPABLE); 305de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 306de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_SETFD, 0) == 0); 307de503941SPawel Jakub Dawidek CHECK(fcntl(fd, F_GETFD) == 0); 308de503941SPawel Jakub Dawidek 309de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 310de503941SPawel Jakub Dawidek } 311de503941SPawel Jakub Dawidek 312de503941SPawel Jakub Dawidek int 313de503941SPawel Jakub Dawidek main(void) 314de503941SPawel Jakub Dawidek { 315de503941SPawel Jakub Dawidek int fd, pfd, sp[2]; 316de503941SPawel Jakub Dawidek pid_t pid; 317de503941SPawel Jakub Dawidek 318de503941SPawel Jakub Dawidek printf("1..607\n"); 319de503941SPawel Jakub Dawidek 320de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 321de503941SPawel Jakub Dawidek ioctl_tests_0(fd); 322de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 323de503941SPawel Jakub Dawidek 324de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 325de503941SPawel Jakub Dawidek ioctl_tests_1(fd); 326de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 327de503941SPawel Jakub Dawidek 328de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 329de503941SPawel Jakub Dawidek ioctl_tests_2(fd); 330de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 331de503941SPawel Jakub Dawidek 332de503941SPawel Jakub Dawidek /* Child inherits descriptor and operates on it first. */ 333de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 334de503941SPawel Jakub Dawidek pid = fork(); 335de503941SPawel Jakub Dawidek switch (pid) { 336de503941SPawel Jakub Dawidek case -1: 337de503941SPawel Jakub Dawidek err(1, "fork() failed"); 338de503941SPawel Jakub Dawidek case 0: 339de503941SPawel Jakub Dawidek ioctl_tests_0(fd); 340de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 341de503941SPawel Jakub Dawidek exit(0); 342de503941SPawel Jakub Dawidek default: 343de503941SPawel Jakub Dawidek if (waitpid(pid, NULL, 0) == -1) 344de503941SPawel Jakub Dawidek err(1, "waitpid() failed"); 345de503941SPawel Jakub Dawidek ioctl_tests_0(fd); 346de503941SPawel Jakub Dawidek } 347de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 348de503941SPawel Jakub Dawidek 349de503941SPawel Jakub Dawidek /* Child inherits descriptor, but operates on it after parent. */ 350de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 351de503941SPawel Jakub Dawidek pid = fork(); 352de503941SPawel Jakub Dawidek switch (pid) { 353de503941SPawel Jakub Dawidek case -1: 354de503941SPawel Jakub Dawidek err(1, "fork() failed"); 355de503941SPawel Jakub Dawidek case 0: 356de503941SPawel Jakub Dawidek sleep(1); 357de503941SPawel Jakub Dawidek ioctl_tests_0(fd); 358de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 359de503941SPawel Jakub Dawidek exit(0); 360de503941SPawel Jakub Dawidek default: 361de503941SPawel Jakub Dawidek ioctl_tests_0(fd); 362de503941SPawel Jakub Dawidek if (waitpid(pid, NULL, 0) == -1) 363de503941SPawel Jakub Dawidek err(1, "waitpid() failed"); 364de503941SPawel Jakub Dawidek } 365de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 366de503941SPawel Jakub Dawidek 367de503941SPawel Jakub Dawidek /* Child inherits descriptor and operates on it first. */ 368de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 369de503941SPawel Jakub Dawidek pid = pdfork(&pfd, 0); 370de503941SPawel Jakub Dawidek switch (pid) { 371de503941SPawel Jakub Dawidek case -1: 372de503941SPawel Jakub Dawidek err(1, "pdfork() failed"); 373de503941SPawel Jakub Dawidek case 0: 374de503941SPawel Jakub Dawidek ioctl_tests_1(fd); 375de503941SPawel Jakub Dawidek exit(0); 376de503941SPawel Jakub Dawidek default: 377de503941SPawel Jakub Dawidek if (pdwait(pfd) == -1) 378de503941SPawel Jakub Dawidek err(1, "pdwait() failed"); 379de503941SPawel Jakub Dawidek close(pfd); 380de503941SPawel Jakub Dawidek ioctl_tests_1(fd); 381de503941SPawel Jakub Dawidek } 382de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 383de503941SPawel Jakub Dawidek 384de503941SPawel Jakub Dawidek /* Child inherits descriptor, but operates on it after parent. */ 385de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 386de503941SPawel Jakub Dawidek pid = pdfork(&pfd, 0); 387de503941SPawel Jakub Dawidek switch (pid) { 388de503941SPawel Jakub Dawidek case -1: 389de503941SPawel Jakub Dawidek err(1, "pdfork() failed"); 390de503941SPawel Jakub Dawidek case 0: 391de503941SPawel Jakub Dawidek sleep(1); 392de503941SPawel Jakub Dawidek ioctl_tests_1(fd); 393de503941SPawel Jakub Dawidek exit(0); 394de503941SPawel Jakub Dawidek default: 395de503941SPawel Jakub Dawidek ioctl_tests_1(fd); 396de503941SPawel Jakub Dawidek if (pdwait(pfd) == -1) 397de503941SPawel Jakub Dawidek err(1, "pdwait() failed"); 398de503941SPawel Jakub Dawidek close(pfd); 399de503941SPawel Jakub Dawidek } 400de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 401de503941SPawel Jakub Dawidek 402de503941SPawel Jakub Dawidek /* Child inherits descriptor and operates on it first. */ 403de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 404de503941SPawel Jakub Dawidek pid = fork(); 405de503941SPawel Jakub Dawidek switch (pid) { 406de503941SPawel Jakub Dawidek case -1: 407de503941SPawel Jakub Dawidek err(1, "fork() failed"); 408de503941SPawel Jakub Dawidek case 0: 409de503941SPawel Jakub Dawidek ioctl_tests_2(fd); 410de503941SPawel Jakub Dawidek exit(0); 411de503941SPawel Jakub Dawidek default: 412de503941SPawel Jakub Dawidek if (waitpid(pid, NULL, 0) == -1) 413de503941SPawel Jakub Dawidek err(1, "waitpid() failed"); 414de503941SPawel Jakub Dawidek ioctl_tests_2(fd); 415de503941SPawel Jakub Dawidek } 416de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 417de503941SPawel Jakub Dawidek 418de503941SPawel Jakub Dawidek /* Child inherits descriptor, but operates on it after parent. */ 419de503941SPawel Jakub Dawidek CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 420de503941SPawel Jakub Dawidek pid = fork(); 421de503941SPawel Jakub Dawidek switch (pid) { 422de503941SPawel Jakub Dawidek case -1: 423de503941SPawel Jakub Dawidek err(1, "fork() failed"); 424de503941SPawel Jakub Dawidek case 0: 425de503941SPawel Jakub Dawidek sleep(1); 426de503941SPawel Jakub Dawidek ioctl_tests_2(fd); 427de503941SPawel Jakub Dawidek exit(0); 428de503941SPawel Jakub Dawidek default: 429de503941SPawel Jakub Dawidek ioctl_tests_2(fd); 430de503941SPawel Jakub Dawidek if (waitpid(pid, NULL, 0) == -1) 431de503941SPawel Jakub Dawidek err(1, "waitpid() failed"); 432de503941SPawel Jakub Dawidek } 433de503941SPawel Jakub Dawidek CHECK(close(fd) == 0); 434de503941SPawel Jakub Dawidek 435de503941SPawel Jakub Dawidek /* Send descriptors from parent to child. */ 436de503941SPawel Jakub Dawidek CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0); 437de503941SPawel Jakub Dawidek CHECK((pid = fork()) >= 0); 438de503941SPawel Jakub Dawidek if (pid == 0) { 439de503941SPawel Jakub Dawidek CHECK(close(sp[0]) == 0); 440de503941SPawel Jakub Dawidek ioctl_tests_recv_0(sp[1]); 441de503941SPawel Jakub Dawidek CHECK(close(sp[1]) == 0); 442de503941SPawel Jakub Dawidek exit(0); 443de503941SPawel Jakub Dawidek } else { 444de503941SPawel Jakub Dawidek CHECK(close(sp[1]) == 0); 445de503941SPawel Jakub Dawidek ioctl_tests_send_0(sp[0]); 446de503941SPawel Jakub Dawidek CHECK(waitpid(pid, NULL, 0) == pid); 447de503941SPawel Jakub Dawidek CHECK(close(sp[0]) == 0); 448de503941SPawel Jakub Dawidek } 449de503941SPawel Jakub Dawidek 450de503941SPawel Jakub Dawidek /* Send descriptors from child to parent. */ 451de503941SPawel Jakub Dawidek CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0); 452de503941SPawel Jakub Dawidek CHECK((pid = fork()) >= 0); 453de503941SPawel Jakub Dawidek if (pid == 0) { 454de503941SPawel Jakub Dawidek CHECK(close(sp[0]) == 0); 455de503941SPawel Jakub Dawidek ioctl_tests_send_0(sp[1]); 456de503941SPawel Jakub Dawidek CHECK(close(sp[1]) == 0); 457de503941SPawel Jakub Dawidek exit(0); 458de503941SPawel Jakub Dawidek } else { 459de503941SPawel Jakub Dawidek CHECK(close(sp[1]) == 0); 460de503941SPawel Jakub Dawidek ioctl_tests_recv_0(sp[0]); 461de503941SPawel Jakub Dawidek CHECK(waitpid(pid, NULL, 0) == pid); 462de503941SPawel Jakub Dawidek CHECK(close(sp[0]) == 0); 463de503941SPawel Jakub Dawidek } 464de503941SPawel Jakub Dawidek 465de503941SPawel Jakub Dawidek exit(0); 466de503941SPawel Jakub Dawidek } 467