svr4_resource.c revision 263687
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: stable/10/sys/compat/svr4/svr4_resource.c 263687 2014-03-24 13:48:04Z emaste $"); 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 PROC_LOCK(td->td_proc); 134 lim_rlimit(td->td_proc, rl, &blim); 135 PROC_UNLOCK(td->td_proc); 136 137 /* 138 * Our infinity, is their maxfiles. 139 */ 140 if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY) 141 blim.rlim_max = maxfiles; 142 143 /* 144 * If the limit can be be represented, it is returned. 145 * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX 146 * else return RLIM_SAVED_CUR 147 */ 148 if (blim.rlim_max == RLIM_INFINITY) 149 slim.rlim_max = SVR4_RLIM_INFINITY; 150 else if (OKLIMIT(blim.rlim_max)) 151 slim.rlim_max = (svr4_rlim_t) blim.rlim_max; 152 else 153 slim.rlim_max = SVR4_RLIM_SAVED_MAX; 154 155 if (blim.rlim_cur == RLIM_INFINITY) 156 slim.rlim_cur = SVR4_RLIM_INFINITY; 157 else if (OKLIMIT(blim.rlim_cur)) 158 slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur; 159 else if (blim.rlim_max == blim.rlim_cur) 160 slim.rlim_cur = SVR4_RLIM_SAVED_MAX; 161 else 162 slim.rlim_cur = SVR4_RLIM_SAVED_CUR; 163 164 return copyout(&slim, uap->rlp, sizeof(*uap->rlp)); 165} 166 167 168int 169svr4_sys_setrlimit(td, uap) 170 struct thread *td; 171 struct svr4_sys_setrlimit_args *uap; 172{ 173 int rl = svr4_to_native_rl(uap->which); 174 struct rlimit blim, curlim; 175 struct svr4_rlimit slim; 176 int error; 177 178 if (rl == -1) 179 return EINVAL; 180 181 if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0) 182 return error; 183 184 PROC_LOCK(td->td_proc); 185 lim_rlimit(td->td_proc, rl, &curlim); 186 PROC_UNLOCK(td->td_proc); 187 188 /* 189 * if the limit is SVR4_RLIM_INFINITY, then we set it to our 190 * unlimited. 191 * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the 192 * new limit to the corresponding saved hard limit, and if 193 * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the 194 * corresponding saved soft limit. 195 * 196 */ 197 if (slim.rlim_max == SVR4_RLIM_INFINITY) 198 blim.rlim_max = RLIM_INFINITY; 199 else if (OKLIMIT(slim.rlim_max)) 200 blim.rlim_max = (rlim_t) slim.rlim_max; 201 else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX) 202 blim.rlim_max = curlim.rlim_max; 203 else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR) 204 blim.rlim_max = curlim.rlim_cur; 205 206 if (slim.rlim_cur == SVR4_RLIM_INFINITY) 207 blim.rlim_cur = RLIM_INFINITY; 208 else if (OKLIMIT(slim.rlim_cur)) 209 blim.rlim_cur = (rlim_t) slim.rlim_cur; 210 else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX) 211 blim.rlim_cur = curlim.rlim_max; 212 else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR) 213 blim.rlim_cur = curlim.rlim_cur; 214 215 return (kern_setrlimit(td, rl, &blim)); 216} 217 218 219int 220svr4_sys_getrlimit64(td, uap) 221 struct thread *td; 222 struct svr4_sys_getrlimit64_args *uap; 223{ 224 int rl = svr4_to_native_rl(uap->which); 225 struct rlimit blim; 226 struct svr4_rlimit64 slim; 227 228 if (rl == -1) 229 return EINVAL; 230 231 PROC_LOCK(td->td_proc); 232 lim_rlimit(td->td_proc, rl, &blim); 233 PROC_UNLOCK(td->td_proc); 234 235 /* 236 * Our infinity, is their maxfiles. 237 */ 238 if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY) 239 blim.rlim_max = maxfiles; 240 241 /* 242 * If the limit can be be represented, it is returned. 243 * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX 244 * else return SVR4_RLIM_SAVED_CUR 245 */ 246 if (blim.rlim_max == RLIM_INFINITY) 247 slim.rlim_max = SVR4_RLIM64_INFINITY; 248 else if (OKLIMIT64(blim.rlim_max)) 249 slim.rlim_max = (svr4_rlim64_t) blim.rlim_max; 250 else 251 slim.rlim_max = SVR4_RLIM64_SAVED_MAX; 252 253 if (blim.rlim_cur == RLIM_INFINITY) 254 slim.rlim_cur = SVR4_RLIM64_INFINITY; 255 else if (OKLIMIT64(blim.rlim_cur)) 256 slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur; 257 else if (blim.rlim_max == blim.rlim_cur) 258 slim.rlim_cur = SVR4_RLIM64_SAVED_MAX; 259 else 260 slim.rlim_cur = SVR4_RLIM64_SAVED_CUR; 261 262 return copyout(&slim, uap->rlp, sizeof(*uap->rlp)); 263} 264 265 266int 267svr4_sys_setrlimit64(td, uap) 268 struct thread *td; 269 struct svr4_sys_setrlimit64_args *uap; 270{ 271 int rl = svr4_to_native_rl(uap->which); 272 struct rlimit blim, curlim; 273 struct svr4_rlimit64 slim; 274 int error; 275 276 if (rl == -1) 277 return EINVAL; 278 279 if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0) 280 return error; 281 282 PROC_LOCK(td->td_proc); 283 lim_rlimit(td->td_proc, rl, &curlim); 284 PROC_UNLOCK(td->td_proc); 285 286 /* 287 * if the limit is SVR4_RLIM64_INFINITY, then we set it to our 288 * unlimited. 289 * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the 290 * new limit to the corresponding saved hard limit, and if 291 * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the 292 * corresponding saved soft limit. 293 * 294 */ 295 if (slim.rlim_max == SVR4_RLIM64_INFINITY) 296 blim.rlim_max = RLIM_INFINITY; 297 else if (OKLIMIT64(slim.rlim_max)) 298 blim.rlim_max = (rlim_t) slim.rlim_max; 299 else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX) 300 blim.rlim_max = curlim.rlim_max; 301 else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR) 302 blim.rlim_max = curlim.rlim_cur; 303 304 if (slim.rlim_cur == SVR4_RLIM64_INFINITY) 305 blim.rlim_cur = RLIM_INFINITY; 306 else if (OKLIMIT64(slim.rlim_cur)) 307 blim.rlim_cur = (rlim_t) slim.rlim_cur; 308 else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX) 309 blim.rlim_cur = curlim.rlim_max; 310 else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR) 311 blim.rlim_cur = curlim.rlim_cur; 312 313 return (kern_setrlimit(td, rl, &blim)); 314} 315