svr4_resource.c revision 92761
143412Snewton/*	Derived from:
243412Snewton *      $NetBSD: svr4_resource.c,v 1.3 1998/12/13 18:00:52 christos Exp $
343412Snewton */
443412Snewton
543412Snewton/*-
643412Snewton * Original copyright:
743412Snewton *
843412Snewton * Copyright (c) 1998 The NetBSD Foundation, Inc.
943412Snewton * All rights reserved.
1043412Snewton *
1143412Snewton * This code is derived from software contributed to The NetBSD Foundation
1243412Snewton * by Christos Zoulas.
1343412Snewton *
1443412Snewton * Redistribution and use in source and binary forms, with or without
1543412Snewton * modification, are permitted provided that the following conditions
1643412Snewton * are met:
1743412Snewton * 1. Redistributions of source code must retain the above copyright
1843412Snewton *    notice, this list of conditions and the following disclaimer.
1943412Snewton * 2. Redistributions in binary form must reproduce the above copyright
2043412Snewton *    notice, this list of conditions and the following disclaimer in the
2143412Snewton *    documentation and/or other materials provided with the distribution.
2243412Snewton * 3. All advertising materials mentioning features or use of this software
2343412Snewton *    must display the following acknowledgement:
2443412Snewton *        This product includes software developed by the NetBSD
2543412Snewton *        Foundation, Inc. and its contributors.
2643412Snewton * 4. Neither the name of The NetBSD Foundation nor the names of its
2743412Snewton *    contributors may be used to endorse or promote products derived
2843412Snewton *    from this software without specific prior written permission.
2943412Snewton *
3043412Snewton * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
3143412Snewton * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
3243412Snewton * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3343412Snewton * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3443412Snewton * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3543412Snewton * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3643412Snewton * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3743412Snewton * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3843412Snewton * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3943412Snewton * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4043412Snewton * POSSIBILITY OF SUCH DAMAGE.
4149267Snewton *
4250477Speter * $FreeBSD: head/sys/compat/svr4/svr4_resource.c 92761 2002-03-20 05:48:58Z alfred $
4343412Snewton */
4443412Snewton
4543412Snewton/*
4643412Snewton * Portions of this software have been derived from software contributed
4743412Snewton * to the FreeBSD Project by Mark Newton.
4843412Snewton *
4943412Snewton * Copyright (c) 1999 Mark Newton
5043412Snewton * All rights reserved.
5143412Snewton *
5243412Snewton * Redistribution and use in source and binary forms, with or without
5343412Snewton * modification, are permitted provided that the following conditions
5443412Snewton * are met:
5543412Snewton * 1. Redistributions of source code must retain the above copyright
5643412Snewton *    notice, this list of conditions and the following disclaimer.
5743412Snewton * 2. Redistributions in binary form must reproduce the above copyright
5843412Snewton *    notice, this list of conditions and the following disclaimer in the
5943412Snewton *    documentation and/or other materials provided with the distribution.
6043412Snewton * 3. The name of the author may not be used to endorse or promote products
6143412Snewton *    derived from this software without specific prior written permission
6243412Snewton *
6343412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6443412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
6543412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6643412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6743412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6843412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6943412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7043412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7143412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7243412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7343412Snewton */
7443412Snewton
7543412Snewton#include <sys/param.h>
7643412Snewton#include <sys/systm.h>
7776166Smarkm#include <sys/file.h>
7884811Sjhb#include <sys/lock.h>
7976166Smarkm#include <sys/mutex.h>
8043412Snewton#include <sys/proc.h>
8143412Snewton#include <sys/resource.h>
8243412Snewton#include <sys/resourcevar.h>
8343412Snewton
8465302Sobrien#include <compat/svr4/svr4.h>
8565302Sobrien#include <compat/svr4/svr4_types.h>
8665302Sobrien#include <compat/svr4/svr4_resource.h>
8765302Sobrien#include <compat/svr4/svr4_signal.h>
8865302Sobrien#include <compat/svr4/svr4_proto.h>
8965302Sobrien#include <compat/svr4/svr4_util.h>
9043412Snewton
9192761Salfredstatic __inline int svr4_to_native_rl(int);
9243412Snewton
9343412Snewtonstatic __inline int
9443412Snewtonsvr4_to_native_rl(rl)
9543412Snewton	int rl;
9643412Snewton{
9743412Snewton	switch (rl) {
9843412Snewton	case SVR4_RLIMIT_CPU:
9943412Snewton		return RLIMIT_CPU;
10043412Snewton	case SVR4_RLIMIT_FSIZE:
10143412Snewton		return RLIMIT_FSIZE;
10243412Snewton	case SVR4_RLIMIT_DATA:
10343412Snewton		return RLIMIT_DATA;
10443412Snewton	case SVR4_RLIMIT_STACK:
10543412Snewton		return RLIMIT_STACK;
10643412Snewton	case SVR4_RLIMIT_CORE:
10743412Snewton		return RLIMIT_CORE;
10843412Snewton	case SVR4_RLIMIT_NOFILE:
10943412Snewton		return RLIMIT_NOFILE;
11043412Snewton	case SVR4_RLIMIT_VMEM:
11143412Snewton		return RLIMIT_RSS;
11243412Snewton	default:
11343412Snewton		return -1;
11443412Snewton	}
11543412Snewton}
11643412Snewton
11743412Snewton/*
11843412Snewton * Check if the resource limit fits within the BSD range and it is not
11943412Snewton * one of the magic SVR4 limit values
12043412Snewton */
12143412Snewton#define OKLIMIT(l) (((int32_t)(l)) >= 0 && ((int32_t)(l)) < 0x7fffffff && \
12243412Snewton	((svr4_rlim_t)(l)) != SVR4_RLIM_INFINITY && \
12343412Snewton	((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_CUR && \
12443412Snewton	((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_MAX)
12543412Snewton
12643412Snewton#define OKLIMIT64(l) (((rlim_t)(l)) >= 0 && ((rlim_t)(l)) < RLIM_INFINITY && \
12743412Snewton	((svr4_rlim64_t)(l)) != SVR4_RLIM64_INFINITY && \
12843412Snewton	((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_CUR && \
12943412Snewton	((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_MAX)
13043412Snewton
13143412Snewtonint
13283366Sjuliansvr4_sys_getrlimit(td, uap)
13383366Sjulian	register struct thread *td;
13443412Snewton	struct svr4_sys_getrlimit_args *uap;
13543412Snewton{
13643412Snewton	int rl = svr4_to_native_rl(SCARG(uap, which));
13743412Snewton	struct rlimit blim;
13843412Snewton	struct svr4_rlimit slim;
13943412Snewton
14043412Snewton	if (rl == -1)
14143412Snewton		return EINVAL;
14243412Snewton
14371454Sjhb	/* For p_rlimit. */
14471454Sjhb	mtx_assert(&Giant, MA_OWNED);
14583366Sjulian	blim = td->td_proc->p_rlimit[rl];
14643412Snewton
14743412Snewton	/*
14843412Snewton	 * Our infinity, is their maxfiles.
14943412Snewton	 */
15043412Snewton	if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
15143412Snewton		blim.rlim_max = maxfiles;
15243412Snewton
15343412Snewton	/*
15443412Snewton	 * If the limit can be be represented, it is returned.
15543412Snewton	 * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX
15643412Snewton	 * else return RLIM_SAVED_CUR
15743412Snewton	 */
15843412Snewton	if (blim.rlim_max == RLIM_INFINITY)
15943412Snewton		slim.rlim_max = SVR4_RLIM_INFINITY;
16043412Snewton	else if (OKLIMIT(blim.rlim_max))
16143412Snewton		slim.rlim_max = (svr4_rlim_t) blim.rlim_max;
16243412Snewton	else
16343412Snewton		slim.rlim_max = SVR4_RLIM_SAVED_MAX;
16443412Snewton
16543412Snewton	if (blim.rlim_cur == RLIM_INFINITY)
16643412Snewton		slim.rlim_cur = SVR4_RLIM_INFINITY;
16743412Snewton	else if (OKLIMIT(blim.rlim_cur))
16843412Snewton		slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur;
16943412Snewton	else if (blim.rlim_max == blim.rlim_cur)
17043412Snewton		slim.rlim_cur = SVR4_RLIM_SAVED_MAX;
17143412Snewton	else
17243412Snewton		slim.rlim_cur = SVR4_RLIM_SAVED_CUR;
17343412Snewton
17443412Snewton	return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
17543412Snewton}
17643412Snewton
17743412Snewton
17843412Snewtonint
17983366Sjuliansvr4_sys_setrlimit(td, uap)
18083366Sjulian	register struct thread *td;
18143412Snewton	struct svr4_sys_setrlimit_args *uap;
18243412Snewton{
18343412Snewton	int rl = svr4_to_native_rl(SCARG(uap, which));
18443412Snewton	struct rlimit blim, *limp;
18543412Snewton	struct svr4_rlimit slim;
18643412Snewton	int error;
18743412Snewton
18843412Snewton	if (rl == -1)
18943412Snewton		return EINVAL;
19043412Snewton
19171454Sjhb	/* For p_rlimit. */
19271454Sjhb	mtx_assert(&Giant, MA_OWNED);
19383366Sjulian	limp = &td->td_proc->p_rlimit[rl];
19443412Snewton
19543412Snewton	if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
19643412Snewton		return error;
19743412Snewton
19843412Snewton	/*
19943412Snewton	 * if the limit is SVR4_RLIM_INFINITY, then we set it to our
20043412Snewton	 * unlimited.
20143412Snewton	 * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the
20243412Snewton	 * new limit to the corresponding saved hard limit, and if
20343412Snewton	 * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the
20443412Snewton	 * corresponding saved soft limit.
20543412Snewton	 *
20643412Snewton	 */
20743412Snewton	if (slim.rlim_max == SVR4_RLIM_INFINITY)
20843412Snewton		blim.rlim_max = RLIM_INFINITY;
20943412Snewton	else if (OKLIMIT(slim.rlim_max))
21043412Snewton		blim.rlim_max = (rlim_t) slim.rlim_max;
21143412Snewton	else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX)
21243412Snewton		blim.rlim_max = limp->rlim_max;
21343412Snewton	else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR)
21443412Snewton		blim.rlim_max = limp->rlim_cur;
21543412Snewton
21643412Snewton	if (slim.rlim_cur == SVR4_RLIM_INFINITY)
21743412Snewton		blim.rlim_cur = RLIM_INFINITY;
21843412Snewton	else if (OKLIMIT(slim.rlim_cur))
21943412Snewton		blim.rlim_cur = (rlim_t) slim.rlim_cur;
22043412Snewton	else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX)
22143412Snewton		blim.rlim_cur = limp->rlim_max;
22243412Snewton	else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
22343412Snewton		blim.rlim_cur = limp->rlim_cur;
22443412Snewton
22583366Sjulian	return dosetrlimit(td, rl, &blim);
22643412Snewton}
22743412Snewton
22843412Snewton
22943412Snewtonint
23083366Sjuliansvr4_sys_getrlimit64(td, uap)
23183366Sjulian	register struct thread *td;
23243412Snewton	struct svr4_sys_getrlimit64_args *uap;
23343412Snewton{
23443412Snewton	int rl = svr4_to_native_rl(SCARG(uap, which));
23543412Snewton	struct rlimit blim;
23643412Snewton	struct svr4_rlimit64 slim;
23743412Snewton
23843412Snewton	if (rl == -1)
23943412Snewton		return EINVAL;
24043412Snewton
24171454Sjhb	/* For p_rlimit. */
24271454Sjhb	mtx_assert(&Giant, MA_OWNED);
24383366Sjulian	blim = td->td_proc->p_rlimit[rl];
24443412Snewton
24543412Snewton	/*
24643412Snewton	 * Our infinity, is their maxfiles.
24743412Snewton	 */
24843412Snewton	if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
24943412Snewton		blim.rlim_max = maxfiles;
25043412Snewton
25143412Snewton	/*
25243412Snewton	 * If the limit can be be represented, it is returned.
25343412Snewton	 * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX
25443412Snewton	 * else return SVR4_RLIM_SAVED_CUR
25543412Snewton	 */
25643412Snewton	if (blim.rlim_max == RLIM_INFINITY)
25743412Snewton		slim.rlim_max = SVR4_RLIM64_INFINITY;
25843412Snewton	else if (OKLIMIT64(blim.rlim_max))
25943412Snewton		slim.rlim_max = (svr4_rlim64_t) blim.rlim_max;
26043412Snewton	else
26143412Snewton		slim.rlim_max = SVR4_RLIM64_SAVED_MAX;
26243412Snewton
26343412Snewton	if (blim.rlim_cur == RLIM_INFINITY)
26443412Snewton		slim.rlim_cur = SVR4_RLIM64_INFINITY;
26543412Snewton	else if (OKLIMIT64(blim.rlim_cur))
26643412Snewton		slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur;
26743412Snewton	else if (blim.rlim_max == blim.rlim_cur)
26843412Snewton		slim.rlim_cur = SVR4_RLIM64_SAVED_MAX;
26943412Snewton	else
27043412Snewton		slim.rlim_cur = SVR4_RLIM64_SAVED_CUR;
27143412Snewton
27243412Snewton	return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
27343412Snewton}
27443412Snewton
27543412Snewton
27643412Snewtonint
27783366Sjuliansvr4_sys_setrlimit64(td, uap)
27883366Sjulian	register struct thread *td;
27943412Snewton	struct svr4_sys_setrlimit64_args *uap;
28043412Snewton{
28143412Snewton	int rl = svr4_to_native_rl(SCARG(uap, which));
28243412Snewton	struct rlimit blim, *limp;
28343412Snewton	struct svr4_rlimit64 slim;
28443412Snewton	int error;
28543412Snewton
28643412Snewton	if (rl == -1)
28743412Snewton		return EINVAL;
28843412Snewton
28971454Sjhb	/* For p_rlimit. */
29071454Sjhb	mtx_assert(&Giant, MA_OWNED);
29183366Sjulian	limp = &td->td_proc->p_rlimit[rl];
29243412Snewton
29343412Snewton	if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
29443412Snewton		return error;
29543412Snewton
29643412Snewton	/*
29743412Snewton	 * if the limit is SVR4_RLIM64_INFINITY, then we set it to our
29843412Snewton	 * unlimited.
29943412Snewton	 * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the
30043412Snewton	 * new limit to the corresponding saved hard limit, and if
30143412Snewton	 * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the
30243412Snewton	 * corresponding saved soft limit.
30343412Snewton	 *
30443412Snewton	 */
30543412Snewton	if (slim.rlim_max == SVR4_RLIM64_INFINITY)
30643412Snewton		blim.rlim_max = RLIM_INFINITY;
30743412Snewton	else if (OKLIMIT64(slim.rlim_max))
30843412Snewton		blim.rlim_max = (rlim_t) slim.rlim_max;
30943412Snewton	else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX)
31043412Snewton		blim.rlim_max = limp->rlim_max;
31143412Snewton	else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR)
31243412Snewton		blim.rlim_max = limp->rlim_cur;
31343412Snewton
31443412Snewton	if (slim.rlim_cur == SVR4_RLIM64_INFINITY)
31543412Snewton		blim.rlim_cur = RLIM_INFINITY;
31643412Snewton	else if (OKLIMIT64(slim.rlim_cur))
31743412Snewton		blim.rlim_cur = (rlim_t) slim.rlim_cur;
31843412Snewton	else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX)
31943412Snewton		blim.rlim_cur = limp->rlim_max;
32043412Snewton	else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
32143412Snewton		blim.rlim_cur = limp->rlim_cur;
32243412Snewton
32383366Sjulian	return dosetrlimit(td, rl, &blim);
32443412Snewton}
325