Subject: Tackling more kauth(9) stuff
To: None <tech-kern@netbsd.org>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 09/20/2006 14:43:12
Hi,

A large portion of where we currently check for KAUTH_GENERIC_ISSUSER
(ie., if the user is the super-user) belongs in device driver code for
either network interfaces or terminals.

Common examples are:

src/sys/net/if_gif.c:

[...]
int
gif_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
[...]
	switch (cmd) {
	case SIOCSIFMTU:
	case SIOCSLIFPHYADDR:
#ifdef SIOCDIFPHYADDR
	case SIOCDIFPHYADDR:
#endif
		if ((error = kauth_authorize_generic(l->l_cred,
		    KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
			return (error);
		/* FALLTHROUGH */
	default:
		break;
	}
[...]

src/sys/arch/i386/isa/pccons.c:

[...]
int
pcopen(dev_t dev, int flag, int mode, struct lwp *l)
{
[...]
	if ((tp->t_state & TS_ISOPEN) == 0) {
		[...]
	} else if (tp->t_state&TS_XCLUDE &&
	    kauth_authorize_generic(l->l_cred,
	    KAUTH_GENERIC_ISSUSER, &l->l_acflag) != 0)
			return (EBUSY);
[...]

Where the first checks if "privileged" modifications can be made to the
(in this example) gif interface such as setting the MTU, or changing
the interface address. The second checks if a terminal that is already
opened and marked with TS_XCLUDE ("exclusive open") can be re-opened:
only the super-user can do that.

My proposal includes the following:

  1. Adding a KAUTH_NETWORK_INTERFACE action to the network scope, with
     a set of "generic" sub-actions as follows:

       - KAUTH_REQ_NETWORK_INTERFACE_SET
       - KAUTH_REQ_NETWORK_INTERFACE_GET
       - KAUTH_REQ_NETWORK_INTERFACE_SETPRIV
       - KAUTH_REQ_NETWORK_INTERFACE_GETPRIV

     Where the first two are requests to set/get non-privileged data
     that (usually) all users can do, and the last two are those that
     (again, usually) are restricted to the super-user.

     This will be passed as arg0. In addition, full context will be
     provided in arg1 (struct ifnet *) and arg2 (cmd). arg3 is left free
     for now for this action.

     The above follows *existing* policy of using arg0, where possible,
     to provide a "generic" request that most policies will care about
     without having to deal with too much internals of each specific
     case, and makes listener writing very easy.

  2. Adding a "device" scope, for a variety of authorization requests
     related to devices (terminals is what we care about now) on the
     system.

     The arguments for this scope will be a device_t as arg0, and a
     context depending on the device.

     For this case, arg1 will be KAUTH_REQ_DEVICE_TTY_OVERRIDE, arg2
     a struct tty *, and arg3 is left free for now.

There's also a possibility of adding network interface authorization
to the "device" scope (devclass_t can be DV_IFNET), but I think
logically it would be wiser to keep them with the rest of the networking
authorization listener code.

Comments?

-e.

-- 
Elad Efrat