Subject: Re: Towards a capabilities system
To: Elad Efrat <elad@NetBSD.org>
From: ober <ober@linbsd.org>
List: tech-security
Date: 08/03/2006 11:51:09
Sign me up for sys/{arch,compat,dev}


-Ober


On Tue, 1 Aug 2006, Elad Efrat wrote:

> Date: Tue, 01 Aug 2006 18:49:33 +0200
> From: Elad Efrat <elad@NetBSD.org>
> To: tech-security@NetBSD.org, tech-kern@NetBSD.org
> Subject: Towards a capabilities system
> 
> Hi,
>
> We recently integrated the kauth(9) interface, but that was only the
> first step in preparing the ground for the more interesting stuff; for
> example, capabilities.
>
> This post details the work needed to be done, and more importantly,
> lists who can participate in the work -- that includes not only
> developers, but also the NetBSD user-base. In fact, the reason I am
> posting this to a public list is that I'm interested more in the
> latter.. :)
>
> People who just want to get to the summary of how they can help with
> each task can simply scroll to its (the task's) bottom.
>
> Task list
>
>  The goal is to classify the authorization requests so that we know
>  why and what access is requested.
>
>  Here's what needs to be done:
>
>  1. Making sure all authorization requests really go through kauth(9)
>
>     The traditional Unix security model says "superuser can do
>     everything", more or less. Unfortunately, not all NetBSD kernel
>     code used to check that fact with suser(9); some code uses
>     hard-coded comparisons against zero.
>
>     For example, from sys/ufs/ufs/ufs_lookup.c:WRITE():
>
> 	[...]
> 	/*
> 	 * If we successfully wrote any data, and we are not the
> 	 * superuser we clear the setuid and setgid bits as a precaution
> 	 * against tampering.
> 	 */
> 	[...]
> 	if (resid > uio->uio_resid && ap->a_cred &&
> 	    kauth_cred_geteuid(ap->a_cred) != 0) {
> 		ip->i_mode &= ~(ISUID | ISGID);
> 		DIP_ASSIGN(ip, mode, ip->i_mode);
> 	}
> 	[...]
>
>     The comment says we care if we are (or are not) the superuser; the
>     code checks if the effective user-id is zero; what we really want
>     to know is if we should clear the setuid and setgid bits.
>
>     TASK: Locate occurences in the code where any of the following is
>           used to grant or deny access:
>
> 		kauth_cred_geteuid() /* <-- jackpot */
> 		kauth_cred_getuid()
> 		kauth_cred_getsvuid()
> 		kauth_cred_getegid()
> 		kauth_cred_getgid()
> 		kauth_cred_getsvgid()
>
>  2. Replace KAUTH_GENERIC_ISSUSER with something more specific
>
>     Most authorization requests right now use KAUTH_GENERIC_ISSUSER,
>     which simply checks if the user is the superuser. However, what we
>     really care about is what operation needs to be done.
>
>     For example, from sys/netinet/raw_ip.c:rip_usrreq():
>
> 	[...]
> 	switch (req) {
> 	case PRU_ATTACH:
> 	[...]
> 		if (l == 0 ||
> 		    (error = kauth_authorize_generic(l->l_cred,
> 		    KAUTH_GENERIC_ISSUSER, &l->l_acflag))) {
> 			error = EACCES;
> 			break;
> 		}
> 	[...]
>
>     According to the context of the code, we can tell that it is
>     really a request to open a raw socket.
>
>     TASK: Locate calls to kauth_authorize_generic(), examine their
>           context, and mark what the real request is.
>
>
> Any feedback should be sent to me, preferably off-list. You don't have
> to send code patches to help! lists such as this one will help
> tremendously:
>
> ufs/ufs/ufs_readwrite.c:486: zerocmp: retain setuid/setgid bit on move
> netinet/raw_ip.c:544: issuser: can open raw socket
>
> Note, that these are very easy tasks that can be easiy accomplished
> using grep(1) and some common sense. :) The problem is that there are so
> many of them that we'll accomplish things faster if we work together.
> The more people help hunt these down, the faster we can move on to with
> *really* allowing the choice of a security model.
>
> The above is *mandatory* before we can implement capabilities, user
> roles, program roles, etc.
>
>
> Thank you,
>
> -e.
>
> -- 
> Elad Efrat
>