PERFORCE change 113320 for review

Todd Miller millert at FreeBSD.org
Mon Jan 22 15:17:56 UTC 2007


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

Change 113320 by millert at millert_macbook on 2007/01/22 15:17:03

	Add ifnet label support.  Also add the ifnet label as an 
	argument to mpo_mbuf_label_associate_ifnet like FreeBSD.
	
	Note that some network pseudo-devices (faith, gif, lo, stf) 
	do not use dlil for allocation so we have to call
	mac_ifnet_label_init() directly for those.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/dlil.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_faith.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_gif.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_loop.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_stf.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_var.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/sockio.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#28 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_net.c#7 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#36 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#26 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#59 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/test/mac_test.c#19 edit

Differences ...

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

@@ -1093,7 +1093,13 @@
 	}
 
 	do {
-		
+#ifdef MAC
+		retval = mac_ifnet_check_transmit(ifp, m);
+		if (retval) {
+			m_freem(m);
+			goto cleanup;
+		}
+#endif
 	
 		if (ifp->if_framer) {
 			retval = ifp->if_framer(ifp, &m, dest, dst_linkaddr, frame_type); 
@@ -1219,6 +1225,14 @@
 			goto cleanup;
 		}
 	}
+
+#ifdef MAC
+	retval = mac_ifnet_check_transmit(ifp, m);
+	if (retval) {
+		m_freem(m);
+		goto cleanup;
+	}
+#endif
 	
 	/*
 	 * Call framing module 
@@ -2384,6 +2398,9 @@
 			ifa->ifa_debug |= IFA_ATTACHED;
 			TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
 		}
+#ifdef MAC
+		mac_ifnet_label_associate(ifp);
+#endif
 		
 		TAILQ_INSERT_TAIL(&ifnet_head, ifp, if_link);
 		ifindex2ifnet[ifp->if_index] = ifp;
@@ -2758,6 +2775,9 @@
     ifp1 = (struct ifnet *)dlifp1;
     ifp1->if_eflags |= IFEF_INUSE;
     ifp1->if_name = dlifp1->if_namestorage;
+#ifdef MAC
+    mac_ifnet_label_init(ifp1);
+#endif
 
     TAILQ_INSERT_TAIL(&dlil_ifnet_head, dlifp1, dl_if_link);
      
@@ -2785,6 +2805,15 @@
 
     strncpy(dlifp->if_namestorage, ifp->if_name, IFNAMSIZ);
     ifp->if_name = dlifp->if_namestorage;
+#ifdef MAC
+    /*
+     * We can either recycle the MAC label here or in dlil_if_acquire().
+     * It seems logical to do it here but this means that anything that
+     * still has a handle on ifp will now see it as unlabeled.
+     * Since the interface is "dead" that may be OK.  Revisit later.
+     */
+    mac_ifnet_label_recycle(ifp);
+#endif
     if (ifp->if_lock)
 		ifnet_lock_done(ifp);
     

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

@@ -104,6 +104,10 @@
 #endif
 #endif
 
+#ifdef MAC 
+#include <security/mac_framework.h>
+#endif
+
 /*
  * System initialization
  */
@@ -1086,6 +1090,13 @@
 		ifnet_lock_done(ifp);
 		break;
 
+#ifdef MAC
+	case SIOCGIFMAC:
+		error = mac_ifnet_label_get(proc_ucred(p), ifr, ifp);
+		if (error)
+			return (error);
+		break;
+#endif
 	case SIOCGIFMETRIC:
 		ifnet_lock_shared(ifp);
 		ifr->ifr_metric = ifp->if_metric;
@@ -1131,6 +1142,13 @@
 		ifnet_touch_lastchange(ifp);
 		break;
 
+#ifdef MAC
+	case SIOCSIFMAC:
+		error = mac_ifnet_label_set(proc_ucred(p), ifr, ifp);
+		if (error)
+			return (error);
+		break;
+#endif
 	case SIOCSIFMETRIC:
 		error = proc_suser(p);
 		if (error)

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

@@ -274,6 +274,9 @@
 		ifp->if_type = IFT_FAITH;
 		ifp->if_hdrlen = 0;
 		ifp->if_addrlen = 0;
