Module Name: src Committed By: elad Date: Fri Oct 2 22:38:45 UTC 2009
Modified Files: src/sys/kern: kern_resource.c sys_process.c src/sys/secmodel/suser: secmodel_suser.c src/sys/sys: proc.h Log Message: Move rlimit policy back to the subsystem. For this we needed proc_uidmatch() exposed, which makes a lot of sense, so put it back in sys_process.c for use in other places as well. To generate a diff of this commit: cvs rdiff -u -r1.152 -r1.153 src/sys/kern/kern_resource.c cvs rdiff -u -r1.148 -r1.149 src/sys/kern/sys_process.c cvs rdiff -u -r1.5 -r1.6 src/sys/secmodel/suser/secmodel_suser.c cvs rdiff -u -r1.290 -r1.291 src/sys/sys/proc.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_resource.c diff -u src/sys/kern/kern_resource.c:1.152 src/sys/kern/kern_resource.c:1.153 --- src/sys/kern/kern_resource.c:1.152 Tue May 26 06:57:38 2009 +++ src/sys/kern/kern_resource.c Fri Oct 2 22:38:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_resource.c,v 1.152 2009/05/26 06:57:38 elad Exp $ */ +/* $NetBSD: kern_resource.c,v 1.153 2009/10/02 22:38:45 elad Exp $ */ /*- * Copyright (c) 1982, 1986, 1991, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.152 2009/05/26 06:57:38 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.153 2009/10/02 22:38:45 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -69,6 +69,43 @@ static pool_cache_t plimit_cache; static pool_cache_t pstats_cache; +static kauth_listener_t rlimit_listener; + +static int +rlimit_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, + void *arg0, void *arg1, void *arg2, void *arg3) +{ + struct proc *p; + int result; + enum kauth_process_req req; + + result = KAUTH_RESULT_DEFER; + p = arg0; + req = (enum kauth_process_req)(unsigned long)arg1; + + if (action != KAUTH_PROCESS_RLIMIT) + return result; + + if (req == KAUTH_REQ_PROCESS_RLIMIT_SET) { + struct rlimit *new_rlimit; + u_long which; + + if ((p != curlwp->l_proc) && + (proc_uidmatch(cred, p->p_cred) != 0)) + return result; + + new_rlimit = arg2; + which = (u_long)arg3; + + if (new_rlimit->rlim_max <= p->p_rlimit[which].rlim_max) + result = KAUTH_RESULT_ALLOW; + } else if (req == KAUTH_REQ_PROCESS_RLIMIT_GET) { + result = KAUTH_RESULT_ALLOW; + } + + return result; +} + void resource_init(void) { @@ -77,6 +114,9 @@ "plimitpl", NULL, IPL_NONE, NULL, NULL, NULL); pstats_cache = pool_cache_init(sizeof(struct pstats), 0, 0, 0, "pstatspl", NULL, IPL_NONE, NULL, NULL, NULL); + + rlimit_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, + rlimit_listener_cb, NULL); } /* Index: src/sys/kern/sys_process.c diff -u src/sys/kern/sys_process.c:1.148 src/sys/kern/sys_process.c:1.149 --- src/sys/kern/sys_process.c:1.148 Fri Oct 2 22:18:57 2009 +++ src/sys/kern/sys_process.c Fri Oct 2 22:38:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_process.c,v 1.148 2009/10/02 22:18:57 elad Exp $ */ +/* $NetBSD: sys_process.c,v 1.149 2009/10/02 22:38:45 elad Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -118,7 +118,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.148 2009/10/02 22:18:57 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.149 2009/10/02 22:38:45 elad Exp $"); #include "opt_ptrace.h" #include "opt_ktrace.h" @@ -1033,3 +1033,38 @@ } #endif /* KTRACE || PTRACE */ +/* + * common code for corename, rlimit, and stopflag. + */ +int +proc_uidmatch(kauth_cred_t cred, kauth_cred_t target) +{ + int r = 0; + + if (kauth_cred_getuid(cred) != kauth_cred_getuid(target) || + kauth_cred_getuid(cred) != kauth_cred_getsvuid(target)) { + /* + * suid proc of ours or proc not ours + */ + r = EPERM; + } else if (kauth_cred_getgid(target) != kauth_cred_getsvgid(target)) { + /* + * sgid proc has sgid back to us temporarily + */ + r = EPERM; + } else { + /* + * our rgid must be in target's group list (ie, + * sub-processes started by a sgid process) + */ + int ismember = 0; + + if (kauth_cred_ismember_gid(cred, + kauth_cred_getgid(target), &ismember) != 0 || + !ismember) + r = EPERM; + } + + return (r); +} + Index: src/sys/secmodel/suser/secmodel_suser.c diff -u src/sys/secmodel/suser/secmodel_suser.c:1.5 src/sys/secmodel/suser/secmodel_suser.c:1.6 --- src/sys/secmodel/suser/secmodel_suser.c:1.5 Fri Oct 2 22:18:57 2009 +++ src/sys/secmodel/suser/secmodel_suser.c Fri Oct 2 22:38:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: secmodel_suser.c,v 1.5 2009/10/02 22:18:57 elad Exp $ */ +/* $NetBSD: secmodel_suser.c,v 1.6 2009/10/02 22:38:45 elad Exp $ */ /*- * Copyright (c) 2006 Elad Efrat <e...@netbsd.org> * All rights reserved. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.5 2009/10/02 22:18:57 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.6 2009/10/02 22:38:45 elad Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -504,41 +504,6 @@ } /* - * common code for corename, rlimit, and stopflag. - */ -static int -proc_uidmatch(kauth_cred_t cred, kauth_cred_t target) -{ - int r = 0; - - if (kauth_cred_getuid(cred) != kauth_cred_getuid(target) || - kauth_cred_getuid(cred) != kauth_cred_getsvuid(target)) { - /* - * suid proc of ours or proc not ours - */ - r = EPERM; - } else if (kauth_cred_getgid(target) != kauth_cred_getsvgid(target)) { - /* - * sgid proc has sgid back to us temporarily - */ - r = EPERM; - } else { - /* - * our rgid must be in target's group list (ie, - * sub-processes started by a sgid process) - */ - int ismember = 0; - - if (kauth_cred_ismember_gid(cred, - kauth_cred_getgid(target), &ismember) != 0 || - !ismember) - r = EPERM; - } - - return (r); -} - -/* * kauth(9) listener * * Security model: Traditional NetBSD @@ -698,38 +663,17 @@ break; case KAUTH_PROCESS_RLIMIT: { - unsigned long req; + enum kauth_process_req req; - req = (unsigned long)arg1; + req = (enum kauth_process_req)(unsigned long)arg1; switch (req) { - case KAUTH_REQ_PROCESS_RLIMIT_SET: { - struct rlimit *new_rlimit; - u_long which; - - if (isroot) { - result = KAUTH_RESULT_ALLOW; - break; - } - - if ((p != curlwp->l_proc) && - (proc_uidmatch(cred, p->p_cred) != 0)) { - break; - } - - new_rlimit = arg2; - which = (u_long)arg3; - - if (new_rlimit->rlim_max <= - p->p_rlimit[which].rlim_max) + case KAUTH_REQ_PROCESS_RLIMIT_SET: + case KAUTH_REQ_PROCESS_RLIMIT_GET: + if (isroot) result = KAUTH_RESULT_ALLOW; break; - } - - case KAUTH_REQ_PROCESS_RLIMIT_GET: - result = KAUTH_RESULT_ALLOW; - break; default: break; Index: src/sys/sys/proc.h diff -u src/sys/sys/proc.h:1.290 src/sys/sys/proc.h:1.291 --- src/sys/sys/proc.h:1.290 Wed May 27 12:15:11 2009 +++ src/sys/sys/proc.h Fri Oct 2 22:38:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.290 2009/05/27 12:15:11 yamt Exp $ */ +/* $NetBSD: proc.h,v 1.291 2009/10/02 22:38:45 elad Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -510,6 +510,7 @@ int proc_isunder(struct proc *, struct lwp *); void proc_stop(struct proc *, int, int); +int proc_uidmatch(kauth_cred_t, kauth_cred_t); int proc_vmspace_getref(struct proc *, struct vmspace **); void proc_crmod_leave(kauth_cred_t, kauth_cred_t, bool);