143412Snewton/*- 243412Snewton * Copyright (c) 1998 The NetBSD Foundation, Inc. 343412Snewton * All rights reserved. 443412Snewton * 543412Snewton * This code is derived from software contributed to The NetBSD Foundation 643412Snewton * by Christos Zoulas. 743412Snewton * 843412Snewton * Redistribution and use in source and binary forms, with or without 943412Snewton * modification, are permitted provided that the following conditions 1043412Snewton * are met: 1143412Snewton * 1. Redistributions of source code must retain the above copyright 1243412Snewton * notice, this list of conditions and the following disclaimer. 1343412Snewton * 2. Redistributions in binary form must reproduce the above copyright 1443412Snewton * notice, this list of conditions and the following disclaimer in the 1543412Snewton * documentation and/or other materials provided with the distribution. 1643412Snewton * 1743412Snewton * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1843412Snewton * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1943412Snewton * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2043412Snewton * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2143412Snewton * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2243412Snewton * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2343412Snewton * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2443412Snewton * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2543412Snewton * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2643412Snewton * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2743412Snewton * POSSIBILITY OF SUCH DAMAGE. 2843412Snewton */ 29139743Simp/*- 3043412Snewton * Portions of this software have been derived from software contributed 3143412Snewton * to the FreeBSD Project by Mark Newton. 3243412Snewton * 3343412Snewton * Copyright (c) 1999 Mark Newton 3443412Snewton * All rights reserved. 3543412Snewton * 3643412Snewton * Redistribution and use in source and binary forms, with or without 3743412Snewton * modification, are permitted provided that the following conditions 3843412Snewton * are met: 3943412Snewton * 1. Redistributions of source code must retain the above copyright 4043412Snewton * notice, this list of conditions and the following disclaimer. 4143412Snewton * 2. Redistributions in binary form must reproduce the above copyright 4243412Snewton * notice, this list of conditions and the following disclaimer in the 4343412Snewton * documentation and/or other materials provided with the distribution. 4443412Snewton * 3. The name of the author may not be used to endorse or promote products 4543412Snewton * derived from this software without specific prior written permission 4643412Snewton * 4743412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 4843412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4943412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 5043412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 5143412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 5243412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 5343412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5443412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5543412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 5643412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57116174Sobrien * 58116174Sobrien * Derived from: $NetBSD: svr4_resource.c,v 1.3 1998/12/13 18:00:52 christos Exp $ 5943412Snewton */ 6043412Snewton 61116174Sobrien#include <sys/cdefs.h> 62116174Sobrien__FBSDID("$FreeBSD: releng/11.0/sys/compat/svr4/svr4_resource.c 284215 2015-06-10 10:48:12Z mjg $"); 63116174Sobrien 6443412Snewton#include <sys/param.h> 6543412Snewton#include <sys/systm.h> 6676166Smarkm#include <sys/file.h> 6784811Sjhb#include <sys/lock.h> 6876166Smarkm#include <sys/mutex.h> 6943412Snewton#include <sys/proc.h> 7043412Snewton#include <sys/resource.h> 7143412Snewton#include <sys/resourcevar.h> 72139739Sjhb#include <sys/syscallsubr.h> 7343412Snewton 7465302Sobrien#include <compat/svr4/svr4.h> 7565302Sobrien#include <compat/svr4/svr4_types.h> 7665302Sobrien#include <compat/svr4/svr4_resource.h> 7765302Sobrien#include <compat/svr4/svr4_signal.h> 7865302Sobrien#include <compat/svr4/svr4_proto.h> 7965302Sobrien#include <compat/svr4/svr4_util.h> 8043412Snewton 8192761Salfredstatic __inline int svr4_to_native_rl(int); 8243412Snewton 8343412Snewtonstatic __inline int 8443412Snewtonsvr4_to_native_rl(rl) 8543412Snewton int rl; 8643412Snewton{ 8743412Snewton switch (rl) { 8843412Snewton case SVR4_RLIMIT_CPU: 8943412Snewton return RLIMIT_CPU; 9043412Snewton case SVR4_RLIMIT_FSIZE: 9143412Snewton return RLIMIT_FSIZE; 9243412Snewton case SVR4_RLIMIT_DATA: 9343412Snewton return RLIMIT_DATA; 9443412Snewton case SVR4_RLIMIT_STACK: 9543412Snewton return RLIMIT_STACK; 9643412Snewton case SVR4_RLIMIT_CORE: 9743412Snewton return RLIMIT_CORE; 9843412Snewton case SVR4_RLIMIT_NOFILE: 9943412Snewton return RLIMIT_NOFILE; 10043412Snewton case SVR4_RLIMIT_VMEM: 101102630Sdillon return RLIMIT_VMEM; 10243412Snewton default: 10343412Snewton return -1; 10443412Snewton } 10543412Snewton} 10643412Snewton 10743412Snewton/* 10843412Snewton * Check if the resource limit fits within the BSD range and it is not 10943412Snewton * one of the magic SVR4 limit values 11043412Snewton */ 11143412Snewton#define OKLIMIT(l) (((int32_t)(l)) >= 0 && ((int32_t)(l)) < 0x7fffffff && \ 11243412Snewton ((svr4_rlim_t)(l)) != SVR4_RLIM_INFINITY && \ 11343412Snewton ((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_CUR && \ 11443412Snewton ((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_MAX) 11543412Snewton 11643412Snewton#define OKLIMIT64(l) (((rlim_t)(l)) >= 0 && ((rlim_t)(l)) < RLIM_INFINITY && \ 11743412Snewton ((svr4_rlim64_t)(l)) != SVR4_RLIM64_INFINITY && \ 11843412Snewton ((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_CUR && \ 11943412Snewton ((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_MAX) 12043412Snewton 12143412Snewtonint 12283366Sjuliansvr4_sys_getrlimit(td, uap) 123193014Sdelphij struct thread *td; 12443412Snewton struct svr4_sys_getrlimit_args *uap; 12543412Snewton{ 126107849Salfred int rl = svr4_to_native_rl(uap->which); 12743412Snewton struct rlimit blim; 12843412Snewton struct svr4_rlimit slim; 12943412Snewton 13043412Snewton if (rl == -1) 13143412Snewton return EINVAL; 13243412Snewton 133284215Smjg lim_rlimit(td, rl, &blim); 13443412Snewton 13543412Snewton /* 13643412Snewton * Our infinity, is their maxfiles. 13743412Snewton */ 13843412Snewton if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY) 13943412Snewton blim.rlim_max = maxfiles; 14043412Snewton 14143412Snewton /* 14243412Snewton * If the limit can be be represented, it is returned. 14343412Snewton * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX 14443412Snewton * else return RLIM_SAVED_CUR 14543412Snewton */ 14643412Snewton if (blim.rlim_max == RLIM_INFINITY) 14743412Snewton slim.rlim_max = SVR4_RLIM_INFINITY; 14843412Snewton else if (OKLIMIT(blim.rlim_max)) 14943412Snewton slim.rlim_max = (svr4_rlim_t) blim.rlim_max; 15043412Snewton else 15143412Snewton slim.rlim_max = SVR4_RLIM_SAVED_MAX; 15243412Snewton 15343412Snewton if (blim.rlim_cur == RLIM_INFINITY) 15443412Snewton slim.rlim_cur = SVR4_RLIM_INFINITY; 15543412Snewton else if (OKLIMIT(blim.rlim_cur)) 15643412Snewton slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur; 15743412Snewton else if (blim.rlim_max == blim.rlim_cur) 15843412Snewton slim.rlim_cur = SVR4_RLIM_SAVED_MAX; 15943412Snewton else 16043412Snewton slim.rlim_cur = SVR4_RLIM_SAVED_CUR; 16143412Snewton 162107849Salfred return copyout(&slim, uap->rlp, sizeof(*uap->rlp)); 16343412Snewton} 16443412Snewton 16543412Snewton 16643412Snewtonint 16783366Sjuliansvr4_sys_setrlimit(td, uap) 168193014Sdelphij struct thread *td; 16943412Snewton struct svr4_sys_setrlimit_args *uap; 17043412Snewton{ 171107849Salfred int rl = svr4_to_native_rl(uap->which); 172125454Sjhb struct rlimit blim, curlim; 17343412Snewton struct svr4_rlimit slim; 17443412Snewton int error; 17543412Snewton 17643412Snewton if (rl == -1) 17743412Snewton return EINVAL; 17843412Snewton 179107849Salfred if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0) 18043412Snewton return error; 18143412Snewton 182284215Smjg lim_rlimit(td, rl, &curlim); 183125454Sjhb 18443412Snewton /* 18543412Snewton * if the limit is SVR4_RLIM_INFINITY, then we set it to our 18643412Snewton * unlimited. 18743412Snewton * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the 18843412Snewton * new limit to the corresponding saved hard limit, and if 18943412Snewton * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the 19043412Snewton * corresponding saved soft limit. 19143412Snewton * 19243412Snewton */ 19343412Snewton if (slim.rlim_max == SVR4_RLIM_INFINITY) 19443412Snewton blim.rlim_max = RLIM_INFINITY; 19543412Snewton else if (OKLIMIT(slim.rlim_max)) 19643412Snewton blim.rlim_max = (rlim_t) slim.rlim_max; 19743412Snewton else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX) 198125454Sjhb blim.rlim_max = curlim.rlim_max; 19943412Snewton else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR) 200125454Sjhb blim.rlim_max = curlim.rlim_cur; 20143412Snewton 20243412Snewton if (slim.rlim_cur == SVR4_RLIM_INFINITY) 20343412Snewton blim.rlim_cur = RLIM_INFINITY; 20443412Snewton else if (OKLIMIT(slim.rlim_cur)) 20543412Snewton blim.rlim_cur = (rlim_t) slim.rlim_cur; 20643412Snewton else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX) 207125454Sjhb blim.rlim_cur = curlim.rlim_max; 20843412Snewton else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR) 209125454Sjhb blim.rlim_cur = curlim.rlim_cur; 21043412Snewton 211125454Sjhb return (kern_setrlimit(td, rl, &blim)); 21243412Snewton} 21343412Snewton 21443412Snewton 21543412Snewtonint 21683366Sjuliansvr4_sys_getrlimit64(td, uap) 217193014Sdelphij struct thread *td; 21843412Snewton struct svr4_sys_getrlimit64_args *uap; 21943412Snewton{ 220107849Salfred int rl = svr4_to_native_rl(uap->which); 22143412Snewton struct rlimit blim; 22243412Snewton struct svr4_rlimit64 slim; 22343412Snewton 22443412Snewton if (rl == -1) 22543412Snewton return EINVAL; 22643412Snewton 227284215Smjg lim_rlimit(td, rl, &blim); 22843412Snewton 22943412Snewton /* 23043412Snewton * Our infinity, is their maxfiles. 23143412Snewton */ 23243412Snewton if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY) 23343412Snewton blim.rlim_max = maxfiles; 23443412Snewton 23543412Snewton /* 23643412Snewton * If the limit can be be represented, it is returned. 23743412Snewton * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX 23843412Snewton * else return SVR4_RLIM_SAVED_CUR 23943412Snewton */ 24043412Snewton if (blim.rlim_max == RLIM_INFINITY) 24143412Snewton slim.rlim_max = SVR4_RLIM64_INFINITY; 24243412Snewton else if (OKLIMIT64(blim.rlim_max)) 24343412Snewton slim.rlim_max = (svr4_rlim64_t) blim.rlim_max; 24443412Snewton else 24543412Snewton slim.rlim_max = SVR4_RLIM64_SAVED_MAX; 24643412Snewton 24743412Snewton if (blim.rlim_cur == RLIM_INFINITY) 24843412Snewton slim.rlim_cur = SVR4_RLIM64_INFINITY; 24943412Snewton else if (OKLIMIT64(blim.rlim_cur)) 25043412Snewton slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur; 25143412Snewton else if (blim.rlim_max == blim.rlim_cur) 25243412Snewton slim.rlim_cur = SVR4_RLIM64_SAVED_MAX; 25343412Snewton else 25443412Snewton slim.rlim_cur = SVR4_RLIM64_SAVED_CUR; 25543412Snewton 256107849Salfred return copyout(&slim, uap->rlp, sizeof(*uap->rlp)); 25743412Snewton} 25843412Snewton 25943412Snewton 26043412Snewtonint 26183366Sjuliansvr4_sys_setrlimit64(td, uap) 262193014Sdelphij struct thread *td; 26343412Snewton struct svr4_sys_setrlimit64_args *uap; 26443412Snewton{ 265107849Salfred int rl = svr4_to_native_rl(uap->which); 266125454Sjhb struct rlimit blim, curlim; 26743412Snewton struct svr4_rlimit64 slim; 26843412Snewton int error; 26943412Snewton 27043412Snewton if (rl == -1) 27143412Snewton return EINVAL; 27243412Snewton 273107849Salfred if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0) 27443412Snewton return error; 27543412Snewton 276284215Smjg lim_rlimit(td, rl, &curlim); 277125454Sjhb 27843412Snewton /* 27943412Snewton * if the limit is SVR4_RLIM64_INFINITY, then we set it to our 28043412Snewton * unlimited. 28143412Snewton * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the 28243412Snewton * new limit to the corresponding saved hard limit, and if 28343412Snewton * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the 28443412Snewton * corresponding saved soft limit. 28543412Snewton * 28643412Snewton */ 28743412Snewton if (slim.rlim_max == SVR4_RLIM64_INFINITY) 28843412Snewton blim.rlim_max = RLIM_INFINITY; 28943412Snewton else if (OKLIMIT64(slim.rlim_max)) 29043412Snewton blim.rlim_max = (rlim_t) slim.rlim_max; 29143412Snewton else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX) 292125454Sjhb blim.rlim_max = curlim.rlim_max; 29343412Snewton else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR) 294125454Sjhb blim.rlim_max = curlim.rlim_cur; 29543412Snewton 29643412Snewton if (slim.rlim_cur == SVR4_RLIM64_INFINITY) 29743412Snewton blim.rlim_cur = RLIM_INFINITY; 29843412Snewton else if (OKLIMIT64(slim.rlim_cur)) 29943412Snewton blim.rlim_cur = (rlim_t) slim.rlim_cur; 30043412Snewton else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX) 301125454Sjhb blim.rlim_cur = curlim.rlim_max; 30243412Snewton else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR) 303125454Sjhb blim.rlim_cur = curlim.rlim_cur; 30443412Snewton 305125454Sjhb return (kern_setrlimit(td, rl, &blim)); 30643412Snewton} 307