1 /* $NetBSD: t_unpriv.c,v 1.11 2014/08/29 17:39:18 gson Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/stat.h> 30 #include <sys/time.h> 31 32 #include <atf-c.h> 33 #include <libgen.h> 34 #include <limits.h> 35 #include <unistd.h> 36 37 #include <rump/rump_syscalls.h> 38 #include <rump/rump.h> 39 40 #include "../common/h_fsmacros.h" 41 #include "../../h_macros.h" 42 43 #define USES_OWNER \ 44 if (FSTYPE_MSDOS(tc)) \ 45 atf_tc_skip("owner not supported by file system") 46 47 static void 48 owner(const atf_tc_t *tc, const char *mp) 49 { 50 51 USES_OWNER; 52 53 FSTEST_ENTER(); 54 55 rump_pub_lwproc_rfork(RUMP_RFCFDG); 56 if (rump_sys_setuid(1) == -1) 57 atf_tc_fail_errno("setuid"); 58 if (FSTYPE_ZFS(tc)) 59 atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 60 if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM) 61 atf_tc_fail_errno("chown"); 62 if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM) 63 atf_tc_fail_errno("chmod"); 64 rump_pub_lwproc_releaselwp(); 65 66 if (rump_sys_chown(".", 1, -1) == -1) 67 atf_tc_fail_errno("chown"); 68 69 rump_pub_lwproc_rfork(RUMP_RFCFDG); 70 if (rump_sys_setuid(1) == -1) 71 atf_tc_fail_errno("setuid"); 72 if (rump_sys_chown(".", 1, -1) == -1) 73 atf_tc_fail_errno("chown"); 74 if (rump_sys_chmod(".", 0000) == -1) 75 atf_tc_fail_errno("chmod"); 76 rump_pub_lwproc_releaselwp(); 77 78 FSTEST_EXIT(); 79 } 80 81 static void 82 dirperms(const atf_tc_t *tc, const char *mp) 83 { 84 char name[] = "dir.test/file.test"; 85 char *dir = dirname(name); 86 int fd; 87 88 if (FSTYPE_SYSVBFS(tc)) 89 atf_tc_skip("directories not supported by file system"); 90 91 FSTEST_ENTER(); 92 93 if (rump_sys_mkdir(dir, 0777) == -1) 94 atf_tc_fail_errno("mkdir"); 95 96 rump_pub_lwproc_rfork(RUMP_RFCFDG); 97 if (rump_sys_setuid(1) == -1) 98 atf_tc_fail_errno("setuid"); 99 if (FSTYPE_ZFS(tc)) 100 atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 101 if (rump_sys_open(name, O_RDWR|O_CREAT, 0666) != -1 || errno != EACCES) 102 atf_tc_fail_errno("open"); 103 rump_pub_lwproc_releaselwp(); 104 105 if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 106 atf_tc_fail_errno("open"); 107 if (rump_sys_close(fd) == -1) 108 atf_tc_fail_errno("close"); 109 110 rump_pub_lwproc_rfork(RUMP_RFCFDG); 111 if (rump_sys_setuid(1) == -1) 112 atf_tc_fail_errno("setuid"); 113 if (rump_sys_unlink(name) != -1 || errno != EACCES) 114 atf_tc_fail_errno("unlink"); 115 rump_pub_lwproc_releaselwp(); 116 117 if (rump_sys_unlink(name) == -1) 118 atf_tc_fail_errno("unlink"); 119 120 if (rump_sys_rmdir(dir) == -1) 121 atf_tc_fail_errno("rmdir"); 122 123 FSTEST_EXIT(); 124 } 125 126 static void 127 times(const atf_tc_t *tc, const char *mp) 128 { 129 const char *name = "file.test"; 130 int fd; 131 unsigned int i, j; 132 struct timeval tmv[2]; 133 static struct timeval tmvs[] = { 134 { QUAD_MIN, 0 }, 135 { 0, 0 }, 136 { QUAD_MAX, 999999 } 137 }; 138 139 FSTEST_ENTER(); 140 141 if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 142 atf_tc_fail_errno("open"); 143 if (rump_sys_close(fd) == -1) 144 atf_tc_fail_errno("close"); 145 146 rump_pub_lwproc_rfork(RUMP_RFCFDG); 147 if (rump_sys_setuid(1) == -1) 148 atf_tc_fail_errno("setuid"); 149 if (FSTYPE_ZFS(tc)) 150 atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 151 if (rump_sys_utimes(name, NULL) != -1 || errno != EACCES) 152 atf_tc_fail_errno("utimes"); 153 rump_pub_lwproc_releaselwp(); 154 155 if (rump_sys_utimes(name, NULL) == -1) 156 atf_tc_fail_errno("utimes"); 157 158 for (i = 0; i < sizeof(tmvs) / sizeof(tmvs[0]); i++) { 159 for (j = 0; j < sizeof(tmvs) / sizeof(tmvs[0]); j++) { 160 tmv[0] = tmvs[i]; 161 tmv[1] = tmvs[j]; 162 rump_pub_lwproc_rfork(RUMP_RFCFDG); 163 if (rump_sys_setuid(1) == -1) 164 atf_tc_fail_errno("setuid"); 165 if (rump_sys_utimes(name, tmv) != -1 || errno != EPERM) 166 atf_tc_fail_errno("utimes"); 167 rump_pub_lwproc_releaselwp(); 168 169 if (rump_sys_utimes(name, tmv) == -1) 170 atf_tc_fail_errno("utimes"); 171 } 172 } 173 174 if (rump_sys_unlink(name) == -1) 175 atf_tc_fail_errno("unlink"); 176 177 FSTEST_EXIT(); 178 } 179 180 static void 181 flags(const atf_tc_t *tc, const char *mp) 182 { 183 const char *name = "file.test"; 184 int fd, fflags; 185 struct stat st; 186 187 FSTEST_ENTER(); 188 189 if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 190 atf_tc_fail_errno("open"); 191 if (rump_sys_close(fd) == -1) 192 atf_tc_fail_errno("close"); 193 194 if (rump_sys_stat(name, &st) == -1) 195 atf_tc_fail_errno("stat"); 196 if (FSTYPE_ZFS(tc)) 197 atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 198 if (rump_sys_chflags(name, st.st_flags) == -1) { 199 if (errno == EOPNOTSUPP) 200 atf_tc_skip("file flags not supported by file system"); 201 atf_tc_fail_errno("chflags"); 202 } 203 204 fflags = st.st_flags | UF_IMMUTABLE; 205 206 rump_pub_lwproc_rfork(RUMP_RFCFDG); 207 if (rump_sys_setuid(1) == -1) 208 atf_tc_fail_errno("setuid"); 209 fflags |= UF_IMMUTABLE; 210 if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM) 211 atf_tc_fail_errno("chflags"); 212 rump_pub_lwproc_releaselwp(); 213 214 if (rump_sys_chflags(name, fflags) == -1) 215 atf_tc_fail_errno("chflags"); 216 217 fflags &= ~UF_IMMUTABLE; 218 if (rump_sys_chflags(name, fflags) == -1) 219 atf_tc_fail_errno("chflags"); 220 221 if (rump_sys_unlink(name) == -1) 222 atf_tc_fail_errno("unlink"); 223 224 FSTEST_EXIT(); 225 } 226 227 ATF_TC_FSAPPLY(owner, "owner unprivileged checks"); 228 ATF_TC_FSAPPLY(dirperms, "directory permission checks"); 229 ATF_TC_FSAPPLY(times, "time set checks"); 230 ATF_TC_FSAPPLY(flags, "file flags checks"); 231 232 ATF_TP_ADD_TCS(tp) 233 { 234 235 ATF_TP_FSAPPLY(owner); 236 ATF_TP_FSAPPLY(dirperms); 237 ATF_TP_FSAPPLY(times); 238 ATF_TP_FSAPPLY(flags); 239 240 return atf_no_error(); 241 } 242