Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_rlimit.c revision 1.1.16.1
      1  1.1.16.1  thorpej /*	$NetBSD: netbsd32_rlimit.c,v 1.1.16.1 2021/04/03 22:28:42 thorpej Exp $	*/
      2       1.1      mrg 
      3       1.1      mrg /*
      4       1.1      mrg  * Copyright (c) 1998, 2001, 2008, 2018 Matthew R. Green
      5       1.1      mrg  * All rights reserved.
      6       1.1      mrg  *
      7       1.1      mrg  * Redistribution and use in source and binary forms, with or without
      8       1.1      mrg  * modification, are permitted provided that the following conditions
      9       1.1      mrg  * are met:
     10       1.1      mrg  * 1. Redistributions of source code must retain the above copyright
     11       1.1      mrg  *    notice, this list of conditions and the following disclaimer.
     12       1.1      mrg  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1      mrg  *    notice, this list of conditions and the following disclaimer in the
     14       1.1      mrg  *    documentation and/or other materials provided with the distribution.
     15       1.1      mrg  *
     16       1.1      mrg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17       1.1      mrg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18       1.1      mrg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19       1.1      mrg  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20       1.1      mrg  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21       1.1      mrg  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22       1.1      mrg  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23       1.1      mrg  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24       1.1      mrg  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25       1.1      mrg  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26       1.1      mrg  * SUCH DAMAGE.
     27       1.1      mrg  *
     28       1.1      mrg  * from: NetBSD: netbsd32_netbsd.c,v 1.218 2018/08/10 21:44:58 pgoyette Exp
     29       1.1      mrg  */
     30       1.1      mrg 
     31       1.1      mrg /* rlimit netbsd32 related code */
     32       1.1      mrg 
     33       1.1      mrg #include <sys/cdefs.h>
     34  1.1.16.1  thorpej __KERNEL_RCSID(0, "$NetBSD: netbsd32_rlimit.c,v 1.1.16.1 2021/04/03 22:28:42 thorpej Exp $");
     35       1.1      mrg 
     36       1.1      mrg #include <sys/param.h>
     37       1.1      mrg #include <sys/systm.h>
     38       1.1      mrg #include <sys/resource.h>
     39       1.1      mrg #include <sys/exec.h>
     40       1.1      mrg 
     41       1.1      mrg #include <compat/netbsd32/netbsd32.h>
     42       1.1      mrg #include <compat/netbsd32/netbsd32_syscall.h>
     43       1.1      mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
     44       1.1      mrg #include <compat/netbsd32/netbsd32_conv.h>
     45       1.1      mrg 
     46       1.1      mrg #define LIMITCHECK(a, b) ((a) != RLIM_INFINITY && (a) > (b))
     47       1.1      mrg 
     48       1.1      mrg static void
     49       1.1      mrg fixlimit(int which, struct rlimit *alim)
     50       1.1      mrg {
     51       1.1      mrg 	switch (which) {
     52       1.1      mrg 	case RLIMIT_DATA:
     53       1.1      mrg 		if (LIMITCHECK(alim->rlim_cur, MAXDSIZ32))
     54       1.1      mrg 			alim->rlim_cur = MAXDSIZ32;
     55       1.1      mrg 		if (LIMITCHECK(alim->rlim_max, MAXDSIZ32))
     56       1.1      mrg 			alim->rlim_max = MAXDSIZ32;
     57       1.1      mrg 		return;
     58       1.1      mrg 	case RLIMIT_STACK:
     59       1.1      mrg 		if (LIMITCHECK(alim->rlim_cur, MAXSSIZ32))
     60       1.1      mrg 			alim->rlim_cur = MAXSSIZ32;
     61       1.1      mrg 		if (LIMITCHECK(alim->rlim_max, MAXSSIZ32))
     62       1.1      mrg 			alim->rlim_max = MAXSSIZ32;
     63       1.1      mrg 		return;
     64       1.1      mrg 	default:
     65       1.1      mrg 		return;
     66       1.1      mrg 	}
     67       1.1      mrg }
     68       1.1      mrg 
     69       1.1      mrg int
     70       1.1      mrg netbsd32_getrlimit(struct lwp *l, const struct netbsd32_getrlimit_args *uap,
     71       1.1      mrg     register_t *retval)
     72       1.1      mrg {
     73       1.1      mrg 	/* {
     74       1.1      mrg 		syscallarg(int) which;
     75       1.1      mrg 		syscallarg(netbsd32_rlimitp_t) rlp;
     76       1.1      mrg 	} */
     77       1.1      mrg 	int which = SCARG(uap, which);
     78       1.1      mrg 	struct rlimit alim;
     79       1.1      mrg 
     80       1.1      mrg 	if ((u_int)which >= RLIM_NLIMITS)
     81       1.1      mrg 		return EINVAL;
     82       1.1      mrg 
     83       1.1      mrg 	alim = l->l_proc->p_rlimit[which];
     84       1.1      mrg 
     85       1.1      mrg 	fixlimit(which, &alim);
     86       1.1      mrg 
     87       1.1      mrg 	return copyout(&alim, SCARG_P32(uap, rlp), sizeof(alim));
     88       1.1      mrg }
     89       1.1      mrg 
     90       1.1      mrg int
     91       1.1      mrg netbsd32_setrlimit(struct lwp *l, const struct netbsd32_setrlimit_args *uap,
     92       1.1      mrg     register_t *retval)
     93       1.1      mrg {
     94       1.1      mrg 	/* {
     95       1.1      mrg 		syscallarg(int) which;
     96       1.1      mrg 		syscallarg(const netbsd32_rlimitp_t) rlp;
     97       1.1      mrg 	} */
     98       1.1      mrg 		int which = SCARG(uap, which);
     99       1.1      mrg 	struct rlimit alim;
    100       1.1      mrg 	int error;
    101       1.1      mrg 
    102       1.1      mrg 	if ((u_int)which >= RLIM_NLIMITS)
    103       1.1      mrg 		return EINVAL;
    104       1.1      mrg 
    105       1.1      mrg 	error = copyin(SCARG_P32(uap, rlp), &alim, sizeof(struct rlimit));
    106       1.1      mrg 	if (error)
    107  1.1.16.1  thorpej 		return error;
    108       1.1      mrg 
    109       1.1      mrg 	fixlimit(which, &alim);
    110       1.1      mrg 
    111       1.1      mrg 	return dosetrlimit(l, l->l_proc, which, &alim);
    112       1.1      mrg }
    113       1.1      mrg 
    114       1.1      mrg void
    115       1.1      mrg netbsd32_adjust_limits(struct proc *p)
    116       1.1      mrg {
    117       1.1      mrg 	static const struct {
    118       1.1      mrg 		int id;
    119       1.1      mrg 		rlim_t lim;
    120       1.1      mrg 	} lm[] = {
    121       1.1      mrg 		{ RLIMIT_DATA,	MAXDSIZ32 },
    122       1.1      mrg 		{ RLIMIT_STACK, MAXSSIZ32 },
    123       1.1      mrg 	};
    124       1.1      mrg 	size_t i;
    125       1.1      mrg 	struct plimit *lim;
    126       1.1      mrg 	struct rlimit *rlim;
    127       1.1      mrg 
    128       1.1      mrg 	/*
    129       1.1      mrg 	 * We can only reduce the current limits, we cannot stop external
    130       1.1      mrg 	 * processes from changing them (eg via sysctl) later on.
    131       1.1      mrg 	 * So there is no point trying to lock out such changes here.
    132       1.1      mrg 	 *
    133       1.1      mrg 	 * If we assume that rlim_cur/max are accessed using atomic
    134       1.1      mrg 	 * operations, we don't need to lock against any other updates
    135       1.1      mrg 	 * that might happen if the plimit structure is shared writable
    136       1.1      mrg 	 * between multiple processes.
    137       1.1      mrg 	 */
    138       1.1      mrg 
    139       1.1      mrg 	/* Scan to determine is any limits are out of range */
    140       1.1      mrg 	lim = p->p_limit;
    141       1.1      mrg 	for (i = 0; ; i++) {
    142       1.1      mrg 		if (i >= __arraycount(lm))
    143       1.1      mrg 			/* All in range */
    144       1.1      mrg 			return;
    145       1.1      mrg 		rlim = lim->pl_rlimit + lm[i].id;
    146       1.1      mrg 		if (LIMITCHECK(rlim->rlim_cur, lm[i].lim))
    147       1.1      mrg 			break;
    148       1.1      mrg 		if (LIMITCHECK(rlim->rlim_max, lm[i].lim))
    149       1.1      mrg 			break;
    150       1.1      mrg 	}
    151       1.1      mrg 
    152       1.1      mrg 	lim_privatise(p);
    153       1.1      mrg 
    154       1.1      mrg 	lim = p->p_limit;
    155       1.1      mrg 	for (i = 0; i < __arraycount(lm); i++) {
    156       1.1      mrg 		rlim = lim->pl_rlimit + lm[i].id;
    157       1.1      mrg 		if (LIMITCHECK(rlim->rlim_cur, lm[i].lim))
    158       1.1      mrg 			rlim->rlim_cur = lm[i].lim;
    159       1.1      mrg 		if (LIMITCHECK(rlim->rlim_max, lm[i].lim))
    160       1.1      mrg 			rlim->rlim_max = lm[i].lim;
    161       1.1      mrg 	}
    162       1.1      mrg }
    163