+#ifdef MAC
+		mac_ifnet_label_init(ifp);
+#endif
 		dlil_if_attach(ifp);
 #if NBPFILTER > 0
 #ifdef HAVE_OLD_BPF

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

@@ -325,6 +325,9 @@
 	sc->gif_if.if_type   = IFT_GIF;
 	sc->gif_if.if_add_proto = gif_add_proto;
 	sc->gif_if.if_del_proto = gif_del_proto;
+#ifdef MAC
+	mac_ifnet_label_init(&sc->gif_if);
+#endif
 	dlil_if_attach(&sc->gif_if);
 	bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
 	TAILQ_INSERT_TAIL(&gifs, sc, gif_link);

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

@@ -472,6 +472,9 @@
 		ifp->if_type = IFT_LOOP;
 		ifp->if_hwassist = IF_HWASSIST_CSUM_IP | IF_HWASSIST_CSUM_TCP | IF_HWASSIST_CSUM_UDP;
 		ifp->if_hdrlen = sizeof(struct loopback_header);
+#ifdef MAC
+		mac_ifnet_label_init(ifp);
+#endif
 		lo_ifp = ifp;
 		dlil_if_attach(ifp);
 #if NBPFILTER > 0

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_stf.c#2 (text+ko) ====

@@ -270,6 +270,9 @@
 	sc->sc_if.if_flags  |= IFF_LINK2;
 #endif
 	sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
+#ifdef MAC
+	mac_ifnet_label_init(&sc->sc_if);
+#endif
 
 	if (error = dlil_if_attach(&sc->sc_if))
 		printf("stfattach: can't dlil_if_attach error=%d\n");
@@ -635,6 +638,10 @@
 
 	ifp = &sc->sc_if;
 
+#ifdef MAC
+	mac_mbuf_label_associate_ifnet(ifp, m);
+#endif
+
 	/*
 	 * perform sanity check against outer src/dst.
 	 * for source, perform ingress filter as well.

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

@@ -439,6 +439,7 @@
 			u_char	*ptr;
 		} u;
 	} if_broadcast;
+	struct  label *if_label;	/* interface MAC label */
 };
 
 #define if_add_proto	if_add_proto_u.original

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

@@ -179,4 +179,7 @@
 #define SIOCSETOT     _IOW('s', 128, int)             /* set socket for LibOT */
 #endif /* PRIVATE */
 
+#define SIOCGIFMAC	_IOWR('i', 130, struct ifreq)	/* get IF MAC label */
+#define SIOCSIFMAC	_IOW('i', 131, struct ifreq)	/* set IF MAC label */
+
 #endif /* !_SYS_SOCKIO_H_ */

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

@@ -60,6 +60,7 @@
 struct fdescnode;
 struct fileglob;
 struct ifnet;
+struct ifreq;
 struct lctx;
 struct mac;
 struct mac_module_data;
@@ -146,6 +147,15 @@
 void	mac_file_label_associate(struct ucred *cred, struct fileglob *fg);
 void	mac_file_label_destroy(struct fileglob *fg);
 void	mac_file_label_init(struct fileglob *fg);
+int	mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *mbuf);
+void	mac_ifnet_label_associate(struct ifnet *ifp);
+void	mac_ifnet_label_destroy(struct ifnet *ifp);
+int	mac_ifnet_label_get(struct ucred *cred, struct ifreq *ifr,
+	    struct ifnet *ifp);
+void	mac_ifnet_label_init(struct ifnet *ifp);
+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);
 struct label	*mac_lctx_label_alloc(void);

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

@@ -2,6 +2,7 @@
  * Copyright (c) 1999-2002 Robert N. M. Watson
  * Copyright (c) 2001 Ilmar S. Habibulin
  * Copyright (c) 2001-2004 Networks Associates Technology, Inc.
+ * Copyright (c) 2006 SPARTA, Inc.
  * All rights reserved.
  *
  * This software was developed by Robert Watson and Ilmar Habibulin for the
