xref: /freebsd/tools/regression/priv/main.c (revision f0a75d274af375d15b97b830966b99a02b7db911)
1 /*-
2  * Copyright (c) 2006 nCircle Network Security, Inc.
3  * All rights reserved.
4  *
5  * This software was developed by Robert N. M. Watson for the TrustedBSD
6  * Project under contract to nCircle Network Security, Inc.
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 AUTHOR 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 AUTHOR, NCIRCLE NETWORK SECURITY,
21  * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 /*
33  * Privilege test framework.  Each test is encapsulated on a .c file exporting
34  * a function that implements the test.  Each test is run from its own child
35  * process, and they are run in sequence one at a time.
36  */
37 
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <sys/wait.h>
41 
42 #include <err.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 
48 #include "main.h"
49 
50 /*
51  * Common routines used across many tests.
52  */
53 void
54 assert_root(void)
55 {
56 
57 	if (getuid() != UID_ROOT || geteuid() != UID_ROOT)
58 		err(-1, "must be run as root");
59 }
60 
61 void
62 setup_file(char *fpathp, uid_t uid, gid_t gid, mode_t mode)
63 {
64 	int fd;
65 
66 	strcpy(fpathp, "/tmp/priv.XXXXXXXXXXX");
67 	fd = mkstemp(fpathp);
68 	if (fd < 0)
69 		err(-1, "mkstemp");
70 
71 	if (fchown(fd, uid, gid) < 0)
72 		err(-1, "fchown(%s, %d, %d)", fpathp, uid, gid);
73 
74 	if (fchmod(fd, mode) < 0)
75 		err(-1, "chmod(%s, 0%o)", fpathp, mode);
76 
77 	close(fd);
78 }
79 
80 /*
81  * When downgrading privileges, set the gid before the uid; when upgrading,
82  * set uid before gid.
83  */
84 void
85 set_creds(uid_t uid, gid_t gid)
86 {
87 
88 	if (setegid(gid) < 0)
89 		err(-1, "setegid(%d)", gid);
90 	if (seteuid(uid) < 0)
91 		err(-1, "seteuid(%d)", uid);
92 }
93 
94 void
95 set_euid(uid_t uid)
96 {
97 
98 	if (seteuid(uid) < 0)
99 		err(-1, "seteuid(%d)", uid);
100 }
101 
102 void
103 restore_creds(void)
104 {
105 
106 	if (seteuid(UID_ROOT) < 0)
107 		err(-1, "seteuid(%d)", UID_ROOT);
108 	if (setegid(GID_WHEEL) < 0)
109 		err(-1, "setegid(%d)", GID_WHEEL);
110 }
111 
112 /*
113  * Execute tests in a child process so they don't contaminate each other,
114  * especially with regard to file descriptors, credentials, working
115  * directories, and chroot status.
116  */
117 static void
118 run(const char *funcname, void (*func)(void))
119 {
120 	pid_t childpid, pid;
121 
122 	printf("running %s\n", funcname);
123 	fflush(stdout);
124 	fflush(stderr);
125 	childpid = fork();
126 	if (childpid == -1)
127 		err(-1, "test %s unable to fork", funcname);
128 	if (childpid == 0) {
129 		setprogname(funcname);
130 		func();
131 		fflush(stdout);
132 		fflush(stderr);
133 		exit(0);
134 	} else {
135 		while (1) {
136 			pid = waitpid(childpid, NULL, 0);
137 			if (pid == -1)
138 				warn("waitpid %s", funcname);
139 			if (pid == childpid)
140 				break;
141 		}
142 	}
143 	fflush(stdout);
144 	fflush(stderr);
145 }
146 
147 int
148 main(int argc, char *argv[])
149 {
150 
151 	run("priv_acct", priv_acct);
152 	run("priv_adjtime", priv_adjtime);
153 	run("priv_clock_settime", priv_clock_settime);
154 	run("priv_io", priv_io);
155 	run("priv_kenv_set", priv_kenv_set);
156 	run("priv_kenv_unset", priv_kenv_unset);
157 	run("priv_proc_setlogin", priv_proc_setlogin);
158 	run("priv_proc_setrlimit", priv_proc_setrlimit);
159 	run("priv_sched_rtprio", priv_sched_rtprio);
160 	run("priv_sched_setpriority", priv_sched_setpriority);
161 	run("priv_settimeofday", priv_settimeofday);
162 	run("priv_sysctl_write", priv_sysctl_write);
163 	run("priv_vfs_admin", priv_vfs_admin);
164 	run("priv_vfs_chown", priv_vfs_chown);
165 	run("priv_vfs_chroot", priv_vfs_chroot);
166 	run("priv_vfs_clearsugid", priv_vfs_clearsugid);
167 	run("priv_vfs_extattr_system", priv_vfs_extattr_system);
168 	run("priv_vfs_fhopen", priv_vfs_fhopen);
169 	run("priv_vfs_fhstat", priv_vfs_fhstat);
170 	run("priv_vfs_fhstatfs", priv_vfs_fhstatfs);
171 	run("priv_vfs_generation", priv_vfs_generation);
172 	run("priv_vfs_getfh", priv_vfs_getfh);
173 	run("priv_vfs_read", priv_vfs_read);
174 	run("priv_vfs_setgid", priv_vfs_setgid);
175 	run("priv_vfs_stickyfile", priv_vfs_stickyfile);
176 	run("priv_vfs_write", priv_vfs_write);
177 	run("priv_vm_madv_protect", priv_vm_madv_protect);
178 	run("priv_vm_mlock", priv_vm_mlock);
179 	run("priv_vm_munlock", priv_vm_munlock);
180 
181 	run("test_utimes", test_utimes);
182 
183 	return (0);
184 }
185