PERFORCE change 113332 for review

Todd Miller millert at FreeBSD.org
Mon Jan 22 15:46:23 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=113332

Change 113332 by millert at millert_macbook on 2007/01/22 15:44:51

	Add inpcb labels so we can check labels during packet
	delivery; adapted from FreeBSD.
	Much of mac_inet.c remains commented out for now.
	
	Unlike FreeBSD, Darwin has no pru_sosetlabel so we always
	sync the inpcb label when the socket label changes.  I
	believe this is safe.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/in_pcb.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/in_pcb.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/ip_divert.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/raw_ip.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/tcp_input.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/tcp_output.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/tcp_subr.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/udp_usrreq.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#4 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#31 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#39 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_socket.c#9 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#63 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/in_pcb.c#3 (text+ko) ====

@@ -191,11 +191,9 @@
 {
 	register struct inpcb *inp;
 	caddr_t		      temp;
-#if IPSEC
-#ifndef __APPLE__
+#ifdef MAC
 	int error;
 #endif
-#endif
 
 	if (so->cached_in_sock_layer == 0) {
 #if TEMPDEBUG
@@ -219,12 +217,23 @@
 	inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
 	inp->inp_pcbinfo = pcbinfo;
 	inp->inp_socket = so;
+#ifdef MAC
+	error = mac_inpcb_label_init(inp, M_WAITOK);
+	if (error != 0) {
+		if (so->cached_in_sock_layer == 0)
+			zfree(pcbinfo->ipi_zone, inp);
+		return (error);
+	}
+	mac_inpcb_label_associate(so, inp);
+#endif
 	so->so_pcb = (caddr_t)inp;
 
 	if (so->so_proto->pr_flags & PR_PCBLOCK) {
 		inp->inpcb_mtx = lck_mtx_alloc_init(pcbinfo->mtx_grp, pcbinfo->mtx_attr);
 		if (inp->inpcb_mtx == NULL) {
 			printf("in_pcballoc: can't alloc mutex! so=%x\n", so);
+			if (so->cached_in_sock_layer == 0)
+				zfree(pcbinfo->ipi_zone, inp);
 			return(ENOMEM);
 		}
 	}
@@ -793,6 +802,9 @@
 		so->so_pcb = 0; 
 		inp->inp_socket = 0;
 		inp->reserved[0] = so;
+#ifdef MAC
+		mac_inpcb_label_destroy(inp);
+#endif
 		if (so->cached_in_sock_layer == 0) {
 			zfree(ipi->ipi_zone, inp);
 		}
@@ -1686,6 +1698,9 @@
     struct proc *p = current_proc();
 
     bzero(&pcbinfo->nat_dummy_socket, sizeof(struct socket));
+#ifdef MAC
+    mac_socket_label_init(&pcbinfo->nat_dummy_socket, M_WAITOK);
+#endif
     pcbinfo->nat_dummy_socket.so_proto = pffindproto_locked(afamily, pfamily, protocol);
     pcbinfo->all_owners = 0;
     stat = in_pcballoc(&pcbinfo->nat_dummy_socket, pcbinfo, p);

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/in_pcb.h#3 (text+ko) ====

@@ -75,8 +75,6 @@
 #endif
 #endif /* KERNEL_PRIVATE */
 
-#include <netinet6/ipsec.h> /* for IPSEC */
-
 #ifdef KERNEL_PRIVATE
 
 #define	in6pcb		inpcb	/* for KAME src sync over BSD*'s */
@@ -185,7 +183,8 @@
 #else
 	void	  *inpcb_mtx;
 #endif
-	u_long	reserved[2];		/* For future use */
+	struct label *inp_label;	/* MAC label */
+	u_long	reserved[1];		/* For future use */
 };
 
 #endif /* KERNEL_PRIVATE */

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/ip_divert.c#3 (text+ko) ====

@@ -370,6 +370,9 @@
 		/* Send packet to output processing */
 		ipstat.ips_rawout++;			/* XXX */
 		socket_unlock(so, 0);
+#ifdef MAC
+		mac_mbuf_label_associate_inpcb(inp, m);
+#endif
 		error = ip_output(m,
 			    inp->inp_options, &inp->inp_route,
 			(so->so_options & SO_DONTROUTE) |
@@ -420,6 +423,9 @@
 			ip->ip_sum = in_cksum(m, hlen);
 		}
 
+#ifdef MAC
+		mac_mbuf_label_associate_socket(so, m);
+#endif
 		/* Send packet to input processing */
 		proto_inject(PF_INET, m);
 	}

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/raw_ip.c#6 (text+ko) ====