@@ -38,6 +39,11 @@
 #include <sys/kernel.h>
 #include <sys/mbuf.h>
 
+#include <net/if.h>
+
+#include <bsd/bsm/audit.h>
+#include <bsd/bsm/audit_kernel.h>
+
 #include <security/mac_internal.h>
 
 int	mac_label_mbufs	= 1;		/* Exported via sysctl in mac_base.c */
@@ -67,6 +73,23 @@
 	return (label);
 }
 
+static struct label *
+mac_ifnet_label_alloc(void)
+{
+	struct label *label;
+
+	label = mac_labelzone_alloc(M_WAITOK);
+	MAC_PERFORM(ifnet_label_init, label);
+	return (label);
+}
+
+void
+mac_ifnet_label_init(struct ifnet *ifp)
+{
+
+	ifp->if_label = mac_ifnet_label_alloc();
+}
+
 /*
  * On failure, caller should cleanup with m_tag_free().
  */
@@ -86,7 +109,30 @@
 	return (error);
 }
 
+static void
+mac_ifnet_label_free(struct label *label)
+{
+
+	MAC_PERFORM(ifnet_label_destroy, label);
+	mac_labelzone_free(label);
+}
+
+void
+mac_ifnet_label_destroy(struct ifnet *ifp)
+{
+
+	mac_ifnet_label_free(ifp->if_label);
+	ifp->if_label = NULL;
+}
+
 void
+mac_ifnet_label_recycle(struct ifnet *ifp)
+{
+
+	MAC_PERFORM(ifnet_label_recycle, ifp->if_label);
+}
+
+void
 mac_mbuf_tag_destroy(struct m_tag *tag)
 {
 	struct label *label;
@@ -132,6 +178,41 @@
 	MAC_PERFORM(mbuf_label_copy, src_label, dest_label);
 }
 
+static void
+mac_ifnet_label_copy(struct label *src, struct label *dest)
+{
+
+	MAC_PERFORM(ifnet_label_copy, src, dest);
+}
+
+static int
+mac_ifnet_label_externalize(struct label *label, char *elements,
+    char *outbuf, size_t outbuflen)
+{
+	int error;
+
+	error = MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen);
+
+	return (error);
+}
+
+static int
+mac_ifnet_label_internalize(struct label *label, char *string)
+{
+	int error;
+
+	error = MAC_INTERNALIZE(ifnet, label, string);
+
+	return (error);
+}
+
+void
+mac_ifnet_label_associate(struct ifnet *ifp)
+{
+
+	MAC_PERFORM(ifnet_label_associate, ifp, ifp->if_label);
+}
+
 int
 mac_mbuf_label_init(struct mbuf *m, int flag)
 {
@@ -171,16 +252,17 @@
 }
 
 void
-mac_mbuf_label_associate_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
+mac_mbuf_label_associate_ifnet(struct ifnet *ifp, struct mbuf *mbuf)
 {
-	struct label *label;
+	struct label *m_label;
 
-	/* ifnet must be locked */
+	/* ifp must be locked */
 
-	label = mac_mbuf_to_label(mbuf);
+	m_label = mac_mbuf_to_label(mbuf);
 
 	/* Policy must deal with NULL label (unlabeled mbufs) */
-	MAC_PERFORM(mbuf_label_associate_ifnet, ifnet, mbuf, label);
+	MAC_PERFORM(mbuf_label_associate_ifnet, ifp, ifp->if_label, mbuf,
+	    m_label);
 }
 
 void
@@ -192,9 +274,133 @@
 	/* socket must be locked */
 
 	label = mac_mbuf_to_label(mbuf);
-        
+
 	/* Policy must deal with NULL label (unlabeled mbufs) */
 	sotoxsocket(socket, &xso);
 	MAC_PERFORM(mbuf_label_associate_socket, &xso, socket->so_label,
 		    mbuf, label);
 }
