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
>