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