+
+int
+mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *mbuf)
+{
+	struct label *label;
+	int error;
+
+	label = mac_mbuf_to_label(mbuf);
+
+	ifnet_lock_shared(ifp);
+	MAC_CHECK(ifnet_check_transmit, ifp, ifp->if_label, mbuf, label);
+	ifnet_lock_done(ifp);
+
+	return (error);
+}
+
+int
+mac_ifnet_label_get(__unused struct ucred *cred, struct ifreq *ifr,
+    struct ifnet *ifp)
+{
+	char *elements, *buffer;
+	struct label *intlabel;
+	struct mac mac;
+	int error;
+	size_t len;
+
+	error = copyin(CAST_USER_ADDR_T(ifr->ifr_ifru.ifru_data),
+	    &mac, sizeof(mac));
+	if (error)
+		return (error);
+
+	error = mac_check_structmac_consistent(&mac);
+	if (error)
+		return (error);
+
+	MALLOC(elements, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
+	error = copyinstr(CAST_USER_ADDR_T(mac.m_string), elements,
+	    mac.m_buflen, &len);
+	if (error) {
+		FREE(elements, M_MACTEMP);
+		return (error);
+	}
+	AUDIT_ARG(mac_string, elements);
+
+	MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
+	intlabel = mac_ifnet_label_alloc();
+	ifnet_lock_shared(ifp);
+	mac_ifnet_label_copy(ifp->if_label, intlabel);
+	ifnet_lock_done(ifp);
+	error = mac_ifnet_label_externalize(intlabel, elements,
+	    buffer, mac.m_buflen);
+	mac_ifnet_label_free(intlabel);
+	FREE(elements, M_MACTEMP);
+
+	if (error == 0)
+		error = copyout(buffer, CAST_USER_ADDR_T(mac.m_string),
+		    strlen(buffer) + 1);
+	FREE(buffer, M_MACTEMP);
+
+	return (error);
+}
+
+int
+mac_ifnet_label_set(struct ucred *cred, struct ifreq *ifr,
+    struct ifnet *ifp)
+{
+	struct label *intlabel;
+	struct mac mac;
+	char *buffer;
+	int error;
+	size_t len;
+
+	error = copyin(CAST_USER_ADDR_T(ifr->ifr_ifru.ifru_data),
+	    &mac, sizeof(mac));
+	if (error)
+		return (error);
+
+	error = mac_check_structmac_consistent(&mac);
+	if (error)
+		return (error);
+
+	MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
+	error = copyinstr(CAST_USER_ADDR_T(mac.m_string), buffer,
+	    mac.m_buflen, &len);
+	if (error) {
+		FREE(buffer, M_MACTEMP);
+		return (error);
+	}
+	AUDIT_ARG(mac_string, buffer);
+
+	intlabel = mac_ifnet_label_alloc();
+	error = mac_ifnet_label_internalize(intlabel, buffer);
+	FREE(buffer, M_MACTEMP);
+	if (error) {
+		mac_ifnet_label_free(intlabel);
+		return (error);
+	}
+
+	/*
+	 * XXX: Note that this is a redundant privilege check, since
+	 * policies impose this check themselves if required by the
+	 * policy.  Eventually, this should go away.
+	 */
+	error = suser(cred, NULL);
+	if (error) {
+		mac_ifnet_label_free(intlabel);
+		return (error);
+	}
+
+	ifnet_lock_exclusive(ifp);
+	MAC_CHECK(ifnet_check_label_update, cred, ifp, ifp->if_label,
+	    intlabel);
+	if (error) {
+		ifnet_lock_done(ifp);
+		mac_ifnet_label_free(intlabel);
+		return (error);
+	}
+
+	MAC_PERFORM(ifnet_label_update, cred, ifp, ifp->if_label, intlabel);
+	ifnet_lock_done(ifp);
+	mac_ifnet_label_free(intlabel);
+
+	return (0);
+}

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

@@ -61,7 +61,6 @@
 struct devnode;
 struct fileglob;
 struct ifnet;
-struct ipq;
 struct label;
 struct lctx;
 struct mac_module_data;
@@ -814,6 +813,159 @@
 	struct label *label
 );
 /**
+  @brief Access control check for relabeling network interfaces
+  @param cred Subject credential
+  @param ifp network interface being relabeled
+  @param ifnetlabel Current label of the network interfaces
+  @param newlabel New label to apply to the network interfaces
+  @see mpo_ifnet_label_update_t
+
+  Determine whether the subject identified by the credential can
+  relabel the network interface represented by ifp to the supplied
+  new label (newlabel).
+
+  @return Return 0 if access is granted, otherwise an appropriate value for
+  errno should be returned.
+*/
+typedef int mpo_ifnet_check_label_update_t(
+	struct ucred *cred,
+	struct ifnet *ifp,
+	struct label *ifnetlabel,
+	struct label *newlabel
+);
+/**
+  @brief Access control check for relabeling network interfaces
+  @param ifp Network interface mbuf will be transmitted through
+  @param ifnetlabel Label of the network interfaces
+  @param m The mbuf to be transmitted
+  @param mbuflabel Label of the mbuf to be transmitted
+
+  Determine whether the mbuf with label mbuflabel may be transmitted
+  through the network interface represented by ifp that has the
+  label ifnetlabel.
+
+  @return Return 0 if access is granted, otherwise an appropriate value for
+  errno should be returned.
+*/
+typedef int mpo_ifnet_check_transmit_t(
+	struct ifnet *ifp,
+	struct label *ifnetlabel,
+	struct mbuf *m,
+	struct label *mbuflabel
+);
+/**
+  @brief Create a network interface label
+  @param ifp Network interface labeled
+  @param ifnetlabel Label for the network interface
+
+  Set the label of a newly created network interface, most likely
+  using the information in the supplied network interface struct.
+*/
+typedef void mpo_ifnet_label_associate_t(
+	struct ifnet *ifp,
+	struct label *ifnetlabel
+);
+/**
+  @brief Copy an ifnet label
+  @param src Source ifnet label
+  @param dest Destination ifnet label
+
+  Copy the label information from src to dest.
+*/
+typedef void mpo_ifnet_label_copy_t(
+	struct label *src,
+	struct label *dest
+);
+/**
+ @brief Destroy ifnet label
+ @param label The label to be destroyed
+*/
+typedef void mpo_ifnet_label_destroy_t(
+	struct label *label
+);
+/**
+  @brief Externalize an ifnet label
+  @param label Label to be externalized
+  @param element_name Name of the label namespace for which labels should be
+  externalized
+  @param sb String buffer to be filled with a text representation of the label
+
+  Produce an external representation of the label on an interface.
+  An externalized label consists of a text representation of the
+  label contents that can be used with user applications.
+  Policy-agnostic user space tools will display this externalized
+  version.
+
+  @return 0 on success, return non-zero if an error occurs while
+  externalizing the label data.
+
+*/
+typedef int mpo_ifnet_label_externalize_t(
+	struct label *label,
+	char *element_name,
+	struct sbuf *sb
+);
+/**
+  @brief Initialize ifnet label
+  @param label New label to initialize
+*/
+typedef void mpo_ifnet_label_init_t(
+	struct label *label
+);
+/**
+  @brief Internalize an interface label
+  @param label Label to be internalized
+  @param element_name Name of the label namespace for which the label should
+  be internalized
+  @param element_data Text data to be internalized
+
+  Produce an interface label from an external representation.  An
+  externalized label consists of a text representation of the label
+  contents that can be used with user applications.  Policy-agnostic
+  user space tools will forward text version to the kernel for
+  processing by individual policy modules.
+
+  The policy's internalize entry points will be called only if the
+  policy has registered interest in the label namespace.
+
+  @return 0 on success, Otherwise, return non-zero if an error occurs
+  while internalizing the label data.
+
+*/
+typedef int mpo_ifnet_label_internalize_t(
+	struct label *label,
+	char *element_name,
+	char *element_data
+);
+/**
+  @brief Recycle up a network interface label
+  @param label The label to be recycled
+
+  Recycle a network interface label.  Darwin caches the struct ifnet
+  of detached ifnets in a "free pool".  Before ifnets are returned
+  to the "free pool", policies can cleanup or overwrite any information
+  present in the label.
+*/
+typedef void mpo_ifnet_label_recycle_t(
+	struct label *label
+);
+/**
+  @brief Update a network interface label
+  @param cred Subject credential
+  @param ifp The network interface to be relabeled
+  @param ifnetlabel The current label of the network interface
+  @param newlabel A new label to apply to the network interface
+  @see mpo_ifnet_check_label_update_t
+
+  Update the label on a network interface, using the supplied new label.
+*/
+typedef void mpo_ifnet_label_update_t(
+	struct ucred *cred,
+	struct ifnet *ifp,
+	struct label *ifnetlabel,
+	struct label *newlabel
+);
+/**
   @brief Device hardware access control
   @param devtype Type of device connected
   @param properties XML-formatted property list
@@ -990,7 +1142,7 @@
 );
 /**
  @brief Assign a label to a new mbuf
- @param ifnet Interface descriptor
+ @param ifp Interface descriptor
  @param m Object; mbuf
  @param m_label Policy label to fill in for m
 
@@ -998,6 +1150,7 @@
 */
 typedef void mpo_mbuf_label_associate_ifnet_t(
 	struct ifnet *ifp,
+	struct label *i_label,
 	struct mbuf *m,
 	struct label *m_label
 );
