svr4_resource.c revision 193014
1/*-
2 * Copyright (c) 1998 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Christos Zoulas.
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 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *        This product includes software developed by the NetBSD
19 *        Foundation, Inc. and its contributors.
20 * 4. Neither the name of The NetBSD Foundation nor the names of its
21 *    contributors may be used to endorse or promote products derived
22 *    from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36/*-
37 * Portions of this software have been derived from software contributed
38 * to the FreeBSD Project by Mark Newton.
39 *
40 * Copyright (c) 1999 Mark Newton
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 *    notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 *    notice, this list of conditions and the following disclaimer in the
50 *    documentation and/or other materials provided with the distribution.
51 * 3. The name of the author may not be used to endorse or promote products
52 *    derived from this software without specific prior written permission
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 * Derived from: $NetBSD: svr4_resource.c,v 1.3 1998/12/13 18:00:52 christos Exp $
66 */
67
68#include <sys/cdefs.h>
69__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_resource.c 193014 2009-05-29 05:58:46Z delphij $");
70
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/file.h>
74#include <sys/lock.h>
75#include <sys/mutex.h>
76#include <sys/proc.h>
77#include <sys/resource.h>
78#include <sys/resourcevar.h>
79#include <sys/syscallsubr.h>
80
81#include <compat/svr4/svr4.h>
82#include <compat/svr4/svr4_types.h>
83#include <compat/svr4/svr4_resource.h>
84#include <compat/svr4/svr4_signal.h>
85#include <compat/svr4/svr4_proto.h>
86#include <compat/svr4/svr4_util.h>
87
88static __inline int svr4_to_native_rl(int);
89
90static __inline int
91svr4_to_native_rl(rl)
92	int rl;
93{
94	switch (rl) {
95	case SVR4_RLIMIT_CPU:
96		return RLIMIT_CPU;
97	case SVR4_RLIMIT_FSIZE:
98		return RLIMIT_FSIZE;
99	case SVR4_RLIMIT_DATA:
100		return RLIMIT_DATA;
101	case SVR4_RLIMIT_STACK:
102		return RLIMIT_STACK;
103	case SVR4_RLIMIT_CORE:
104		return RLIMIT_CORE;
105	case SVR4_RLIMIT_NOFILE:
106		return RLIMIT_NOFILE;
107	case SVR4_RLIMIT_VMEM:
108		return RLIMIT_VMEM;
109	default:
110		return -1;
111	}
112}
113
114/*
115 * Check if the resource limit fits within the BSD range and it is not
116 * one of the magic SVR4 limit values
117 */
118#define OKLIMIT(l) (((int32_t)(l)) >= 0 && ((int32_t)(l)) < 0x7fffffff && \
119	((svr4_rlim_t)(l)) != SVR4_RLIM_INFINITY && \
120	((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_CUR && \
121	((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_MAX)
122
123#define OKLIMIT64(l) (((rlim_t)(l)) >= 0 && ((rlim_t)(l)) < RLIM_INFINITY && \
124	((svr4_rlim64_t)(l)) != SVR4_RLIM64_INFINITY && \
125	((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_CUR && \
126	((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_MAX)
127
128int
129svr4_sys_getrlimit(td, uap)
130	struct thread *td;
131	struct svr4_sys_getrlimit_args *uap;
132{
133	int rl = svr4_to_native_rl(uap->which);
134	struct rlimit blim;
135	struct svr4_rlimit slim;
136
137	if (rl == -1)
138		return EINVAL;
139
140	PROC_LOCK(td->td_proc);
141	lim_rlimit(td->td_proc, rl, &blim);
142	PROC_UNLOCK(td->td_proc);
143
144	/*
145	 * Our infinity, is their maxfiles.
146	 */
147	if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
148		blim.rlim_max = maxfiles;
149
150	/*
151	 * If the limit can be be represented, it is returned.
152	 * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX
153	 * else return RLIM_SAVED_CUR
154	 */
155	if (blim.rlim_max == RLIM_INFINITY)
156		slim.rlim_max = SVR4_RLIM_INFINITY;
157	else if (OKLIMIT(blim.rlim_max))
158		slim.rlim_max = (svr4_rlim_t) blim.rlim_max;
159	else
160		slim.rlim_max = SVR4_RLIM_SAVED_MAX;
161
162	if (blim.rlim_cur == RLIM_INFINITY)
163		slim.rlim_cur = SVR4_RLIM_INFINITY;
164	else if (OKLIMIT(blim.rlim_cur))
165		slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur;
166	else if (blim.rlim_max == blim.rlim_cur)
167		slim.rlim_cur = SVR4_RLIM_SAVED_MAX;
168	else
169		slim.rlim_cur = SVR4_RLIM_SAVED_CUR;
170
171	return copyout(&slim, uap->rlp, sizeof(*uap->rlp));
172}
173
174
175int
176svr4_sys_setrlimit(td, uap)
177	struct thread *td;
178	struct svr4_sys_setrlimit_args *uap;
179{
180	int rl = svr4_to_native_rl(uap->which);
181	struct rlimit blim, curlim;
182	struct svr4_rlimit slim;
183	int error;
184
185	if (rl == -1)
186		return EINVAL;
187
188	if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
189		return error;
190
191	PROC_LOCK(td->td_proc);
192	lim_rlimit(td->td_proc, rl, &curlim);
193	PROC_UNLOCK(td->td_proc);
194
195	/*
196	 * if the limit is SVR4_RLIM_INFINITY, then we set it to our
197	 * unlimited.
198	 * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the
199	 * new limit to the corresponding saved hard limit, and if
200	 * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the
201	 * corresponding saved soft limit.
202	 *
203	 */
204	if (slim.rlim_max == SVR4_RLIM_INFINITY)
205		blim.rlim_max = RLIM_INFINITY;
206	else if (OKLIMIT(slim.rlim_max))
207		blim.rlim_max = (rlim_t) slim.rlim_max;
208	else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX)
209		blim.rlim_max = curlim.rlim_max;
210	else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR)
211		blim.rlim_max = curlim.rlim_cur;
212
213	if (slim.rlim_cur == SVR4_RLIM_INFINITY)
214		blim.rlim_cur = RLIM_INFINITY;
215	else if (OKLIMIT(slim.rlim_cur))
216		blim.rlim_cur = (rlim_t) slim.rlim_cur;
217	else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX)
218		blim.rlim_cur = curlim.rlim_max;
219	else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
220		blim.rlim_cur = curlim.rlim_cur;
221
222	return (kern_setrlimit(td, rl, &blim));
223}
224
225
226int
227svr4_sys_getrlimit64(td, uap)
228	struct thread *td;
229	struct svr4_sys_getrlimit64_args *uap;
230{
231	int rl = svr4_to_native_rl(uap->which);
232	struct rlimit blim;
233	struct svr4_rlimit64 slim;
234
235	if (rl == -1)
236		return EINVAL;
237
238	PROC_LOCK(td->td_proc);
239	lim_rlimit(td->td_proc, rl, &blim);
240	PROC_UNLOCK(td->td_proc);
241
242	/*
243	 * Our infinity, is their maxfiles.
244	 */
245	if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
246		blim.rlim_max = maxfiles;
247
248	/*
249	 * If the limit can be be represented, it is returned.
250	 * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX
251	 * else return SVR4_RLIM_SAVED_CUR
252	 */
253	if (blim.rlim_max == RLIM_INFINITY)
254		slim.rlim_max = SVR4_RLIM64_INFINITY;
255	else if (OKLIMIT64(blim.rlim_max))
256		slim.rlim_max = (svr4_rlim64_t) blim.rlim_max;
257	else
258		slim.rlim_max = SVR4_RLIM64_SAVED_MAX;
259
260	if (blim.rlim_cur == RLIM_INFINITY)
261		slim.rlim_cur = SVR4_RLIM64_INFINITY;
262	else if (OKLIMIT64(blim.rlim_cur))
263		slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur;
264	else if (blim.rlim_max == blim.rlim_cur)
265		slim.rlim_cur = SVR4_RLIM64_SAVED_MAX;
266	else
267		slim.rlim_cur = SVR4_RLIM64_SAVED_CUR;
268
269	return copyout(&slim, uap->rlp, sizeof(*uap->rlp));
270}
271
272
273int
274svr4_sys_setrlimit64(td, uap)
275	struct thread *td;
276	struct svr4_sys_setrlimit64_args *uap;
277{
278	int rl = svr4_to_native_rl(uap->which);
279	struct rlimit blim, curlim;
280	struct svr4_rlimit64 slim;
281	int error;
282
283	if (rl == -1)
284		return EINVAL;
285
286	if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
287		return error;
288
289	PROC_LOCK(td->td_proc);
290	lim_rlimit(td->td_proc, rl, &curlim);
291	PROC_UNLOCK(td->td_proc);
292
293	/*
294	 * if the limit is SVR4_RLIM64_INFINITY, then we set it to our
295	 * unlimited.
296	 * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the
297	 * new limit to the corresponding saved hard limit, and if
298	 * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the
299	 * corresponding saved soft limit.
300	 *
301	 */
302	if (slim.rlim_max == SVR4_RLIM64_INFINITY)
303		blim.rlim_max = RLIM_INFINITY;
304	else if (OKLIMIT64(slim.rlim_max))
305		blim.rlim_max = (rlim_t) slim.rlim_max;
306	else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX)
307		blim.rlim_max = curlim.rlim_max;
308	else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR)
309		blim.rlim_max = curlim.rlim_cur;
310
311	if (slim.rlim_cur == SVR4_RLIM64_INFINITY)
312		blim.rlim_cur = RLIM_INFINITY;
313	else if (OKLIMIT64(slim.rlim_cur))
314		blim.rlim_cur = (rlim_t) slim.rlim_cur;
315	else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX)
316		blim.rlim_cur = curlim.rlim_max;
317	else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
318		blim.rlim_cur = curlim.rlim_cur;
319
320	return (kern_setrlimit(td, rl, &blim));
321}
322