@@ -226,7 +226,13 @@
 				lck_mtx_unlock(sadb_mutex);
 			} 
 #endif /*IPSEC*/
+#ifdef MAC
 			if (n && skipit == 0) {
+				if (mac_inpcb_check_deliver(last, n) != 0)
+					skipit = 1;
+			}
+#endif
+			if (n && skipit == 0) {
 				int error = 0;
 				if (last->inp_flags & INP_CONTROLOPTS ||
 				    last->inp_socket->so_options & SO_TIMESTAMP)
@@ -269,6 +275,12 @@
 		lck_mtx_unlock(sadb_mutex);
 	} 
 #endif /*IPSEC*/
+#ifdef MAC
+	if (last && skipit == 0) {
+		if (mac_inpcb_check_deliver(last, m) != 0)
+			skipit = 1;
+	}
+#endif
 	if (skipit == 0) {
 		if (last) {
 			if (last->inp_flags & INP_CONTROLOPTS ||
@@ -364,7 +376,7 @@
 	}
 
 #ifdef MAC_SOCKET
-	mac_mbuf_label_associate_socket(so, m);
+	mac_mbuf_label_associate_inpcb(inp, m);
 #endif
 
 	return (ip_output_list(m, 0, inp->inp_options, &inp->inp_route, flags,

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/tcp_input.c#6 (text+ko) ====

@@ -911,8 +911,7 @@
 		tiwin = th->th_win;
 
 #ifdef MAC_SOCKET
-	/* XXXMAC: should be mac_inpcb_check_deliver() */
-	if (mac_socket_check_deliver(so, m))
+	if (mac_inpcb_check_deliver(inp, m))
 		goto drop;
 #endif
 

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/tcp_output.c#6 (text+ko) ====

@@ -1006,11 +1006,7 @@
 	}
 	m->m_pkthdr.rcvif = 0;
 #ifdef MAC_SOCKET
-#ifdef __darwin8_notyet
-		mac_inpcb_create_mbuf(tp->t_inpcb, m);
-#else
-		mac_mbuf_label_associate_socket(so, m);
-#endif
+	mac_mbuf_label_associate_inpcb(tp->t_inpcb, m);
 #endif
 #if INET6
 	if (isipv6) {

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/tcp_subr.c#6 (text+ko) ====

@@ -581,12 +581,7 @@
 		 * Packet is associated with a socket, so allow the
 		 * label of the response to reflect the socket label.
 		 */
-#ifdef __darwin8_notyet
-		INP_LOCK_ASSERT(inp);
-		mac_inpcb_create_mbuf(tp->t_inpcb, m);
-#else
-		mac_mbuf_label_associate_socket(tp->t_inpcb->inp_socket, m);
-#endif
+		mac_mbuf_label_associate_inpcb(tp->t_inpcb, m);
 	} else {
 #ifdef __darwin8_notyet
 		/*

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/netinet/udp_usrreq.c#3 (text+ko) ====

@@ -696,6 +696,12 @@
 	struct sockaddr *append_sa;
 	struct mbuf *opts = 0;
 
+#ifdef MAC
+	if (mac_inpcb_check_deliver(last, n) != 0) {
+		m_freem(n);
+		return;
+	}
+#endif
 	if (last->inp_flags & INP_CONTROLOPTS ||
 	    last->inp_socket->so_options & SO_TIMESTAMP) {
 #if INET6
@@ -1006,6 +1012,9 @@
 		}
 	}
 
+#ifdef MAC
+	mac_mbuf_label_associate_inpcb(inp, m);
+#endif
 
 	/*
 	 * Calculate data length and get a mbuf

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#4 (text+ko) ====

@@ -25,3 +25,4 @@
 security/mac_pipe.c					optional mac
 security/mac_iokit.c					optional mac
 security/mac_file.c					optional mac
+security/mac_inet.c					optional mac

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#31 (text+ko) ====

@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 1999-2002 Robert N. M. Watson
  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
- * Copyright (c) 2005-2006 SPARTA, Inc.
+ * Copyright (c) 2005-2007 SPARTA, Inc.
  * All rights reserved.
  *
  * This software was developed by Robert Watson for the TrustedBSD Project.
@@ -60,6 +60,7 @@
 struct fdescnode;
 struct fileglob;
 struct ifnet;
+struct inpcb;
 struct ifreq;
 struct lctx;
 struct mac;
@@ -160,8 +161,12 @@
 void	mac_ifnet_label_recycle(struct ifnet *ifp);
 int	mac_ifnet_label_set(struct ucred *cred, struct ifreq *ifr,
 	    struct ifnet *ifp);
-int	mac_iokit_check_device(char *devtype, struct mac_module_data *mdata);
-int	mac_lctx_check_label_update(struct lctx *l, struct label *newlabel);
+int	mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *mbuf);
+void	mac_inpcb_label_associate(struct socket *so, struct inpcb *inp);
+void	mac_inpcb_label_destroy(struct inpcb *inp);
+int	mac_inpcb_label_init(struct inpcb *inp, int flag);
+void	mac_inpcb_label_recycle(struct inpcb *inp);
+void	mac_inpcb_label_update(struct socket *so);
 struct label	*mac_lctx_label_alloc(void);
 void    mac_lctx_label_free(struct label *label);
 void	mac_lctx_label_update(struct lctx *l, struct label *newlabel);
@@ -170,6 +175,7 @@
 void	mac_lctx_notify_leave(struct proc *proc, struct lctx *l);
 void	mac_mbuf_label_associate_bpfdesc(struct bpf_d *bpf_d, struct mbuf *m);
 void	mac_mbuf_label_associate_ifnet(struct ifnet *ifp, struct mbuf *m);
+void	mac_mbuf_label_associate_inpcb(struct inpcb *inp, struct mbuf *m);
 void	mac_mbuf_label_associate_linklayer(struct ifnet *ifp, struct mbuf *m);
 void	mac_mbuf_label_associate_socket(struct socket *so, struct mbuf *m);
 void	mac_mbuf_label_copy(struct mbuf *m_from, struct mbuf *m_to);

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#39 (text+ko) ====

@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 1999-2002 Robert N. M. Watson
  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
- * Copyright (c) 2005-2006 SPARTA, Inc.
+ * Copyright (c) 2005-2007 SPARTA, Inc.
  * All rights reserved.
  *
  * This software was developed by Robert Watson for the TrustedBSD Project.
@@ -61,6 +61,7 @@
 struct devnode;
 struct fileglob;
 struct ifnet;
+struct inpcb;
 struct label;
 struct lctx;
 struct mac_module_data;
@@ -1005,6 +1006,84 @@
 	struct label *label
 );
 /**
+  @brief Access control check for delivering a packet to a socket
+  @param inp inpcb the socket is associated with
+  @param inplabel Label of the inpcb
+  @param m The mbuf being received
+  @param mbuflabel Label of the mbuf being received
+
+  Determine whether the mbuf with label mbuflabel may be received
+  by the socket associated with inpcb that has the label inplabel.
+
+  @return Return 0 if access is granted, otherwise an appropriate value for
+  errno should be returned.
+*/
+typedef int mpo_inpcb_check_deliver_t(
+	struct inpcb *inp,
+	struct label *inplabel,
+	struct mbuf *m,
+	struct label *mbuflabel
+);
+/**
+  @brief Create an inpcb label
+  @param so Socket containing the inpcb to be labeled
+  @param solabel Label of the socket
+  @param inp inpcb to be labeled
+  @param inplabel Label for the inpcb
+
+  Set the label of a newly created inpcb, most likely
+  using the information in the socket and/or socket label.
+*/
+typedef void mpo_inpcb_label_associate_t(
+	struct socket *so,
+	struct label *solabel,
+	struct inpcb *inp,
+	struct label *inplabel
+);
+/**
+ @brief Destroy inpcb label
+ @param label The label to be destroyed
+*/
+typedef void mpo_inpcb_label_destroy_t(
+	struct label *label
+);
+/**
+  @brief Initialize inpcb label
+  @param label New label to initialize
+  @param flag M_WAITOK or M_NOWAIT
+*/
+typedef int mpo_inpcb_label_init_t(
+	struct label *label,
+	int flag
+);
+/**
+  @brief Recycle up an inpcb label
+  @param label The label to be recycled
+
+  Recycle an inpcb label.  Darwin allocates the inpcb as part of
+  the socket structure in some cases.  For this case we must recycle
+  rather than destroy the inpcb as it will be reused later.
+*/
+typedef void mpo_inpcb_label_recycle_t(
+	struct label *label
+);
+/**
+  @brief Update an inpcb label from a socket label
+  @param so Socket containing the inpcb to be relabeled
+  @param solabel New label of the socket
+  @param inp inpcb to be labeled
+  @param inplabel Label for the inpcb
+
+  Set the label of a newly created inpcb due to a change in the
+  underlying socket label.
+*/
+typedef void mpo_inpcb_label_update_t(
+	struct socket *so,
+	struct label *solabel,
+	struct inpcb *inp,
+	struct label *inplabel
+);
+/**
   @brief Update a network interface label
   @param cred Subject credential
   @param ifp The network interface to be relabeled
@@ -1217,6 +1296,21 @@
 );
 /**
  @brief Assign a label to a new mbuf
+ @param inp inpcb structure
+ @param i_label Existing label of inp
+ @param m Object; mbuf
+ @param m_label Policy label to fill in for m
+
+ Label an mbuf based on the inpcb from which it was derived.
+*/
+typedef void mpo_mbuf_label_associate_inpcb_t(
+	struct inpcb *inp,
+	struct label *i_label,
+	struct mbuf *m,
+	struct label *m_label
+);
+/**
+ @brief Assign a label to a new mbuf
  @param ifp Subject; network interface
  @param i_label Existing label of ifp
  @param m Object; mbuf
@@ -5271,6 +5365,12 @@
 	mpo_ifnet_label_internalize_t		*mpo_ifnet_label_internalize;
 	mpo_ifnet_label_update_t		*mpo_ifnet_label_update;
 	mpo_ifnet_label_recycle_t		*mpo_ifnet_label_recycle;
+	mpo_inpcb_check_deliver_t		*mpo_inpcb_check_deliver;
+	mpo_inpcb_label_associate_t		*mpo_inpcb_label_associate;
+	mpo_inpcb_label_destroy_t		*mpo_inpcb_label_destroy;
+	mpo_inpcb_label_init_t			*mpo_inpcb_label_init;
+	mpo_inpcb_label_recycle_t		*mpo_inpcb_label_recycle;
+	mpo_inpcb_label_update_t		*mpo_inpcb_label_update;
 	mpo_iokit_check_device_t		*mpo_iokit_check_device;
 	mpo_lctx_check_label_update_t		*mpo_lctx_check_label_update;
 	mpo_lctx_label_destroy_t		*mpo_lctx_label_destroy;
@@ -5283,6 +5383,7 @@
 	mpo_lctx_notify_leave_t			*mpo_lctx_notify_leave;
 	mpo_mbuf_label_associate_bpfdesc_t	*mpo_mbuf_label_associate_bpfdesc;
 	mpo_mbuf_label_associate_ifnet_t	*mpo_mbuf_label_associate_ifnet;
+	mpo_mbuf_label_associate_inpcb_t	*mpo_mbuf_label_associate_inpcb;
 	mpo_mbuf_label_associate_linklayer_t	*mpo_mbuf_label_associate_linklayer;
 	mpo_mbuf_label_associate_socket_t	*mpo_mbuf_label_associate_socket;
 	mpo_mbuf_label_copy_t			*mpo_mbuf_label_copy;

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_socket.c#9 (text+ko) ====

@@ -434,16 +434,14 @@
 	sotoxsocket(so, &xso);
 	MAC_PERFORM(socket_label_update, cred, &xso, so->so_label, label);
 
-#ifdef __darwin8_notyet
 	/*
 	 * If the protocol has expressed interest in socket layer changes,
 	 * such as if it needs to propagate changes to a cached pcb
 	 * label from the socket, notify it of the label change while
 	 * holding the socket lock.
+	 * XXXMAC - are there cases when we should not do this?
 	 */
-	if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL)
-		(so->so_proto->pr_usrreqs->pru_sosetlabel)(so);
-#endif
+	mac_inpcb_label_update(so);
 
 	return (0);
 }

==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#63 (text+ko) ====

@@ -933,6 +933,14 @@
 }
 
 static void
+sebsd_mbuf_label_associate_inpcb(struct inpcb *inp, struct label *ilabel,
+    struct mbuf *m, struct label *mlabel)
+{
+
+	sebsd_label_copy(ilabel, mlabel);
+}
+
+static void
 sebsd_posixsem_label_associate(struct ucred *cred, struct pseminfo *psem,
     struct label *psemlabel, const char *name)
 {
@@ -2651,9 +2659,8 @@
     struct label *socklabel)
 {
 
-	/* XXX - check for NULL mbuf label */
-	/* XXX what to use here? */
-	return (socket_has_perm(cred, socklabel, SOCKET__DELIVER));
+	/* XXX - check for NULL socket label? */
+	return (socket_has_perm(cred, socklabel, SOCKET__RECV));
 }
 #endif
 
@@ -3089,6 +3096,38 @@
 	return (error);
 }
 