@@ -5025,6 +5178,16 @@
 	mpo_file_label_init_t			*mpo_file_label_init;
 	mpo_file_label_destroy_t		*mpo_file_label_destroy;
 	mpo_file_label_associate_t		*mpo_file_label_associate;
+	mpo_ifnet_check_label_update_t		*mpo_ifnet_check_label_update;
+	mpo_ifnet_check_transmit_t		*mpo_ifnet_check_transmit;
+	mpo_ifnet_label_associate_t		*mpo_ifnet_label_associate;
+	mpo_ifnet_label_copy_t			*mpo_ifnet_label_copy;
+	mpo_ifnet_label_destroy_t		*mpo_ifnet_label_destroy;
+	mpo_ifnet_label_externalize_t		*mpo_ifnet_label_externalize;
+	mpo_ifnet_label_init_t			*mpo_ifnet_label_init;
+	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_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;

==== //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#26 (text+ko) ====

@@ -1543,16 +1543,17 @@
 
 static void
 mac_mls_mbuf_label_associate_ifnet(struct ifnet *ifnet,
-			 	 struct mbuf *mbuf, struct label *mbuflabel)
+    struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel)
 {
-	struct mac_mls *dest;
+	struct mac_mls *source, *dest;
 
-	if (mbuflabel == NULL)
+	if (ifnetlabel == NULL || mbuflabel == NULL)
 		return;
 
+	source = SLOT(ifnetlabel);
 	dest = SLOT(mbuflabel);
 
-	mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
+	mac_mls_copy_effective(source, dest);
 }
 
 static void

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

