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