1 /* $NetBSD: t_unpriv.c,v 1.9 2012/04/04 18:53:34 njoly 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 <unistd.h> 35 36 #include <rump/rump_syscalls.h> 37 #include <rump/rump.h> 38 39 #include "../common/h_fsmacros.h" 40 #include "../../h_macros.h" 41 42 #define USES_OWNER \ 43 if (FSTYPE_MSDOS(tc)) \ 44 atf_tc_skip("owner not supported by file system") 45 46 static void 47 owner(const atf_tc_t *tc, const char *mp) 48 { 49 50 USES_OWNER; 51 52 FSTEST_ENTER(); 53 54 rump_pub_lwproc_rfork(RUMP_RFCFDG); 55 if (rump_sys_setuid(1) == -1) 56 atf_tc_fail_errno("setuid"); 57 if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM) 58 atf_tc_fail_errno("chown"); 59 if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM) 60 atf_tc_fail_errno("chmod"); 61 rump_pub_lwproc_releaselwp(); 62 63 if (rump_sys_chown(".", 1, -1) == -1) 64 atf_tc_fail_errno("chown"); 65 66 rump_pub_lwproc_rfork(RUMP_RFCFDG); 67 if (rump_sys_setuid(1) == -1) 68 atf_tc_fail_errno("setuid"); 69 if (rump_sys_chown(".", 1, -1) == -1) 70 atf_tc_fail_errno("chown"); 71 if (rump_sys_chmod(".", 0000) == -1) 72 atf_tc_fail_errno("chmod"); 73 rump_pub_lwproc_releaselwp(); 74 75 FSTEST_EXIT(); 76 } 77 78 static void 79 dirperms(const atf_tc_t *tc, const char *mp) 80 { 81 char name[] = "dir.test/file.test"; 82 char *dir = dirname(name); 83 int fd; 84 85 if (FSTYPE_SYSVBFS(tc)) 86 atf_tc_skip("directories not supported by file system"); 87 88 FSTEST_ENTER(); 89 90 if (rump_sys_mkdir(dir, 0777) == -1) 91 atf_tc_fail_errno("mkdir"); 92 93 rump_pub_lwproc_rfork(RUMP_RFCFDG); 94 if (rump_sys_setuid(1) == -1) 95 atf_tc_fail_errno("setuid"); 96 if (rump_sys_open(name, O_RDWR|O_CREAT, 0666) != -1 || errno != EACCES) 97 atf_tc_fail_errno("open"); 98 rump_pub_lwproc_releaselwp(); 99 100 if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 101 atf_tc_fail_errno("open"); 102 if (rump_sys_close(fd) == -1) 103 atf_tc_fail_errno("close"); 104 105 rump_pub_lwproc_rfork(RUMP_RFCFDG); 106 if (rump_sys_setuid(1) == -1) 107 atf_tc_fail_errno("setuid"); 108 if (rump_sys_unlink(name) != -1 || errno != EACCES) 109 atf_tc_fail_errno("unlink"); 110 rump_pub_lwproc_releaselwp(); 111 112 if (rump_sys_unlink(name) == -1) 113 atf_tc_fail_errno("unlink"); 114 115 if (rump_sys_rmdir(dir) == -1) 116 atf_tc_fail_errno("rmdir"); 117 118 FSTEST_EXIT(); 119 } 120 121 static void 122 times(const atf_tc_t *tc, const char *mp) 123 { 124 const char *name = "file.test"; 125 int fd; 126 struct timeval tmv[2]; 127 128 FSTEST_ENTER(); 129 130 if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 131 atf_tc_fail_errno("open"); 132 if (rump_sys_close(fd) == -1) 133 atf_tc_fail_errno("close"); 134 135 rump_pub_lwproc_rfork(RUMP_RFCFDG); 136 if (rump_sys_setuid(1) == -1) 137 atf_tc_fail_errno("setuid"); 138 if (rump_sys_utimes(name, NULL) != -1 || errno != EACCES) 139 atf_tc_fail_errno("utimes"); 140 rump_pub_lwproc_releaselwp(); 141 142 if (rump_sys_utimes(name, NULL) == -1) 143 atf_tc_fail_errno("utimes"); 144 145 rump_pub_lwproc_rfork(RUMP_RFCFDG); 146 if (rump_sys_setuid(1) == -1) 147 atf_tc_fail_errno("setuid"); 148 if (rump_sys_utimes(name, tmv) != -1 || errno != EPERM) 149 atf_tc_fail_errno("utimes"); 150 rump_pub_lwproc_releaselwp(); 151 152 if (rump_sys_utimes(name, tmv) == -1) 153 atf_tc_fail_errno("utimes"); 154 155 if (rump_sys_unlink(name) == -1) 156 atf_tc_fail_errno("unlink"); 157 158 FSTEST_EXIT(); 159 } 160 161 static void 162 flags(const atf_tc_t *tc, const char *mp) 163 { 164 const char *name = "file.test"; 165 int fd, fflags; 166 struct stat st; 167 168 FSTEST_ENTER(); 169 170 if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 171 atf_tc_fail_errno("open"); 172 if (rump_sys_close(fd) == -1) 173 atf_tc_fail_errno("close"); 174 175 if (rump_sys_stat(name, &st) == -1) 176 atf_tc_fail_errno("stat"); 177 if (rump_sys_chflags(name, st.st_flags) == -1) { 178 if (errno == EOPNOTSUPP) 179 atf_tc_skip("file flags not supported by file system"); 180 atf_tc_fail_errno("chflags"); 181 } 182 183 fflags = st.st_flags | UF_IMMUTABLE; 184 185 rump_pub_lwproc_rfork(RUMP_RFCFDG); 186 if (rump_sys_setuid(1) == -1) 187 atf_tc_fail_errno("setuid"); 188 fflags |= UF_IMMUTABLE; 189 if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM) 190 atf_tc_fail_errno("chflags"); 191 rump_pub_lwproc_releaselwp(); 192 193 if (rump_sys_chflags(name, fflags) == -1) 194 atf_tc_fail_errno("chflags"); 195 196 fflags &= ~UF_IMMUTABLE; 197 if (rump_sys_chflags(name, fflags) == -1) 198 atf_tc_fail_errno("chflags"); 199 200 if (rump_sys_unlink(name) == -1) 201 atf_tc_fail_errno("unlink"); 202 203 FSTEST_EXIT(); 204 } 205 206 ATF_TC_FSAPPLY(owner, "owner unprivileged checks"); 207 ATF_TC_FSAPPLY(dirperms, "directory permission checks"); 208 ATF_TC_FSAPPLY(times, "time set checks"); 209 ATF_TC_FSAPPLY(flags, "file flags checks"); 210 211 ATF_TP_ADD_TCS(tp) 212 { 213 214 ATF_TP_FSAPPLY(owner); 215 ATF_TP_FSAPPLY(dirperms); 216 ATF_TP_FSAPPLY(times); 217 ATF_TP_FSAPPLY(flags); 218 219 return atf_no_error(); 220 } 221