@@ -919,6 +919,7 @@
 
 	network_label_copy(blabel, mlabel);
 }
+#endif
 
 static void
 sebsd_mbuf_label_associate_ifnet(struct ifnet *ifn, struct label *ilabel,
@@ -927,7 +928,6 @@
 
 	network_label_copy(ilabel, mlabel);
 }
-#endif
 
 static void
 sebsd_posixsem_label_associate(struct ucred *cred, struct pseminfo *psem,
@@ -1800,7 +1800,7 @@
     struct label *oldlabel, struct label *newlabel)
 {
 
-	network_label_copy(oldlabel, newlabel);
+	network_label_copy(newlabel, oldlabel);
 }
 
 static void
@@ -3023,7 +3023,86 @@
 	return (file_has_perm(cred, fg, fglabel, 0));
 }
 
+static void
+sebsd_ifnet_label_update(struct ucred *cred, struct ifnet *ifp,
+    struct label *ifnetlabel, struct label *newlabel)
+{
+
+	network_label_copy(newlabel, ifnetlabel);
+}
+
+static void
+sebsd_ifnet_label_associate(struct ifnet *ifp, struct label *ifnetlabel)
+{
+	struct network_security_struct *nsec;
+
+	/*
+	 * We just set the label to a default value and require that
+	 * the system set a more specific value at ifconfig time.
+	 */
+	nsec = SLOT(ifnetlabel);
+	if (nsec != NULL) {
+		nsec->sid = SECINITSID_NETIF;
+		nsec->sclass = SECCLASS_NETIF;
+	}
+}
+
+#if 0
+static int
+sebsd_ifnet_check_label_update(struct ucred *cred, struct ifnet *ifp,
+    struct label *ifnetlabel, struct label *newlabel)
+{
+	struct network_security_struct *nsec, *tsec;
+	int rc;
+
+	nsec = SLOT(newlabel);
+	tsec = SLOT(socklabel);
+
+	if (nsec == NULL)
+		return (0);
+
+	/* XXX - no NETIF__RELABEL{TO,FROM} */
+	rc = avc_has_perm(tsec->sid, tsec->sid, SECCLASS_NETIF,
+	    SOCKET__RELABELFROM, NULL);
+	if (rc)
+		return (rc);
+
+	rc = avc_has_perm(tsec->sid, nsec->sid, SECCLASS_NETIF,
+	    SOCKET__RELABELTO, NULL);
+	if (rc)
+		return (rc);
+
+	return (0);
+}
+#endif
+
 static int
