sys/kern/kern_plimit.c
int
kern_setrlimit(u_int which, struct rlimit *limp)
{
        struct proc *p = curproc;
	struct plimit *limit;
        struct rlimit *alimp;
        int error;

        if (which >= RLIM_NLIMITS)
                return (EINVAL);

	/*
	 * We will be modifying a resource, make a copy if necessary.
	 */
	plimit_modify(p, -1, NULL);
	limit = p->p_limit;
        alimp = &limit->pl_rlimit[which];

        /*
         * Preserve historical bugs by treating negative limits as unsigned.
         */
        if (limp->rlim_cur < 0)
                limp->rlim_cur = RLIM_INFINITY;
        if (limp->rlim_max < 0)
                limp->rlim_max = RLIM_INFINITY;

	spin_lock(&limit->p_spin);
        if (limp->rlim_cur > alimp->rlim_max ||
            limp->rlim_max > alimp->rlim_max) {
		spin_unlock(&limit->p_spin);
                error = priv_check_cred(p->p_ucred, PRIV_PROC_SETRLIMIT, 0);
                if (error)
                        return (error);
	} else {
		spin_unlock(&limit->p_spin);
	}
        if (limp->rlim_cur > limp->rlim_max)
                limp->rlim_cur = limp->rlim_max;

        switch (which) {
        case RLIMIT_CPU:
		spin_lock(&limit->p_spin);
                if (limp->rlim_cur > RLIM_INFINITY / (rlim_t)1000000)
                        limit->p_cpulimit = RLIM_INFINITY;
                else
                        limit->p_cpulimit = (rlim_t)1000000 * limp->rlim_cur;
		spin_unlock(&limit->p_spin);
                break;
        case RLIMIT_DATA:
                if (limp->rlim_cur > maxdsiz)
                        limp->rlim_cur = maxdsiz;
                if (limp->rlim_max > maxdsiz)
                        limp->rlim_max = maxdsiz;
                break;

        case RLIMIT_STACK:
                if (limp->rlim_cur > maxssiz)
                        limp->rlim_cur = maxssiz;
                if (limp->rlim_max > maxssiz)
                        limp->rlim_max = maxssiz;
                /*
                 * Stack is allocated to the max at exec time with only
                 * "rlim_cur" bytes accessible.  If stack limit is going
                 * up make more accessible, if going down make inaccessible.
                 */
		spin_lock(&limit->p_spin);
                if (limp->rlim_cur != alimp->rlim_cur) {
                        vm_offset_t addr;
                        vm_size_t size;
                        vm_prot_t prot;

                        if (limp->rlim_cur > alimp->rlim_cur) {
                                prot = VM_PROT_ALL;
                                size = limp->rlim_cur - alimp->rlim_cur;
                                addr = USRSTACK - limp->rlim_cur;
                        } else {
                                prot = VM_PROT_NONE;
                                size = alimp->rlim_cur - limp->rlim_cur;
                                addr = USRSTACK - alimp->rlim_cur;
                        }
			spin_unlock(&limit->p_spin);
                        addr = trunc_page(addr);
                        size = round_page(size);
                        vm_map_protect(&p->p_vmspace->vm_map,
				       addr, addr+size, prot, FALSE);
                } else {
			spin_unlock(&limit->p_spin);
		}
                break;

        case RLIMIT_NOFILE:
                if (limp->rlim_cur > maxfilesperproc)
                        limp->rlim_cur = maxfilesperproc;
                if (limp->rlim_max > maxfilesperproc)
                        limp->rlim_max = maxfilesperproc;
                break;

        case RLIMIT_NPROC:
                if (limp->rlim_cur > maxprocperuid)
                        limp->rlim_cur = maxprocperuid;
                if (limp->rlim_max > maxprocperuid)
                        limp->rlim_max = maxprocperuid;
                if (limp->rlim_cur < 1)
                        limp->rlim_cur = 1;
                if (limp->rlim_max < 1)
                        limp->rlim_max = 1;
                break;
        case RLIMIT_POSIXLOCKS:
                if (limp->rlim_cur > maxposixlocksperuid)
                        limp->rlim_cur = maxposixlocksperuid;
                if (limp->rlim_max > maxposixlocksperuid)
                        limp->rlim_max = maxposixlocksperuid;
                break;
        }
	spin_lock(&limit->p_spin);
        *alimp = *limp;
	spin_unlock(&limit->p_spin);
        return (0);
}
/*
 * Modify a resource limit (from system call)
 *
 * MPSAFE
 */
