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