From owner-p4-projects@FreeBSD.ORG Fri Jun 12 21:13:11 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8A6AF1065674; Fri, 12 Jun 2009 21:13:11 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 434521065670 for ; Fri, 12 Jun 2009 21:13:11 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 2F8C18FC0C for ; Fri, 12 Jun 2009 21:13:11 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5CLDBHb055665 for ; Fri, 12 Jun 2009 21:13:11 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5CLDBrx055663 for perforce@freebsd.org; Fri, 12 Jun 2009 21:13:11 GMT (envelope-from trasz@freebsd.org) Date: Fri, 12 Jun 2009 21:13:11 GMT Message-Id: <200906122113.n5CLDBrx055663@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 164206 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jun 2009 21:13:12 -0000 http://perforce.freebsd.org/chv.cgi?CH=164206 Change 164206 by trasz@trasz_victim on 2009/06/12 21:12:12 WIP with adding calls to hrl_{alloc,free}(). It seems it's much more hairy than I originally thought. ;-/ Affected files ... .. //depot/projects/soc2009/trasz_limits/TODO#1 add .. //depot/projects/soc2009/trasz_limits/sys/compat/linux/linux_misc.c#4 edit .. //depot/projects/soc2009/trasz_limits/sys/compat/svr4/imgact_svr4.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/compat/svr4/svr4_filio.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/fdescfs/fdesc_vfsops.c#3 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/msdosfs/msdosfs_vnops.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/nfsclient/nfs_clbio.c#5 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/nwfs/nwfs_io.c#3 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/smbfs/smbfs_io.c#4 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/tmpfs/tmpfs_vnops.c#4 edit .. //depot/projects/soc2009/trasz_limits/sys/fs/unionfs/union_subr.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/gnu/fs/ext2fs/ext2_readwrite.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/i386/linux/imgact_linux.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/imgact_aout.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/imgact_elf.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/imgact_gzip.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#3 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_descrip.c#6 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#3 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_fork.c#3 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#6 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_prot.c#5 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#5 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/tty_pts.c#3 edit .. //depot/projects/soc2009/trasz_limits/sys/nfsclient/nfs_bio.c#6 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#5 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#3 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#2 edit .. //depot/projects/soc2009/trasz_limits/sys/ufs/ffs/ffs_vnops.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/vm/vm_unix.c#2 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/compat/linux/linux_misc.c#4 (text+ko) ==== @@ -36,6 +36,7 @@ #include #include #include +#include #if defined(__i386__) #include #endif @@ -359,14 +360,14 @@ * XXX - this is not complete. it should check current usage PLUS * the resources needed by this library. */ - PROC_LOCK(td->td_proc); - if (a_out->a_text > maxtsiz || - a_out->a_data + bss_size > lim_cur(td->td_proc, RLIMIT_DATA)) { - PROC_UNLOCK(td->td_proc); + if (a_out->a_text > maxtsiz) { error = ENOMEM; goto cleanup; } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_DATASIZE, + a_out->a_data + bss_size); + if (error) + goto cleanup; /* * Prevent more writers. ==== //depot/projects/soc2009/trasz_limits/sys/compat/svr4/imgact_svr4.c#2 (text+ko) ==== @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -106,13 +107,12 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(imgp->proc); - if (a_out->a_text > maxtsiz || - a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA)) { - PROC_UNLOCK(imgp->proc); - return (ENOMEM); - } - PROC_UNLOCK(imgp->proc); + if (a_out->a_text > maxtsiz) + return (ENOMEM); + error = hrl_allocated_proc(imgp->proc, HRL_RESOURCE_DATASIZE, + a_out->a_data + bss_size); + if (error) + return (error); VOP_UNLOCK(imgp->vp, 0); ==== //depot/projects/soc2009/trasz_limits/sys/compat/svr4/svr4_filio.c#2 (text+ko) ==== @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,9 @@ int idx = 0, cerr; u_long siz; + /* + * XXX: What is this for? + */ PROC_LOCK(td->td_proc); if (uap->nfds > lim_cur(td->td_proc, RLIMIT_NOFILE) && uap->nfds > FD_SETSIZE) { @@ -74,6 +78,8 @@ } PROC_UNLOCK(td->td_proc); + hrl_alloc(HRL_RESOURCE_OPENFILES, uap->nfds); + pa.fds = uap->fds; pa.nfds = uap->nfds; pa.timeout = uap->timeout; @@ -99,6 +105,7 @@ forget to update it if I add more code */ } done: + hrl_free(HRL_RESOURCE_OPENFILES, uap->nfds); free(pfd, M_TEMP); return error; } ==== //depot/projects/soc2009/trasz_limits/sys/fs/fdescfs/fdesc_vfsops.c#3 (text+ko) ==== @@ -198,6 +198,7 @@ PROC_LOCK(td->td_proc); lim = lim_cur(td->td_proc, RLIMIT_NOFILE); PROC_UNLOCK(td->td_proc); + /* XXX: Check HRL? */ fdp = td->td_proc->p_fd; FILEDESC_SLOCK(fdp); last = min(fdp->fd_nfiles, lim); ==== //depot/projects/soc2009/trasz_limits/sys/fs/msdosfs/msdosfs_vnops.c#2 (text+ko) ==== @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -700,14 +701,10 @@ * If they've exceeded their filesize limit, tell them about it. */ if (td != NULL) { - PROC_LOCK(td->td_proc); - if ((uoff_t)uio->uio_offset + uio->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); - return (EFBIG); - } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } /* ==== //depot/projects/soc2009/trasz_limits/sys/fs/nfsclient/nfs_clbio.c#5 (text+ko) ==== @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -1054,14 +1055,10 @@ * file servers have no limits, i don't think it matters */ if (p != NULL) { - PROC_LOCK(p); - if (uio->uio_offset + uio->uio_resid > - lim_cur(p, RLIMIT_FSIZE)) { - psignal(p, SIGXFSZ); - PROC_UNLOCK(p); - return (EFBIG); - } - PROC_UNLOCK(p); + error = hrl_allocated_proc(p, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } biosize = vp->v_mount->mnt_stat.f_iosize; ==== //depot/projects/soc2009/trasz_limits/sys/fs/nwfs/nwfs_io.c#3 (text+ko) ==== @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -236,14 +237,10 @@ } if (uiop->uio_resid == 0) return 0; if (td != NULL) { - PROC_LOCK(td->td_proc); - if (uiop->uio_offset + uiop->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); - return (EFBIG); - } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_FILESIZE, + (uoff_t)uiop->uio_offset + uiop->uio_resid); + if (error) + return (error); } error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cred); NCPVNDEBUG("after: ofs=%d,resid=%d\n",(int)uiop->uio_offset, uiop->uio_resid); ==== //depot/projects/soc2009/trasz_limits/sys/fs/smbfs/smbfs_io.c#4 (text+ko) ==== @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -278,14 +279,10 @@ if (uiop->uio_resid == 0) return 0; if (p != NULL) { - PROC_LOCK(p); - if (uiop->uio_offset + uiop->uio_resid > - lim_cur(p, RLIMIT_FSIZE)) { - psignal(p, SIGXFSZ); - PROC_UNLOCK(p); - return EFBIG; - } - PROC_UNLOCK(p); + error = hrl_allocated_proc(p, HRL_RESOURCE_FILESIZE, + (uoff_t)uiop->uio_offset + uiop->uio_resid); + if (error) + return (error); } smb_makescred(&scred, td, cred); error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); ==== //depot/projects/soc2009/trasz_limits/sys/fs/tmpfs/tmpfs_vnops.c#4 (text+ko) ==== @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -660,14 +661,10 @@ return (EFBIG); if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); - if (uio->uio_offset + uio->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); - return (EFBIG); - } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } extended = uio->uio_offset + uio->uio_resid > node->tn_size; ==== //depot/projects/soc2009/trasz_limits/sys/fs/unionfs/union_subr.c#2 (text+ko) ==== @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -780,6 +781,8 @@ rootinfo = uifind((uid_t)0); cred = crdup(cnp->cn_cred); chgproccnt(cred->cr_ruidinfo, 1, 0); + /* XXX: What about the return value? And what's the purpose of this, anyway? */ + hrl_alloc(HRL_RESOURCE_MAXPROCESSES, 1); change_euid(cred, rootinfo); change_ruid(cred, rootinfo); change_svuid(cred, (uid_t)0); @@ -830,6 +833,7 @@ unionfs_mkshadowdir_abort: cnp->cn_cred = credbk; chgproccnt(cred->cr_ruidinfo, -1, 0); + hrl_free(HRL_RESOURCE_MAXPROCESSES, 1); crfree(cred); return (error); ==== //depot/projects/soc2009/trasz_limits/sys/gnu/fs/ext2fs/ext2_readwrite.c#2 (text+ko) ==== @@ -210,14 +210,10 @@ */ td = uio->uio_td; if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); - if (uio->uio_offset + uio->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); - return (EFBIG); - } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } resid = uio->uio_resid; ==== //depot/projects/soc2009/trasz_limits/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c#2 (text+ko) ==== @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -599,14 +600,10 @@ #if 0 td = uio->uio_td; if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); - if (uio->uio_offset + uio->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); - return (EFBIG); - } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } #endif ==== //depot/projects/soc2009/trasz_limits/sys/i386/linux/imgact_linux.c#2 (text+ko) ==== @@ -105,13 +105,12 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(imgp->proc); - if (a_out->a_text > maxtsiz || - a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA)) { - PROC_UNLOCK(imgp->proc); + if (a_out->a_text > maxtsiz) return (ENOMEM); - } - PROC_UNLOCK(imgp->proc); + error = hrl_allocated_proc(imgp->proc, HRL_RESOURCE_DATASIZE, + a_out->a_data + bss_size); + if (error) + return (error); VOP_UNLOCK(imgp->vp, 0); ==== //depot/projects/soc2009/trasz_limits/sys/kern/imgact_aout.c#2 (text+ko) ==== @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -180,16 +181,13 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(imgp->proc); if (/* text can't exceed maximum text size */ - a_out->a_text > maxtsiz || - - /* data + bss can't exceed rlimit */ - a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA)) { - PROC_UNLOCK(imgp->proc); - return (ENOMEM); - } - PROC_UNLOCK(imgp->proc); + a_out->a_text > maxtsiz) + return (ENOMEM); + error = hrl_allocated_proc(imgp->proc, HRL_RESOURCE_DATASIZE, + a_out->a_data + bss_size); + if (error) + return (error); /* * Avoid a possible deadlock if the current address space is destroyed ==== //depot/projects/soc2009/trasz_limits/sys/kern/imgact_elf.c#2 (text+ko) ==== @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -787,14 +788,18 @@ * limits after loading the segments since we do * not actually fault in all the segments pages. */ - PROC_LOCK(imgp->proc); - if (data_size > lim_cur(imgp->proc, RLIMIT_DATA) || - text_size > maxtsiz || - total_size > lim_cur(imgp->proc, RLIMIT_VMEM)) { - PROC_UNLOCK(imgp->proc); + if (text_size > maxtsiz) return (ENOMEM); - } + error = hrl_allocated_proc(imgp->proc, HRL_RESOURCE_DATASIZE, + data_size); + if (error) + return (error); + error = hrl_allocated_proc(imgp->proc, HRL_RESOURCE_VMEMORYUSE, + total_size); + if (error) + return (error); + PROC_LOCK(imgp->proc); vmspace->vm_tsize = text_size >> PAGE_SHIFT; vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr; vmspace->vm_dsize = data_size >> PAGE_SHIFT; ==== //depot/projects/soc2009/trasz_limits/sys/kern/imgact_gzip.c#2 (text+ko) ==== @@ -210,18 +210,15 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(gz->ip->proc); if ( /* text can't exceed maximum text size */ - gz->a_out.a_text > maxtsiz || - - /* data + bss can't exceed rlimit */ - gz->a_out.a_data + gz->bss_size > - lim_cur(gz->ip->proc, RLIMIT_DATA)) { - PROC_UNLOCK(gz->ip->proc); + gz->a_out.a_text > maxtsiz) { gz->where = __LINE__; return (ENOMEM); } - PROC_UNLOCK(gz->ip->proc); + error = hrl_allocated_proc(gz->ip->proc, HRL_RESOURCE_DATASIZE, + gz->a_out.a_data + gz->bss_size); + if (error) + return (error); /* Find out how far we should go */ gz->file_end = gz->file_offset + gz->a_out.a_text + gz->a_out.a_data; ==== //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#3 (text+ko) ==== @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -518,6 +519,7 @@ * Charge root for one process. */ (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0); + hrl_alloc(HRL_RESOURCE_MAXPROCESSES, 1); } SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL); ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_descrip.c#6 (text+ko) ==== @@ -279,6 +279,7 @@ td->td_retval[0] = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); PROC_UNLOCK(p); + /* XXX: Use HRL? */ return (0); } @@ -721,6 +722,7 @@ return (flags & DUP_FCNTL ? EINVAL : EBADF); PROC_LOCK(p); maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); + /* XXX: Add HRL accounting. */ PROC_UNLOCK(p); if (new >= maxfd) return (flags & DUP_FCNTL ? EINVAL : EMFILE); @@ -1366,6 +1368,7 @@ PROC_LOCK(p); maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); + /* XXX: Add HRL accounting. */ PROC_UNLOCK(p); /* @@ -1413,6 +1416,7 @@ PROC_LOCK(p); lim = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); + /* XXX: Add HRL accounting. */ PROC_UNLOCK(p); if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) return (1); ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#3 (text+ko) ==== @@ -67,6 +67,7 @@ #include #include /* for acct_process() function prototype */ #include +#include #include #include #include @@ -808,6 +809,7 @@ * Decrement the count of procs running with this uid. */ (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); + hrl_free_proc(p, HRL_RESOURCE_MAXPROCESSES, 1); /* * Free credentials, arguments, and sigacts. ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_fork.c#3 (text+ko) ==== @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -332,14 +333,18 @@ * XXXRW: Can we avoid privilege here if it's not needed? */ error = priv_check_cred(td->td_ucred, PRIV_PROC_LIMIT, 0); - if (error == 0) + if (error == 0) { ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0); - else { + error = hrl_alloc_proc(p1, HRL_RESOURCE_MAXPROCESSES, 1); + } else { PROC_LOCK(p1); ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, lim_cur(p1, RLIMIT_NPROC)); + error = hrl_alloc_proc(p1, HRL_RESOURCE_MAXPROCESSES, 1); PROC_UNLOCK(p1); } + if (ok != !error) + printf("fork1: ok = %d, error = %d\n", ok, error); if (!ok) { error = EAGAIN; goto fail; ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#6 (text+ko) ==== @@ -100,19 +100,53 @@ MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits"); int -hrl_alloc(int resource, uint64_t amount) +hrl_alloc_proc(struct proc *p, int resource, uint64_t amount) { KASSERT(amount > 0, ("invalid amount")); + /* + * XXX: Obviously wrong, fix later. + */ + p->p_resources[resource] += amount; + + /* + * XXX: When denying, return proper errno - EFSIZ, ENOMEM etc. + */ + + return (0); +} + +int +hrl_allocated_proc(struct proc *p, int resource, uint64_t amount) +{ + /* + * XXX: Make sure process can lower its resource consumption, + * even when already above the limit. + */ + return (0); } void -hrl_free(int resource, uint64_t amount) +hrl_free_proc(struct proc *p, int resource, uint64_t amount) { KASSERT(amount > 0, ("invalid amount")); + + p->p_resources[resource] -= amount; +} + +int +hrl_alloc(int resource, uint64_t amount) +{ + return (hrl_alloc_proc(curproc, resource, amount)); +} + +void +hrl_free(int resource, uint64_t amount) +{ + hrl_free_proc(curproc, resource, amount); } void @@ -129,7 +163,7 @@ /* * Removing a limit. */ - if (amount == 0) { + if (amount == -1) { mtx_lock(&hrl_lock); node = RB_FIND(hrl_tree, &hrls, &searched); if (node != NULL) { ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_prot.c#5 (text+ko) ==== @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -2029,11 +2030,14 @@ { (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); + hrl_free(HRL_RESOURCE_MAXPROCESSES, 1); newcred->cr_ruid = ruip->ui_uid; uihold(ruip); uifree(newcred->cr_ruidinfo); newcred->cr_ruidinfo = ruip; (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); + /* XXX: What about the return value? */ + hrl_alloc(HRL_RESOURCE_MAXPROCESSES, 1); } /*- ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#5 (text+ko) ==== @@ -712,9 +712,9 @@ hrl_adjust(subject, id, subject, resource, action, lim->rlim_cur); } else { - hrl_adjust(subject, id, subject, resource, HRL_ACTION_DENY, 0); + hrl_adjust(subject, id, subject, resource, HRL_ACTION_DENY, -1); if (action != -1) - hrl_adjust(subject, id, subject, resource, action, 0); + hrl_adjust(subject, id, subject, resource, action, -1); } } ==== //depot/projects/soc2009/trasz_limits/sys/kern/tty_pts.c#3 (text+ko) ==== @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -680,6 +681,7 @@ free_unr(pts_pool, psc->pts_unit); chgptscnt(psc->pts_uidinfo, -1, 0); + hrl_free(HRL_RESOURCE_PTY, 1); uifree(psc->pts_uidinfo); knlist_destroy(&psc->pts_inpoll.si_note); @@ -707,7 +709,7 @@ static int pts_alloc(int fflags, struct thread *td, struct file *fp) { - int unit, ok; + int unit, ok, error; struct tty *tp; struct pts_softc *psc; struct proc *p = td->td_proc; @@ -716,7 +718,10 @@ /* Resource limiting. */ PROC_LOCK(p); ok = chgptscnt(uid, 1, lim_cur(p, RLIMIT_NPTS)); + error = hrl_alloc(HRL_RESOURCE_PTY, 1); PROC_UNLOCK(p); + if (ok != !error) + printf("pts_alloc: ok = %d, error = %d\n", ok, error); if (!ok) return (EAGAIN); @@ -724,11 +729,13 @@ unit = alloc_unr(pts_pool); if (unit < 0) { chgptscnt(uid, -1, 0); + hrl_free(HRL_RESOURCE_PTY, 1); return (EAGAIN); } if (unit > pts_maxdev) { free_unr(pts_pool, unit); chgptscnt(uid, -1, 0); + hrl_free(HRL_RESOURCE_PTY, 1); return (EAGAIN); } @@ -758,7 +765,7 @@ pts_alloc_external(int fflags, struct thread *td, struct file *fp, struct cdev *dev, const char *name) { - int ok; + int ok, error; struct tty *tp; struct pts_softc *psc; struct proc *p = td->td_proc; @@ -767,7 +774,10 @@ /* Resource limiting. */ PROC_LOCK(p); ok = chgptscnt(uid, 1, lim_cur(p, RLIMIT_NPTS)); + error = hrl_alloc(HRL_RESOURCE_PTY, 1); PROC_UNLOCK(p); + if (ok != !error) + printf("pts_alloc: ok = %d, error = %d\n", ok, error); if (!ok) return (EAGAIN); ==== //depot/projects/soc2009/trasz_limits/sys/nfsclient/nfs_bio.c#6 (text+ko) ==== @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -952,14 +953,10 @@ * file servers have no limits, i don't think it matters */ if (p != NULL) { - PROC_LOCK(p); - if (uio->uio_offset + uio->uio_resid > - lim_cur(p, RLIMIT_FSIZE)) { - psignal(p, SIGXFSZ); - PROC_UNLOCK(p); - return (EFBIG); - } - PROC_UNLOCK(p); + error = hrl_allocated_proc(p, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } biosize = vp->v_mount->mnt_stat.f_iosize; ==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#5 (text+ko) ==== @@ -94,8 +94,14 @@ #ifdef _KERNEL +struct proc; + int hrl_alloc(int object, uint64_t amount); +int hrl_allocated(int object, uint64_t amount); void hrl_free(int object, uint64_t amount); +int hrl_alloc_proc(struct proc *p, int object, uint64_t amount); +int hrl_allocated_proc(struct proc *p, int object, uint64_t amount); +void hrl_free_proc(struct proc *p, int object, uint64_t amount); void hrl_adjust(int subject, id_t subject_id, int per, int resource, int action, int64_t amount); ==== //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#3 (text+ko) ==== @@ -44,6 +44,7 @@ #ifndef _KERNEL #include #endif +#include #include #include #include @@ -545,6 +546,7 @@ LIST_HEAD(, mqueue_notifier) p_mqnotifier; /* (c) mqueue notifiers.*/ struct kdtrace_proc *p_dtrace; /* (*) DTrace-specific data. */ struct cv p_pwait; /* (*) wait cv for exit/exec */ + int64_t p_resources[HRL_RESOURCE_MAX + 1]; }; #define p_session p_pgrp->pg_session ==== //depot/projects/soc2009/trasz_limits/sys/sys/resourcevar.h#2 (text+ko) ==== @@ -38,6 +38,7 @@ #ifdef _KERNEL #include #include +#include #endif /* @@ -94,6 +95,7 @@ long ui_ptscnt; /* (b) number of pseudo-terminals */ uid_t ui_uid; /* (a) uid */ u_int ui_ref; /* (b) reference count */ + int64_t ui_resources[HRL_RESOURCE_MAX + 1]; }; struct proc; ==== //depot/projects/soc2009/trasz_limits/sys/ufs/ffs/ffs_vnops.c#2 (text+ko) ==== @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -684,14 +685,10 @@ */ td = uio->uio_td; if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); - if (uio->uio_offset + uio->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); - return (EFBIG); - } - PROC_UNLOCK(td->td_proc); + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_FILESIZE, + (uoff_t)uio->uio_offset + uio->uio_resid); + if (error) + return (error); } resid = uio->uio_resid; ==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_unix.c#2 (text+ko) ==== @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD: src/sys/vm/vm_unix.c,v 1.49 2009/04/11 22:34:08 alc Exp $"); #include +#include #include #include #include @@ -73,16 +74,10 @@ { struct vmspace *vm = td->td_proc->p_vmspace; vm_offset_t new, old, base; - rlim_t datalim, vmemlim; int rv; int error = 0; boolean_t do_map_wirefuture; - PROC_LOCK(td->td_proc); - datalim = lim_cur(td->td_proc, RLIMIT_DATA); - vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM); - PROC_UNLOCK(td->td_proc); - do_map_wirefuture = FALSE; new = round_page((vm_offset_t)uap->nsize); vm_map_lock(&vm->vm_map); @@ -90,14 +85,10 @@ base = round_page((vm_offset_t) vm->vm_daddr); old = base + ctob(vm->vm_dsize); if (new > base) { - /* - * Check the resource limit, but allow a process to reduce - * its usage, even if it remains over the limit. - */ - if (new - base > datalim && new > old) { - error = ENOMEM; + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_DATASIZE, + new - base); + if (error) goto done; - } if (new > vm_map_max(&vm->vm_map)) { error = ENOMEM; goto done; @@ -112,10 +103,10 @@ goto done; } if (new > old) { - if (vm->vm_map.size + (new - old) > vmemlim) { - error = ENOMEM; + error = hrl_allocated_proc(td->td_proc, HRL_RESOURCE_VMEMORYUSE, + vm->vm_map.size + (new - old)); + if (error) goto done; - } rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new, VM_PROT_RW, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) {