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