Modify a resource limit (from system call)
MPSAFE
Modify a resource limit ( from system call ) MPSAFE
int
kern_setrlimit(u_int which, struct rlimit *limp)
{
        struct proc *p = curproc;
	struct plimit *limit;
        struct rlimit *alimp;
        int error;
        if (which >= RLIM_NLIMITS)
                return (EINVAL);
	plimit_modify(p, -1, NULL);
	limit = p->p_limit;
        alimp = &limit->pl_rlimit[which];
        if (limp->rlim_cur < 0)
                limp->rlim_cur = RLIM_INFINITY;
        if (limp->rlim_max < 0)
                limp->rlim_max = RLIM_INFINITY;
	spin_lock(&limit->p_spin);
        if (limp->rlim_cur > alimp->rlim_max ||
            limp->rlim_max > alimp->rlim_max) {
		spin_unlock(&limit->p_spin);
                error = priv_check_cred(p->p_ucred, PRIV_PROC_SETRLIMIT, 0);
                if (error)
                        return (error);
	} else {
		spin_unlock(&limit->p_spin);
	}
        if (limp->rlim_cur > limp->rlim_max)
                limp->rlim_cur = limp->rlim_max;
        switch (which) {
        case RLIMIT_CPU:
		spin_lock(&limit->p_spin);
                if (limp->rlim_cur > RLIM_INFINITY / (rlim_t)1000000)
                        limit->p_cpulimit = RLIM_INFINITY;
                else
                        limit->p_cpulimit = (rlim_t)1000000 * limp->rlim_cur;
		spin_unlock(&limit->p_spin);
                break;
        case RLIMIT_DATA:
                if (limp->rlim_cur > maxdsiz)
                        limp->rlim_cur = maxdsiz;
                if (limp->rlim_max > maxdsiz)
                        limp->rlim_max = maxdsiz;
                break;
        case RLIMIT_STACK:
                if (limp->rlim_cur > maxssiz)
                        limp->rlim_cur = maxssiz;
                if (limp->rlim_max > maxssiz)
                        limp->rlim_max = maxssiz;
		spin_lock(&limit->p_spin);
                if (limp->rlim_cur != alimp->rlim_cur) {
                        vm_offset_t addr;
                        vm_size_t size;
                        vm_prot_t prot;
                        if (limp->rlim_cur > alimp->rlim_cur) {
                                prot = VM_PROT_ALL;
                                size = limp->rlim_cur - alimp->rlim_cur;
                                addr = USRSTACK - limp->rlim_cur;
                        } else {
                                prot = VM_PROT_NONE;
                                size = alimp->rlim_cur - limp->rlim_cur;
                                addr = USRSTACK - alimp->rlim_cur;
                        }
			spin_unlock(&limit->p_spin);
                        addr = trunc_page(addr);
                        size = round_page(size);
                        vm_map_protect(&p->p_vmspace->vm_map,
				       addr, addr+size, prot, FALSE);
                } else {
			spin_unlock(&limit->p_spin);
		}
                break;
        case RLIMIT_NOFILE:
                if (limp->rlim_cur > maxfilesperproc)
                        limp->rlim_cur = maxfilesperproc;
                if (limp->rlim_max > maxfilesperproc)
                        limp->rlim_max = maxfilesperproc;
                break;
        case RLIMIT_NPROC:
                if (limp->rlim_cur > maxprocperuid)
                        limp->rlim_cur = maxprocperuid;
                if (limp->rlim_max > maxprocperuid)
                        limp->rlim_max = maxprocperuid;
                if (limp->rlim_cur < 1)
                        limp->rlim_cur = 1;
                if (limp->rlim_max < 1)
                        limp->rlim_max = 1;
                break;
        case RLIMIT_POSIXLOCKS:
                if (limp->rlim_cur > maxposixlocksperuid)
                        limp->rlim_cur = maxposixlocksperuid;
                if (limp->rlim_max > maxposixlocksperuid)
                        limp->rlim_max = maxposixlocksperuid;
                break;
        }
	spin_lock(&limit->p_spin);
        *alimp = *limp;
	spin_unlock(&limit->p_spin);
        return (0);
}
int kern_setrlimit ( u_int which , struct rlimit * limp ) { struct proc * p = curproc ; struct plimit * limit ; struct rlimit * alimp ; int error ; if ( which >= RLIM_NLIMITS ) return ( EINVAL ) ; plimit_modify ( p , -1 , NULL ) ; limit = p -> p_limit ; alimp = & limit -> pl_rlimit [ which ] ; if ( limp -> rlim_cur < 0 ) limp -> rlim_cur = RLIM_INFINITY ; if ( limp -> rlim_max < 0 ) limp -> rlim_max = RLIM_INFINITY ; spin_lock ( & limit -> p_spin ) ; if ( limp -> rlim_cur > alimp -> rlim_max || limp -> rlim_max > alimp -> rlim_max ) { spin_unlock ( & limit -> p_spin ) ; error = priv_check_cred ( p -> p_ucred , PRIV_PROC_SETRLIMIT , 0 ) ; if ( error ) return ( error ) ; } else { spin_unlock ( & limit -> p_spin ) ; } if ( limp -> rlim_cur > limp -> rlim_max ) limp -> rlim_cur = limp -> rlim_max ; switch ( which ) { case RLIMIT_CPU : spin_lock ( & limit -> p_spin ) ; if ( limp -> rlim_cur > RLIM_INFINITY / ( rlim_t ) 1000000 ) limit -> p_cpulimit = RLIM_INFINITY ; else limit -> p_cpulimit = ( rlim_t ) 1000000 * limp -> rlim_cur ; spin_unlock ( & limit -> p_spin ) ; break ; case RLIMIT_DATA : if ( limp -> rlim_cur > maxdsiz ) limp -> rlim_cur = maxdsiz ; if ( limp -> rlim_max > maxdsiz ) limp -> rlim_max = maxdsiz ; break ; case RLIMIT_STACK : if ( limp -> rlim_cur > maxssiz ) limp -> rlim_cur = maxssiz ; if ( limp -> rlim_max > maxssiz ) limp -> rlim_max = maxssiz ; spin_lock ( & limit -> p_spin ) ; if ( limp -> rlim_cur != alimp -> rlim_cur ) { vm_offset_t addr ; vm_size_t size ; vm_prot_t prot ; if ( limp -> rlim_cur > alimp -> rlim_cur ) { prot = VM_PROT_ALL ; size = limp -> rlim_cur - alimp -> rlim_cur ; addr = USRSTACK - limp -> rlim_cur ; } else { prot = VM_PROT_NONE ; size = alimp -> rlim_cur - limp -> rlim_cur ; addr = USRSTACK - alimp -> rlim_cur ; } spin_unlock ( & limit -> p_spin ) ; addr = trunc_page ( addr ) ; size = round_page ( size ) ; vm_map_protect ( & p -> p_vmspace -> vm_map , addr , addr + size , prot , FALSE ) ; } else { spin_unlock ( & limit -> p_spin ) ; } break ; case RLIMIT_NOFILE : if ( limp -> rlim_cur > maxfilesperproc ) limp -> rlim_cur = maxfilesperproc ; if ( limp -> rlim_max > maxfilesperproc ) limp -> rlim_max = maxfilesperproc ; break ; case RLIMIT_NPROC : if ( limp -> rlim_cur > maxprocperuid ) limp -> rlim_cur = maxprocperuid ; if ( limp -> rlim_max > maxprocperuid ) limp -> rlim_max = maxprocperuid ; if ( limp -> rlim_cur < 1 ) limp -> rlim_cur = 1 ; if ( limp -> rlim_max < 1 ) limp -> rlim_max = 1 ; break ; case RLIMIT_POSIXLOCKS : if ( limp -> rlim_cur > maxposixlocksperuid ) limp -> rlim_cur = maxposixlocksperuid ; if ( limp -> rlim_max > maxposixlocksperuid ) limp -> rlim_max = maxposixlocksperuid ; break ; } spin_lock ( & limit -> p_spin ) ; * alimp = * limp ; spin_unlock ( & limit -> p_spin ) ; return ( 0 ) ; }
Modify a resource limit (from system call)
 MPSAFE
Modify a resource limit ( from system call ) MPSAFE
/*
	 * We will be modifying a resource, make a copy if necessary.
	 */ /*
         * Preserve historical bugs by treating negative limits as unsigned.
         */ /*
                 * Stack is allocated to the max at exec time with only
                 * "rlim_cur" bytes accessible.  If stack limit is going
                 * up make more accessible, if going down make inaccessible.
                 */