xref: /minix3/tests/fs/vfs/t_unpriv.c (revision 0b98e8aad89f2bd4ba80b523d73cf29e9dd82ce1)
1 /*	$NetBSD: t_unpriv.c,v 1.10 2013/03/16 05:45:37 jmmv 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 (FSTYPE_ZFS(tc))
58 		atf_tc_expect_fail("PR kern/47656: Test known to be broken");
59         if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM)
60 		atf_tc_fail_errno("chown");
61         if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM)
62                 atf_tc_fail_errno("chmod");
63 	rump_pub_lwproc_releaselwp();
64 
65 	if (rump_sys_chown(".", 1, -1) == -1)
66 		atf_tc_fail_errno("chown");
67 
68 	rump_pub_lwproc_rfork(RUMP_RFCFDG);
69 	if (rump_sys_setuid(1) == -1)
70 		atf_tc_fail_errno("setuid");
71         if (rump_sys_chown(".", 1, -1) == -1)
72 		atf_tc_fail_errno("chown");
73         if (rump_sys_chmod(".", 0000) == -1)
74                 atf_tc_fail_errno("chmod");
75 	rump_pub_lwproc_releaselwp();
76 
77 	FSTEST_EXIT();
78 }
79 
80 static void
81 dirperms(const atf_tc_t *tc, const char *mp)
82 {
83 	char name[] = "dir.test/file.test";
84 	char *dir = dirname(name);
85 	int fd;
86 
87 	if (FSTYPE_SYSVBFS(tc))
88 		atf_tc_skip("directories not supported by file system");
89 
90 	FSTEST_ENTER();
91 
92 	if (rump_sys_mkdir(dir, 0777) == -1)
93 		atf_tc_fail_errno("mkdir");
94 
95 	rump_pub_lwproc_rfork(RUMP_RFCFDG);
96 	if (rump_sys_setuid(1) == -1)
97 		atf_tc_fail_errno("setuid");
98 	if (FSTYPE_ZFS(tc))
99 		atf_tc_expect_fail("PR kern/47656: Test known to be broken");
100         if (rump_sys_open(name, O_RDWR|O_CREAT, 0666) != -1 || errno != EACCES)
101 		atf_tc_fail_errno("open");
102 	rump_pub_lwproc_releaselwp();
103 
104 	if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1)
105 		atf_tc_fail_errno("open");
106 	if (rump_sys_close(fd) == -1)
107 		atf_tc_fail_errno("close");
108 
109 	rump_pub_lwproc_rfork(RUMP_RFCFDG);
110 	if (rump_sys_setuid(1) == -1)
111 		atf_tc_fail_errno("setuid");
112         if (rump_sys_unlink(name) != -1 || errno != EACCES)
113 		atf_tc_fail_errno("unlink");
114 	rump_pub_lwproc_releaselwp();
115 
116         if (rump_sys_unlink(name) == -1)
117 		atf_tc_fail_errno("unlink");
118 
119 	if (rump_sys_rmdir(dir) == -1)
120 		atf_tc_fail_errno("rmdir");
121 
122 	FSTEST_EXIT();
123 }
124 
125 static void
126 times(const atf_tc_t *tc, const char *mp)
127 {
128 	const char *name = "file.test";
129 	int fd;
130 	struct timeval tmv[2];
131 
132 	FSTEST_ENTER();
133 
134 	if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1)
135 		atf_tc_fail_errno("open");
136 	if (rump_sys_close(fd) == -1)
137 		atf_tc_fail_errno("close");
138 
139 	rump_pub_lwproc_rfork(RUMP_RFCFDG);
140 	if (rump_sys_setuid(1) == -1)
141 		atf_tc_fail_errno("setuid");
142 	if (FSTYPE_ZFS(tc))
143 		atf_tc_expect_fail("PR kern/47656: Test known to be broken");
144 	if (rump_sys_utimes(name, NULL) != -1 || errno != EACCES)
145 		atf_tc_fail_errno("utimes");
146 	rump_pub_lwproc_releaselwp();
147 
148 	if (rump_sys_utimes(name, NULL) == -1)
149 		atf_tc_fail_errno("utimes");
150 
151 	rump_pub_lwproc_rfork(RUMP_RFCFDG);
152 	if (rump_sys_setuid(1) == -1)
153 		atf_tc_fail_errno("setuid");
154 	if (rump_sys_utimes(name, tmv) != -1 || errno != EPERM)
155 		atf_tc_fail_errno("utimes");
156 	rump_pub_lwproc_releaselwp();
157 
158 	if (rump_sys_utimes(name, tmv) == -1)
159 		atf_tc_fail_errno("utimes");
160 
161 	if (rump_sys_unlink(name) == -1)
162 		atf_tc_fail_errno("unlink");
163 
164 	FSTEST_EXIT();
165 }
166 
167 static void
168 flags(const atf_tc_t *tc, const char *mp)
169 {
170 	const char *name = "file.test";
171 	int fd, fflags;
172 	struct stat st;
173 
174 	FSTEST_ENTER();
175 
176 	if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1)
177 		atf_tc_fail_errno("open");
178 	if (rump_sys_close(fd) == -1)
179 		atf_tc_fail_errno("close");
180 
181 	if (rump_sys_stat(name, &st) == -1)
182 		atf_tc_fail_errno("stat");
183 	if (FSTYPE_ZFS(tc))
184 		atf_tc_expect_fail("PR kern/47656: Test known to be broken");
185 	if (rump_sys_chflags(name, st.st_flags) == -1) {
186 		if (errno == EOPNOTSUPP)
187 			atf_tc_skip("file flags not supported by file system");
188 		atf_tc_fail_errno("chflags");
189 	}
190 
191 	fflags = st.st_flags | UF_IMMUTABLE;
192 
193 	rump_pub_lwproc_rfork(RUMP_RFCFDG);
194 	if (rump_sys_setuid(1) == -1)
195 		atf_tc_fail_errno("setuid");
196 	fflags |= UF_IMMUTABLE;
197 	if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM)
198 		atf_tc_fail_errno("chflags");
199 	rump_pub_lwproc_releaselwp();
200 
201 	if (rump_sys_chflags(name, fflags) == -1)
202 		atf_tc_fail_errno("chflags");
203 
204 	fflags &= ~UF_IMMUTABLE;
205 	if (rump_sys_chflags(name, fflags) == -1)
206 		atf_tc_fail_errno("chflags");
207 
208 	if (rump_sys_unlink(name) == -1)
209 		atf_tc_fail_errno("unlink");
210 
211 	FSTEST_EXIT();
212 }
213 
214 ATF_TC_FSAPPLY(owner, "owner unprivileged checks");
215 ATF_TC_FSAPPLY(dirperms, "directory permission checks");
216 ATF_TC_FSAPPLY(times, "time set checks");
217 ATF_TC_FSAPPLY(flags, "file flags checks");
218 
219 ATF_TP_ADD_TCS(tp)
220 {
221 
222 	ATF_TP_FSAPPLY(owner);
223 	ATF_TP_FSAPPLY(dirperms);
224 	ATF_TP_FSAPPLY(times);
225 	ATF_TP_FSAPPLY(flags);
226 
227 	return atf_no_error();
228 }
229