1 /*- 2 * Copyright (c) 2006 nCircle Network Security, Inc. 3 * Copyright (c) 2007 Robert N. M. Watson 4 * All rights reserved. 5 * 6 * This software was developed by Robert N. M. Watson for the TrustedBSD 7 * Project under contract to nCircle Network Security, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, 22 * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * This is a joint test of both the read and write privileges with respect to 33 * discretionary file system access control (permissions). Only permissions, 34 * not ACL semantics, and only privilege-related checks are performed. 35 */ 36 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 40 #include <err.h> 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <unistd.h> 46 47 #include "main.h" 48 49 static char fpath_none[1024]; 50 static char fpath_read[1024]; 51 static char fpath_write[1024]; 52 static char fpath_readwrite[1024]; 53 54 static int fpath_none_initialized; 55 static int fpath_read_initialized; 56 static int fpath_write_initialized; 57 static int fpath_readwrite_initialized; 58 59 static void 60 try_io(const char *label, const char *fpathp, int asroot, int injail, 61 int flags, int expected_error, int expected_errno) 62 { 63 int fd; 64 65 fd = open(fpathp, flags); 66 if (fd < 0) { 67 if (expected_error != -1) 68 warnx("%s(%s, %s): expected (%d, %d) got (-1, %d)", 69 label, asroot ? "root" : "!root", injail ? "jail" 70 : "!jail", expected_error, expected_errno, errno); 71 } else { 72 if (expected_error == -1) 73 warnx("%s(%s, %s): expected (%d, %d) got 0", label, 74 asroot ? "root" : "!root", injail ? "jail" : 75 "!jail", expected_error, expected_errno); 76 (void)close(fd); 77 } 78 } 79 80 int 81 priv_vfs_readwrite_fowner_setup(int asroot, int injail, struct test *test) 82 { 83 84 setup_file("priv_vfs_readwrite_fowner_setup: fpath_none", fpath_none, 85 asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0000); 86 fpath_none_initialized = 1; 87 setup_file("priv_vfs_readwrite_fowner_setup: fpath_read", fpath_read, 88 asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0400); 89 fpath_read_initialized = 1; 90 setup_file("priv_vfs_readwrite_fowner_setup: fpath_write", 91 fpath_write, asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0200); 92 fpath_write_initialized = 1; 93 setup_file("priv_vfs_readwrite_fowner_setup: fpath_readwrite", 94 fpath_readwrite, asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0600); 95 fpath_readwrite_initialized = 1; 96 return (0); 97 } 98 99 int 100 priv_vfs_readwrite_fgroup_setup(int asroot, int injail, struct test *test) 101 { 102 103 setup_file("priv_vfs_readwrite_fgroup_setup: fpath_none", fpath_none, 104 UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 0000); 105 fpath_none_initialized = 1; 106 setup_file("priv_vfs_readwrite_fgroup_setup: fpath_read", fpath_read, 107 UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 0040); 108 fpath_read_initialized = 1; 109 setup_file("priv_vfs_readwrite_fgroup_setup: fpath_write", 110 fpath_write, UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 0020); 111 fpath_write_initialized = 1; 112 setup_file("priv_vfs_readwrite_fgroup_setup: fpath_readwrite", 113 fpath_readwrite, UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 114 0060); 115 fpath_readwrite_initialized = 1; 116 return (0); 117 } 118 119 int 120 priv_vfs_readwrite_fother_setup(int asroot, int injail, struct test *test) 121 { 122 123 setup_file("priv_vfs_readwrite_fother_setup: fpath_none", fpath_none, 124 UID_OTHER, GID_OTHER, 0000); 125 fpath_none_initialized = 1; 126 setup_file("priv_vfs_readwrite_fother_setup: fpath_read", fpath_read, 127 UID_OTHER, GID_OTHER, 0004); 128 fpath_read_initialized = 1; 129 setup_file("priv_vfs_readwrite_fother_setup: fpath_write", 130 fpath_write, UID_OTHER, GID_OTHER, 0002); 131 fpath_write_initialized = 1; 132 setup_file("priv_vfs_readwrite_fother_setup: fpath_readwrite", 133 fpath_readwrite, UID_OTHER, GID_OTHER, 0006); 134 fpath_readwrite_initialized = 1; 135 return (0); 136 } 137 138 void 139 priv_vfs_readwrite_fowner(int asroot, int injail, struct test *test) 140 { 141 142 try_io("priv_vfs_readwrite_fowner(none, O_RDONLY)", fpath_none, 143 asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); 144 try_io("priv_vfs_readwrite_fowner(none, O_WRONLY)", fpath_none, 145 asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); 146 try_io("priv_vfs_readwrite_fowner(none, O_RDWR)", fpath_none, 147 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 148 149 try_io("priv_vfs_readwrite_fowner(read, O_RDONLY)", fpath_read, 150 asroot, injail, O_RDONLY, 0, 0); 151 try_io("priv_vfs_readwrite_fowner(read, O_WRONLY)", fpath_read, 152 asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); 153 try_io("priv_vfs_readwrite_fowner(read, O_RDWR)", fpath_read, 154 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 155 156 try_io("priv_vfs_readwrite_fowner(write, O_RDONLY)", fpath_write, 157 asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); 158 try_io("priv_vfs_readwrite_fowner(write, O_WRONLY)", fpath_write, 159 asroot, injail, O_WRONLY, 0, 0); 160 try_io("priv_vfs_readwrite_fowner(write, O_RDWR)", fpath_write, 161 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 162 163 try_io("priv_vfs_readwrite_fowner(write, O_RDONLY)", fpath_readwrite, 164 asroot, injail, O_RDONLY, 0, 0); 165 try_io("priv_vfs_readwrite_fowner(write, O_WRONLY)", fpath_readwrite, 166 asroot, injail, O_WRONLY, 0, 0); 167 try_io("priv_vfs_readwrite_fowner(write, O_RDWR)", fpath_readwrite, 168 asroot, injail, O_RDWR, 0, 0); 169 } 170 171 void 172 priv_vfs_readwrite_fgroup(int asroot, int injail, struct test *test) 173 { 174 175 try_io("priv_vfs_readwrite_fgroup(none, O_RDONLY)", fpath_none, 176 asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); 177 try_io("priv_vfs_readwrite_fgroup(none, O_WRONLY)", fpath_none, 178 asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); 179 try_io("priv_vfs_readwrite_fgroup(none, O_RDWR)", fpath_none, 180 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 181 182 try_io("priv_vfs_readwrite_fgroup(read, O_RDONLY)", fpath_read, 183 asroot, injail, O_RDONLY, 0, 0); 184 try_io("priv_vfs_readwrite_fgroup(read, O_WRONLY)", fpath_read, 185 asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); 186 try_io("priv_vfs_readwrite_fgroup(read, O_RDWR)", fpath_read, 187 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 188 189 try_io("priv_vfs_readwrite_fgroup(write, O_RDONLY)", fpath_write, 190 asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); 191 try_io("priv_vfs_readwrite_fgroup(write, O_WRONLY)", fpath_write, 192 asroot, injail, O_WRONLY, 0, 0); 193 try_io("priv_vfs_readwrite_fgroup(write, O_RDWR)", fpath_write, 194 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 195 196 try_io("priv_vfs_readwrite_fgroup(write, O_RDONLY)", fpath_readwrite, 197 asroot, injail, O_RDONLY, 0, 0); 198 try_io("priv_vfs_readwrite_fgroup(write, O_WRONLY)", fpath_readwrite, 199 asroot, injail, O_WRONLY, 0, 0); 200 try_io("priv_vfs_readwrite_fgroup(write, O_RDWR)", fpath_readwrite, 201 asroot, injail, O_RDWR, 0, 0); 202 } 203 204 void 205 priv_vfs_readwrite_fother(int asroot, int injail, struct test *test) 206 { 207 208 try_io("priv_vfs_readwrite_fother(none, O_RDONLY)", fpath_none, 209 asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); 210 try_io("priv_vfs_readwrite_fother(none, O_WRONLY)", fpath_none, 211 asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); 212 try_io("priv_vfs_readwrite_fother(none, O_RDWR)", fpath_none, 213 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 214 215 try_io("priv_vfs_readwrite_fother(read, O_RDONLY)", fpath_read, 216 asroot, injail, O_RDONLY, 0, 0); 217 try_io("priv_vfs_readwrite_fother(read, O_WRONLY)", fpath_read, 218 asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); 219 try_io("priv_vfs_readwrite_fother(read, O_RDWR)", fpath_read, 220 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 221 222 try_io("priv_vfs_readwrite_fother(write, O_RDONLY)", fpath_write, 223 asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); 224 try_io("priv_vfs_readwrite_fother(write, O_WRONLY)", fpath_write, 225 asroot, injail, O_WRONLY, 0, 0); 226 try_io("priv_vfs_readwrite_fother(write, O_RDWR)", fpath_write, 227 asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); 228 229 try_io("priv_vfs_readwrite_fother(write, O_RDONLY)", fpath_readwrite, 230 asroot, injail, O_RDONLY, 0, 0); 231 try_io("priv_vfs_readwrite_fother(write, O_WRONLY)", fpath_readwrite, 232 asroot, injail, O_WRONLY, 0, 0); 233 try_io("priv_vfs_readwrite_fother(write, O_RDWR)", fpath_readwrite, 234 asroot, injail, O_RDWR, 0, 0); 235 } 236 237 void 238 priv_vfs_readwrite_cleanup(int asroot, int injail, struct test *test) 239 { 240 241 if (fpath_none_initialized) { 242 (void)unlink(fpath_none); 243 fpath_none_initialized = 0; 244 } 245 if (fpath_read_initialized) { 246 (void)unlink(fpath_read); 247 fpath_read_initialized = 0; 248 } 249 if (fpath_write_initialized) { 250 (void)unlink(fpath_write); 251 fpath_write_initialized = 0; 252 } 253 if (fpath_readwrite_initialized) { 254 (void)unlink(fpath_readwrite); 255 fpath_readwrite_initialized = 0; 256 } 257 } 258