+static void
+sebsd_inpcb_label_associate(struct socket *so, struct label *solabel,
+    struct inpcb *inp, struct label *inplabel)
+{
+
+	sebsd_label_copy(solabel, inplabel);
+}
+
+static void
+sebsd_inpcb_label_update(struct socket *so, struct label *solabel,
+    struct inpcb *inp, struct label *inplabel)
+{
+
+	sebsd_label_copy(solabel, inplabel);
+}
+
+static int
+sebsd_inpcb_check_deliver(struct inpcb *inp,
+    struct label *inplabel, struct mbuf *m, struct label *mbuflabel)
+{
+	struct network_security_struct *ifsec, *msec;
+	int error;
+
+	ifsec = SLOT(inplabel);
+	msec = SLOT(mbuflabel);
+
+	/* XXX - use an audit struct so we can log useful info */
+	error = avc_has_perm(msec->sid, ifsec->sid, SECCLASS_PACKET,
+	    PACKET__RECV, NULL);
+	return (error);
+}
+
 static int
 ipc_has_perm(struct ucred *cred, struct label *label, u_int32_t perm)
 {
@@ -3475,8 +3514,15 @@
 	.mpo_ifnet_label_internalize = sebsd_label_internalize,
 	.mpo_ifnet_label_recycle = sebsd_label_recycle,
 	.mpo_ifnet_label_update = sebsd_ifnet_label_update,
+	.mpo_inpcb_check_deliver = sebsd_inpcb_check_deliver,
+	.mpo_inpcb_label_associate = sebsd_inpcb_label_associate,
+	.mpo_inpcb_label_destroy = sebsd_label_destroy,
+	.mpo_inpcb_label_init = sebsd_label_init2,
+	.mpo_inpcb_label_recycle = sebsd_label_recycle,
+	.mpo_inpcb_label_update = sebsd_inpcb_label_update,
 	.mpo_mbuf_label_associate_bpfdesc = sebsd_mbuf_label_associate_bpfdesc,
 	.mpo_mbuf_label_associate_ifnet = sebsd_mbuf_label_associate_ifnet,
+	.mpo_mbuf_label_associate_inpcb = sebsd_mbuf_label_associate_inpcb,
 	.mpo_mbuf_label_associate_linklayer = sebsd_mbuf_label_associate_ifnet,
 	.mpo_mbuf_label_associate_socket = sebsd_mbuf_label_associate_socket,
 	.mpo_mbuf_label_copy = sebsd_label_copy,


More information about the trustedbsd-cvs mailing list