+sebsd_ifnet_check_transmit(struct ifnet *ifp,
+    struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel)
+{
+	struct network_security_struct *ifsec, *msec;
+	int error;
+
+	if (ifnetlabel == NULL || mbuflabel == NULL) {
+		/* XXX - mbufs are not always labelled! */
+		return (0);
+	}
+
+	ifsec = SLOT(ifnetlabel);
+	msec = SLOT(mbuflabel);
+
+	if (ifsec == NULL || msec == NULL) {
+		/* XXX - should not happen, log and fix */
+		return (0);
+	}
+
+	/* XXX - use an audit struct so we can log useful info */
+	error = avc_has_perm(msec->sid, ifsec->sid, SECCLASS_PACKET,
+	    PACKET__SEND, NULL);
+	return (error);
+}
+
+static int
 ipc_has_perm(struct ucred *cred, struct label *label, u_int32_t perm)
 {
 	struct task_security_struct *task;
@@ -3396,6 +3475,17 @@
 	.mpo_file_label_associate = sebsd_file_label_associate,
 	.mpo_file_label_destroy = sebsd_label_destroy,
 	.mpo_file_label_init = sebsd_label_init,
+	//.mpo_ifnet_check_label_update = XXX,
+	.mpo_ifnet_check_transmit = sebsd_ifnet_check_transmit,
+	.mpo_ifnet_label_associate = sebsd_ifnet_label_associate,
+	.mpo_ifnet_label_copy = sebsd_label_copy,
+	.mpo_ifnet_label_destroy = sebsd_label_destroy,
+	.mpo_ifnet_label_externalize = sebsd_label_externalize,
+	.mpo_ifnet_label_init = sebsd_label_init,
+	.mpo_ifnet_label_internalize = sebsd_label_internalize,
+	.mpo_ifnet_label_recycle = sebsd_label_recycle,
+	.mpo_ifnet_label_update = sebsd_ifnet_label_update,
+	.mpo_mbuf_label_associate_ifnet = sebsd_mbuf_label_associate_ifnet,
 	.mpo_mbuf_label_associate_socket = sebsd_mbuf_label_associate_socket,
 	.mpo_mbuf_label_copy = network_label_copy,
 	.mpo_mbuf_label_destroy = sebsd_label_destroy,

==== //depot/projects/trustedbsd/sedarwin8/policies/test/mac_test.c#19 (text+ko) ====

@@ -1637,12 +1637,14 @@
 }
 
 static void
-mac_test_mbuf_label_associate_ifnet(struct ifnet *ifnet,
+mac_test_mbuf_label_associate_ifnet(struct ifnet *ifnet, struct label *i_label,
     struct mbuf *m, struct label *m_label)
 {
 	CHECKNULL(ifnet);
 	CHECKNULL(m);
 
+	if (i_label != NULL)
+		INIT_LABEL(i_label, SOCKETTYPE);
 	if (m_label != NULL)
 		INIT_LABEL(m_label, SOCKETTYPE);
 }


More information about the trustedbsd-cvs mailing list