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 * Test that raising current resource limits above hard resource limits
33 * requires privilege. We test three cases:
34 *
35 * - Raise the current above the maximum (privileged).
36 * - Raise the current to the maximum (unprivileged).
37 * - Raise the maximum (privileged).
38 */
39
40 #include <sys/types.h>
41 #include <sys/time.h>
42 #include <sys/resource.h>
43
44 #include <err.h>
45 #include <errno.h>
46 #include <unistd.h>
47
48 #include "main.h"
49
50 static int initialized;
51 static struct rlimit rl_base;
52 static struct rlimit rl_lowered;
53
54 int
priv_proc_setrlimit_setup(int asroot,int injail,struct test * test)55 priv_proc_setrlimit_setup(int asroot, int injail, struct test *test)
56 {
57
58 if (getrlimit(RLIMIT_DATA, &rl_base) < 0) {
59 warn("priv_proc_setrlimit_setup: getrlimit");
60 return (-1);
61 }
62
63 /*
64 * Must lower current and limit to make sure there's room to try to
65 * raise them during tests. Set current lower than max so we can
66 * raise it later also.
67 */
68 rl_lowered = rl_base;
69 rl_lowered.rlim_cur -= 20;
70 rl_lowered.rlim_max -= 10;
71 if (setrlimit(RLIMIT_DATA, &rl_lowered) < 0) {
72 warn("priv_proc_setrlimit_setup: setrlimit");
73 return (-1);
74 }
75 initialized = 1;
76 return (0);
77 }
78
79 /*
80 * Try increasing the maximum limits on the process, which requires
81 * privilege.
82 */
83 void
priv_proc_setrlimit_raisemax(int asroot,int injail,struct test * test)84 priv_proc_setrlimit_raisemax(int asroot, int injail, struct test *test)
85 {
86 struct rlimit rl;
87 int error;
88
89 rl = rl_lowered;
90 rl.rlim_max = rl_base.rlim_max;
91 error = setrlimit(RLIMIT_DATA, &rl);
92 if (asroot && injail)
93 expect("priv_proc_setrlimit_raisemax(asroot, injail)", error,
94 0, 0);
95 if (asroot && !injail)
96 expect("priv_proc_setrlimit_raisemax(asroot, !injail)",
97 error, 0, 0);
98 if (!asroot && injail)
99 expect("priv_proc_setrlimit_raisemax(!asroot, injail)",
100 error, -1, EPERM);
101 if (!asroot && !injail)
102 expect("priv_proc_setrlimit_raisemax(!asroot, !injail)",
103 error, -1, EPERM);
104 }
105
106 /*
107 * Try setting the current limit to the current maximum, which is allowed
108 * without privilege.
109 */
110 void
priv_proc_setrlimit_raisecur_nopriv(int asroot,int injail,struct test * test)111 priv_proc_setrlimit_raisecur_nopriv(int asroot, int injail,
112 struct test *test)
113 {
114 struct rlimit rl;
115 int error;
116
117 rl = rl_lowered;
118 rl.rlim_cur = rl.rlim_max;
119 error = setrlimit(RLIMIT_DATA, &rl);
120 if (asroot && injail)
121 expect("priv_proc_setrlimit_raiscur_nopriv(asroot, injail)",
122 error, 0, 0);
123 if (asroot && !injail)
124 expect("priv_proc_setrlimit_raisecur_nopriv(asroot, !injail)",
125 error, 0, 0);
126 if (!asroot && injail)
127 expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, injail)",
128 error, 0, 0);
129 if (!asroot && !injail)
130 expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, !injail)",
131 error, 0, 0);
132 }
133
134 /*
135 * Try raising the current limits above the maximum, which requires
136 * privilege.
137 */
138 void
priv_proc_setrlimit_raisecur(int asroot,int injail,struct test * test)139 priv_proc_setrlimit_raisecur(int asroot, int injail, struct test *test)
140 {
141 struct rlimit rl;
142 int error;
143
144 rl = rl_lowered;
145 rl.rlim_cur = rl.rlim_max + 10;
146 error = setrlimit(RLIMIT_DATA, &rl);
147 if (asroot && injail)
148 expect("priv_proc_setrlimit_raisecur(asroot, injail)", error,
149 0, 0);
150 if (asroot && !injail)
151 expect("priv_proc_setrlimit_raisecur(asroot, !injail)",
152 error, 0, 0);
153 if (!asroot && injail)
154 expect("priv_proc_setrlimit_raisecur(!asroot, injail)",
155 error, -1, EPERM);
156 if (!asroot && !injail)
157 expect("priv_proc_setrlimit_raisecur(!asroot, !injail)",
158 error, -1, EPERM);
159 }
160
161 void
priv_proc_setrlimit_cleanup(int asroot,int injail,struct test * test)162 priv_proc_setrlimit_cleanup(int asroot, int injail, struct test *test)
163 {
164
165 if (initialized)
166 (void)setrlimit(RLIMIT_DATA, &rl_base);
167 initialized = 0;
168 }
169