1 /*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/capsicum.h> 32 #include <sys/procdesc.h> 33 #include <sys/wait.h> 34 35 #include <err.h> 36 #include <errno.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <unistd.h> 40 41 #include "misc.h" 42 43 int 44 main(void) 45 { 46 unsigned int mode; 47 pid_t pid; 48 int pfd; 49 50 printf("1..27\n"); 51 52 mode = 666; 53 CHECK(cap_getmode(&mode) == 0); 54 /* If cap_getmode() succeeded mode should be modified. */ 55 CHECK(mode != 666); 56 /* We are not in capability mode. */ 57 CHECK(mode == 0); 58 59 /* Expect EFAULT. */ 60 errno = 0; 61 CHECK(cap_getmode(NULL) == -1); 62 CHECK(errno == EFAULT); 63 errno = 0; 64 CHECK(cap_getmode((void *)(uintptr_t)0xdeadc0de) == -1); 65 CHECK(errno == EFAULT); 66 67 /* If parent is not in capability mode, child after fork() also won't be. */ 68 pid = fork(); 69 switch (pid) { 70 case -1: 71 err(1, "fork() failed"); 72 case 0: 73 mode = 666; 74 CHECK(cap_getmode(&mode) == 0); 75 /* If cap_getmode() succeeded mode should be modified. */ 76 CHECK(mode != 666); 77 /* We are not in capability mode. */ 78 CHECK(mode == 0); 79 exit(0); 80 default: 81 if (waitpid(pid, NULL, 0) == -1) 82 err(1, "waitpid() failed"); 83 } 84 85 /* If parent is not in capability mode, child after pdfork() also won't be. */ 86 pid = pdfork(&pfd, 0); 87 switch (pid) { 88 case -1: 89 err(1, "pdfork() failed"); 90 case 0: 91 mode = 666; 92 CHECK(cap_getmode(&mode) == 0); 93 /* If cap_getmode() succeeded mode should be modified. */ 94 CHECK(mode != 666); 95 /* We are not in capability mode. */ 96 CHECK(mode == 0); 97 exit(0); 98 default: 99 if (pdwait(pfd) == -1) 100 err(1, "pdwait() failed"); 101 close(pfd); 102 } 103 104 /* In capability mode... */ 105 106 CHECK(cap_enter() == 0); 107 108 mode = 666; 109 CHECK(cap_getmode(&mode) == 0); 110 /* If cap_getmode() succeeded mode should be modified. */ 111 CHECK(mode != 666); 112 /* We are in capability mode. */ 113 CHECK(mode == 1); 114 115 /* Expect EFAULT. */ 116 errno = 0; 117 CHECK(cap_getmode(NULL) == -1); 118 CHECK(errno == EFAULT); 119 errno = 0; 120 CHECK(cap_getmode((void *)(uintptr_t)0xdeadc0de) == -1); 121 CHECK(errno == EFAULT); 122 123 /* If parent is in capability mode, child after fork() also will be. */ 124 pid = fork(); 125 switch (pid) { 126 case -1: 127 err(1, "fork() failed"); 128 case 0: 129 mode = 666; 130 CHECK(cap_getmode(&mode) == 0); 131 /* If cap_getmode() succeeded mode should be modified. */ 132 CHECK(mode != 666); 133 /* We are in capability mode. */ 134 CHECK(mode == 1); 135 exit(0); 136 default: 137 /* 138 * wait(2) and friends are not permitted in the capability mode, 139 * so we can only just wait for a while. 140 */ 141 sleep(1); 142 } 143 144 /* If parent is in capability mode, child after pdfork() also will be. */ 145 pid = pdfork(&pfd, 0); 146 switch (pid) { 147 case -1: 148 err(1, "pdfork() failed"); 149 case 0: 150 mode = 666; 151 CHECK(cap_getmode(&mode) == 0); 152 /* If cap_getmode() succeeded mode should be modified. */ 153 CHECK(mode != 666); 154 /* We are in capability mode. */ 155 CHECK(mode == 1); 156 exit(0); 157 default: 158 if (pdwait(pfd) == -1) 159 err(1, "pdwait() failed"); 160 close(pfd); 161 } 162 163 exit(0); 164 } 165