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