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