Subject: Re: KAUTH_REQ_NETWORK_SOCKET_OPEN
To: David Young <dyoung@pobox.com>
From: Iain Hibbert <plunky@rya-online.net>
List: tech-kern
Date: 01/31/2007 19:58:32
On Wed, 31 Jan 2007, David Young wrote:

> > > > On Wed, Jan 31, 2007 at 12:16:15AM +0000, Iain Hibbert wrote:
> > > > > 2. rewrite the HCI socket code so that its not socket based..
>
> A character device is nice because it can be delegated using a familiar
> API and UI: chmod/chown.  It also gives the BT HCI privilege a "name"
> in a familiar and highly functional namespace that a lot of programs
> already grok.

This is the way that I thought (afterwards) it should probably have been
done, with a /dev/bthciN entry for each controller, and this would get
around some ugliness where you need the bdaddr to address the device but
its not available until the device is up and running.. but there would be
other issues and I don't want to get into them for now.

> I think the 4.4BSD model may as well get another hard-coded exception.

Ok, but see below for an alternative

> The rule "only root can create a raw socket, PF_ROUTE and PF_BLUETOOTH
> sockets excepted" is a blunt instrument for enforcing a policy on
> what packets a program can send and receive.  It leads to risky
> business like using a setuid program to send and receive innocuous
> ICMP Echo packets.  Going forwards, *perhaps* the granularity needs to
> be finer---socket(PF_ICMP, SOCK_DGRAM, ICMP_ECHO), anyone?---or else
> a different mechanism should enforce the policy (packet filter rules
> applied to programs and processes?).

I had a thought that rather than adding hardcoded values to the kauth
request, if it took a pointer to the protosw instead of (domain, type,
proto), there could be a PR_RESTRICT flag on specific protocols to lock
them off..  (eg below)

This would provide better granularity (and better error reporting for non
existent protocols) but I'm not sure if thats ok in the context of
replaceable security models?

iain
--- sys/kern/uipc_socket.c	2007-01-27 23:38:22.000000000 +0000
+++ sys/kern/uipc_socket.c	2007-01-31 19:50:18.000000000 +0000
@@ -473,12 +473,6 @@
 	uid_t		uid;
 	int		error, s;

-	error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
-	    KAUTH_REQ_NETWORK_SOCKET_OPEN, KAUTH_ARG(dom), KAUTH_ARG(type),
-	    KAUTH_ARG(proto));
-	if (error)
-		return (error);
-
 	if (proto)
 		prp = pffindproto(dom, proto, type);
 	else
@@ -496,6 +490,12 @@
 		return (EPROTONOSUPPORT);
 	if (prp->pr_type != type)
 		return (EPROTOTYPE);
+
+	error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
+	    KAUTH_REQ_NETWORK_SOCKET_OPEN, KAUTH_ARG(prp));
+	if (error)
+		return (error);
+
 	s = splsoftnet();
 	so = pool_get(&socket_pool, PR_WAITOK);
 	memset((caddr_t)so, 0, sizeof(*so));
--- sys/secmodel/bsd44/secmodel_bsd44_suser.c	2007-01-27 23:38:32.000000000 +0000
+++ sys/secmodel/bsd44/secmodel_bsd44_suser.c	2007-01-31 19:55:08.000000000 +0000
@@ -647,13 +647,10 @@
 	case KAUTH_NETWORK_SOCKET:
 		switch (req) {
 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
-			if ((u_long)arg1 == PF_ROUTE)
-				result = KAUTH_RESULT_ALLOW;
-			else if ((u_long)arg2 == SOCK_RAW) {
-				if (isroot)
-					result = KAUTH_RESULT_ALLOW;
-			} else
-				result = KAUTH_RESULT_ALLOW;
+			if ((((struct protosw *)arg1)->pr_flags & PR_RESTRICT) && !isroot)
+				break;
+
+			result = KAUTH_RESULT_ALLOW;
 			break;

 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK: