Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Apr 2003 10:07:17 -0700 (PDT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 28709 for review
Message-ID:  <200304101707.h3AH7HB8093395@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=28709

Change 28709 by rwatson@rwatson_tislabs on 2003/04/10 10:07:11

	Move MAC label storage for mbufs into m_tags from the m_pkthdr
	structure, returning some additional room in the first mbuf in a
	chain, and avoiding feature-specific contents in the mbuf header.
	To do this:
	
	- Add a helper function mbuf_to_label(), which extracts the m_tag
	  holding a label from the mbuf header m_tag chain, and casts
	  as appropriate to a label.  NULL is returned if no m_tag is found.
	
	- Introduce mac_init_mbuf_tag() which does most of the work
	  mac_init_mbuf() used to do, except on an m_tag rather than an
	  mbuf.
	
	- Scale back mac_init_mbuf() to perform m_tag allocation and invoke
	  mac_init_mbuf_tag().
	
	- Replace mac_destroy_mbuf() with mac_destroy_mbuf_tag(), since
	  m_tag's are now GC'd deep in the m_tag/mbuf code rather than
	  at a higher level when mbufs are directly free()'d.
	
	- Add mac_copy_mbuf_tag() to support m_copy_pkthdr() and related
	  notions.
	
	- Generally change all references to mbuf labels so that they use
	  mbuf_to_label() rather than &mbuf->m_pkthdr.label.  This
	  required no changes in the MAC policies (yay!).
	
	- Tweak mbuf release routines to not call mac_destroy_mbuf().
	
	- Remove MAC magic from m_copy_pkthdr() and m_move_pkthdr() --
	  the existing m_tag support does all this for us.  Note that
	  we can no longer just zero the m_tag list on the target mbuf,
	  rather, we have to delete the chain because m_tag's will
	  already be hung off freshly allocated mbuf's.
	
	- Tweak m_tag copying routines so that if we're copying a MAC
	  m_tag, we don't do a binary copy, rather, we initialize the
	  new storage and do a deep copy of the label.
	
	- Remove use of MAC_FLAG_INITIALIZED in a few bizarre places
	  having to do with mbuf header copies previously.
	
	- When an mbuf is copied in ip_input(), we no longer need to
	  explicitly copy the label because it will get handled by the
	  m_tag code now.
	
	- Add MPC_LOADTIME_FLAG_LABELMBUFS flag to Biba, MLS, mac_test.
	  In mac_test, handle the label==NULL case, since it can be
	  dynamically loaded.
	
	In order to improve performance with this change, introduce the
	notion of "lazy MAC label allocation" -- only allocate m_tag
	storage for MAC labels if we're running with a policy that uses
	MAC labels on mbufs.  Policies declare this intent by setting the
	MPC_LOADTIME_FLAG_LABELMBUFS flag in their load-time flags field
	during declaration.  Note: this opens up the possibility of
	post-boot policy modules getting back NULL slot entries even
	though they have policy invariants of non-NULL slot entries, as
	the policy might have been loaded after the mbuf was allocated,
	leaving the mbuf without label storage.  Policies that cannot
	handle this case must be declared as NOTLATE, or must be modified.
	
	- mac_labelmbufs holds the current cumulative status as to whether
	  any policies require mbuf labeling or not.  This is updated
	  whenever the active policy set changes by the function
	  mac_policy_updateflags().  The function iterates the list and
	  checks whether any have the flag set.  Write access to this
	  variable is protected by the policy list; read access is
	  currently not protected for performance reasons.  This might
	  change if it causes problems.
	
	- Add MAC_POLICY_LIST_ASSERT_EXCLUSIVE() to permit the flags
	  update function to assert appropriate locks.
	
	- This makes allocation in mac_init_mbuf() conditional on the
	  flag.

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/conf/options#47 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#379 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/subr_mbuf.c#31 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/uipc_mbuf.c#20 edit
.. //depot/projects/trustedbsd/mac/sys/kern/uipc_mbuf2.c#11 integrate
.. //depot/projects/trustedbsd/mac/sys/net/if_loop.c#19 integrate
.. //depot/projects/trustedbsd/mac/sys/netinet/ip_input.c#29 integrate
.. //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.c#203 integrate
.. //depot/projects/trustedbsd/mac/sys/security/mac_lomac/mac_lomac.c#57 integrate
.. //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#162 integrate
.. //depot/projects/trustedbsd/mac/sys/security/mac_test/mac_test.c#98 integrate
.. //depot/projects/trustedbsd/mac/sys/sys/mac.h#233 integrate
.. //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h#185 integrate
.. //depot/projects/trustedbsd/mac/sys/sys/mbuf.h#27 integrate

Differences ...

==== //depot/projects/trustedbsd/mac/sys/conf/options#47 (text+ko) ====

@@ -154,6 +154,7 @@
 
 # Support for Mandatory Access Control (MAC)
 MAC		opt_mac.h
+MAC_ALWAYS_LABEL_MBUF	opt_mac.h
 MAC_BIBA	opt_dontuse.h
 MAC_BSDEXTENDED	opt_dontuse.h
 MAC_DEBUG	opt_mac.h

==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#379 (text+ko) ====

@@ -120,6 +120,21 @@
  */
 static int	ea_warn_once = 0;
 
+#ifndef MAC_ALWAYS_LABEL_MBUF
+/*
+ * Flag to indicate whether or not we should allocate label storage for
+ * new mbufs.  Since most dynamic policies we currently work with don't
+ * rely on mbuf labeling, try to avoid paying the cost of mtag allocation
+ * unless specifically notified of interest.  One result of this is
+ * that if a dynamically loaded policy requests mbuf labels, it must
+ * be able to deal with a NULL label being returned on any mbufs that
+ * were already in flight when the policy was loaded.  Since the policy
+ * already has to deal with uninitialized labels, this probably won't
+ * be a problem.  Note: currently no locking.  Will this be a problem?
+ */
+static int	mac_labelmbufs = 0;
+#endif
+
 static int	mac_enforce_fs = 1;
 SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -281,6 +296,12 @@
 		    &mac_policy_list_lock);				\
 } while (0)
 
+#define	MAC_POLICY_LIST_ASSERT_EXCLUSIVE() do {				\
+	mtx_assert(&mac_policy_list_lock, MA_OWNED);			\
+	KASSERT(mac_policy_list_busy == 0,				\
+	    ("MAC_POLICY_LIST_ASSERT_EXCLUSIVE()"));			\
+} while (0)
+
 #define	MAC_POLICY_LIST_BUSY() do {					\
 	MAC_POLICY_LIST_LOCK();						\
 	mac_policy_list_busy++;						\
@@ -464,6 +485,35 @@
 }
 
 /*
+ * After the policy list has changed, walk the list to update any global
+ * flags.
+ */
+static void
+mac_policy_updateflags(void)
+{
+	struct mac_policy_conf *tmpc;
+#ifndef MAC_ALWAYS_LABEL_MBUF
+	int labelmbufs;
+#endif
+
+	MAC_POLICY_LIST_ASSERT_EXCLUSIVE();
+
+#ifndef MAC_ALWAYS_LABEL_MBUF
+	labelmbufs = 0;
+#endif
+	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
+#ifndef MAC_ALWAYS_LABEL_MBUF
+		if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
+			labelmbufs++;
+#endif
+	}
+
+#ifndef MAC_ALWAYS_LABEL_MBUF
+	mac_labelmbufs = (labelmbufs != 0);
+#endif
+}
+
+/*
  * Allow MAC policy modules to register during boot, etc.
  */
 int
@@ -530,6 +580,7 @@
 	/* Per-policy initialization. */
 	if (mpc->mpc_ops->mpo_init != NULL)
 		(*(mpc->mpc_ops->mpo_init))(mpc);
+	mac_policy_updateflags();
 	MAC_POLICY_LIST_UNLOCK();
 
 	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
@@ -574,7 +625,7 @@
 
 	LIST_REMOVE(mpc, mpc_list);
 	mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
-
+	mac_policy_updateflags();
 	MAC_POLICY_LIST_UNLOCK();
 
 	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
@@ -620,6 +671,18 @@
 	return (error2);
 }
 
+static struct label *
+mbuf_to_label(struct mbuf *mbuf)
+{
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	label = (struct label *)(tag+1);
+
+	return (label);
+}
+
 static void
 mac_init_label(struct label *label)
 {
@@ -717,20 +780,20 @@
 }
 
 int
-mac_init_mbuf(struct mbuf *m, int flag)
+mac_init_mbuf_tag(struct m_tag *tag, int flag)
 {
-	int error;
+	struct label *label;
+	int error, trflag;
 
-	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
+	label = (struct label *) (tag + 1);
+	mac_init_label(label);
 
-	mac_init_label(&m->m_pkthdr.label);
-
-	MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag);
+	trflag = (flag == M_DONTWAIT ? M_NOWAIT : M_WAITOK);
+	MAC_CHECK(init_mbuf_label, label, trflag);
 	if (error) {
-		MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
-		mac_destroy_label(&m->m_pkthdr.label);
+		MAC_PERFORM(destroy_mbuf_label, label);
+		mac_destroy_label(label);
 	}
-
 #ifdef MAC_DEBUG
 	if (error == 0)
 		atomic_add_int(&nmacmbufs, 1);
@@ -738,6 +801,35 @@
 	return (error);
 }
 
+int
+mac_init_mbuf(struct mbuf *m, int flag)
+{
+	struct m_tag *tag;
+	int error;
+
+#ifndef MAC_ALWAYS_LABEL_MBUF
+	/*
+	 * Don't reserve space for labels on mbufs unless we have a policy
+	 * that uses the labels.
+	 */
+	if (mac_labelmbufs) {
+#endif
+		tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
+		    flag);
+		if (tag == NULL)
+			return (ENOMEM);
+		error = mac_init_mbuf_tag(tag, flag);
+		if (error) {
+			m_tag_free(tag);
+			return (error);
+		}
+		m_tag_prepend(m, tag);
+#ifndef MAC_ALWAYS_LABEL_MBUF
+	}
+#endif
+	return (0);
+}
+
 void
 mac_init_mount(struct mount *mp)
 {
@@ -925,11 +1017,14 @@
 }
 
 void
-mac_destroy_mbuf(struct mbuf *m)
+mac_destroy_mbuf_tag(struct m_tag *tag)
 {
+	struct label *label;
 
-	MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
-	mac_destroy_label(&m->m_pkthdr.label);
+	label = (struct label *)(tag+1);
+
+	MAC_PERFORM(destroy_mbuf_label, label);
+	mac_destroy_label(label);
 #ifdef MAC_DEBUG
 	atomic_subtract_int(&nmacmbufs, 1);
 #endif
@@ -1023,6 +1118,23 @@
 	mac_destroy_vnode_label(&vp->v_label);
 }
 
+void
+mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
+{
+	struct label *src_label, *dest_label;
+
+	src_label = (struct label *)(src+1);
+	dest_label = (struct label *)(dest+1);
+
+#if 0
+	/*
+	 * XXXMAC: init here? */
+	 */
+	mac_init_m...?
+#endif
+	MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
+}
+
 static void
 mac_copy_pipe_label(struct label *src, struct label *dest)
 {
@@ -2093,9 +2205,12 @@
 void
 mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
 {
+	struct label *label;
+
+	label = mbuf_to_label(mbuf);
 
-	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
-	    socket, &socket->so_peerlabel);
+	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
+	    &socket->so_peerlabel);
 }
 
 void
@@ -2110,85 +2225,117 @@
 void
 mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
 {
+	struct label *label;
+
+	label = mbuf_to_label(datagram);
 
 	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
-	    datagram, &datagram->m_pkthdr.label);
+	    datagram, label);
 }
 
 void
 mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
 {
+	struct label *datagramlabel, *fragmentlabel;
+
+	datagramlabel = mbuf_to_label(datagram);
+	fragmentlabel = mbuf_to_label(fragment);
 
-	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
-	    fragment, &fragment->m_pkthdr.label);
+	MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
+	    fragmentlabel);
 }
 
 void
 mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
 {
+	struct label *label;
 
-	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
-	    &ipq->ipq_label);
+	label = mbuf_to_label(fragment);
+
+	MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
 }
 
 void
 mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
 {
+	struct label *oldmbuflabel, *newmbuflabel;
 
-	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
-	    newmbuf, &newmbuf->m_pkthdr.label);
+	oldmbuflabel = mbuf_to_label(oldmbuf);
+	newmbuflabel = mbuf_to_label(newmbuf);
+
+	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
+	    newmbuflabel);
 }
 
 void
 mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
 {
+	struct label *label;
 
+	label = mbuf_to_label(mbuf);
+
 	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
 mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
 {
+	struct label *label;
+
+	label = mbuf_to_label(mbuf);
 
 	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
 mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
 {
+	struct label *label;
+
+	label = mbuf_to_label(mbuf);
 
 	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
 mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
     struct mbuf *newmbuf)
 {
+	struct label *oldmbuflabel, *newmbuflabel;
 
-	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
-	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
-	    &newmbuf->m_pkthdr.label);
+	oldmbuflabel = mbuf_to_label(oldmbuf);
+	newmbuflabel = mbuf_to_label(newmbuf);
+
+	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
+	    ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
 }
 
 void
 mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
 {
+	struct label *oldmbuflabel, *newmbuflabel;
+
+	oldmbuflabel = mbuf_to_label(oldmbuf);
+	newmbuflabel = mbuf_to_label(newmbuf);
 
-	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
-	    newmbuf, &newmbuf->m_pkthdr.label);
+	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
+	    newmbuflabel);
 }
 
 int
 mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
 {
+	struct label *label;
 	int result;
 
+	label = mbuf_to_label(fragment);
+
 	result = 1;
-	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
-	    ipq, &ipq->ipq_label);
+	MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
+	    &ipq->ipq_label);
 
 	return (result);
 }
@@ -2196,17 +2343,22 @@
 void
 mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
 {
+	struct label *label;
+
+	label = mbuf_to_label(fragment);
 
-	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
-	    &ipq->ipq_label);
+	MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
 }
 
 void
 mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
 {
+	struct label *label;
 
+	label = mbuf_to_label(mbuf);
+
 	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
@@ -2265,17 +2417,18 @@
 int
 mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
 {
+	struct label *label;
 	int error;
 
+	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
+
 	if (!mac_enforce_network)
 		return (0);
 
-	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
-	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
-		if_printf(ifnet, "not initialized\n");
+	label = mbuf_to_label(mbuf);
 
 	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 
 	return (error);
 }
@@ -2571,13 +2724,16 @@
 int
 mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
 {
+	struct label *label;
 	int error;
 
 	if (!mac_enforce_socket)
 		return (0);
 
+	label = mbuf_to_label(mbuf);
+
 	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 
 	return (error);
 }

==== //depot/projects/trustedbsd/mac/sys/kern/subr_mbuf.c#31 (text+ko) ====

@@ -1301,14 +1301,18 @@
 m_gethdr(int how, short type)
 {
 	struct mbuf *mb;
+#ifdef MAC
+	int error;
+#endif
 
 	mb = (struct mbuf *)mb_alloc(&mb_list_mbuf, how, type, 0, NULL);
 	if (mb != NULL) {
 		_mbhdr_setup(mb, type);
 #ifdef MAC
-		if (mac_init_mbuf(mb, MBTOM(how)) != 0) {
+		error = mac_init_mbuf(mb, MBTOM(how));
+		if (error) {
 			m_free(mb);
-			return NULL;
+			return (NULL);
 		}
 #endif
 	}
@@ -1347,17 +1351,21 @@
  *  - type: the type of the mbuf being allocated.
  */
 struct mbuf *
-m_gethdr_clrd(int how, short type)
+m_gethdr_clrd(int  how, short type)
 {
 	struct mbuf *mb;
+#ifdef MAC
+	int error;
+#endif
 
 	mb = (struct mbuf *)mb_alloc(&mb_list_mbuf, how, type, 0, NULL);
 	if (mb != NULL) {
 		_mbhdr_setup(mb, type);
 #ifdef MAC
-		if (mac_init_mbuf(mb, MBTOM(how)) != 0) {
+		error = mac_init_mbuf(mb, MBTOM(how));
+		if (error) {
 			m_free(mb);
-			return NULL;
+			return (NULL);
 		}
 #endif
 		bzero(mtod(mb, caddr_t), MHLEN);
@@ -1383,11 +1391,6 @@
 
 	if ((mb->m_flags & M_PKTHDR) != 0)
 		m_tag_delete_chain(mb, NULL);
-#ifdef MAC
-	if ((mb->m_flags & M_PKTHDR) &&
-	    (mb->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
-		mac_destroy_mbuf(mb);
-#endif
 	nb = mb->m_next;
 	if ((mb->m_flags & M_EXT) != 0) {
 		MEXT_REM_REF(mb);
@@ -1430,11 +1433,6 @@
 	while (mb != NULL) {
 		if ((mb->m_flags & M_PKTHDR) != 0)
 			m_tag_delete_chain(mb, NULL);
-#ifdef MAC
-		if ((mb->m_flags & M_PKTHDR) &&
-		    (mb->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
-			mac_destroy_mbuf(mb);
-#endif
 		persist = 0;
 		m = mb;
 		mb = mb->m_next;
@@ -1476,6 +1474,9 @@
 m_getcl(int how, short type, int flags)
 {
 	struct mbuf *mb;
+#ifdef MAC
+	int error;
+#endif
 	int cchnum;
 
 	mb = (struct mbuf *)mb_alloc(&mb_list_mbuf, how, type,
@@ -1502,10 +1503,12 @@
 		_mext_init_ref(mb, &cl_refcntmap[cl2ref(mb->m_ext.ext_buf)]);
 	}
 #ifdef MAC
-	if ((flags & M_PKTHDR) && (mac_init_mbuf(mb, MBTOM(how))
-	    != 0)) {
-		m_free(mb);
-		return NULL;
+	if (flags & M_PKTHDR) {
+		error = mac_init_mbuf(mb, MBTOM(how));
+		if (error) {
+			m_free(mb);
+			return (NULL);
+		}
 	}
 #endif
 	return (mb);

==== //depot/projects/trustedbsd/mac/sys/kern/uipc_mbuf.c#20 (text+ko) ====

@@ -77,21 +77,21 @@
 	/* see below for why these are not enabled */
 	KASSERT(to->m_flags & M_PKTHDR,
 	    ("m_move_pkthdr: called on non-header"));
+	/* Note: with MAC, this may not be a good assertion. */
 	KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags),
 	    ("m_move_pkthdr: to has tags"));
 #endif
 	KASSERT((to->m_flags & M_EXT) == 0, ("m_move_pkthdr: to has cluster"));
 #ifdef MAC
+	/*
+	 * XXXMAC: It could be this should also occur for non-MAC?
+	 */
 	if (to->m_flags & M_PKTHDR)
-		mac_destroy_mbuf(to);
+		m_tag_delete_chain(to, NULL);
 #endif
 	to->m_flags = from->m_flags & M_COPYFLAGS;
 	to->m_data = to->m_pktdat;
 	to->m_pkthdr = from->m_pkthdr;		/* especially tags */
-#ifdef MAC
-	mac_init_mbuf(to, M_WAITOK);		/* XXXMAC no way to fail */
-	mac_create_mbuf_from_mbuf(from, to);
-#endif
 	SLIST_INIT(&from->m_pkthdr.tags);	/* purge tags from src */
 	from->m_flags &= ~M_PKTHDR;
 }
@@ -114,23 +114,19 @@
 	 * assertions to trip.  For now just disable them.
 	 */
 	KASSERT(to->m_flags & M_PKTHDR, ("m_dup_pkthdr: called on non-header"));
+	/* Note: with MAC, this may not be a good assertion. */
 	KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags"));
 #endif
-	KASSERT((to->m_flags & M_EXT) == 0, ("m_dup_pkthdr: to has cluster"));
 #ifdef MAC
 	if (to->m_flags & M_PKTHDR)
-		mac_destroy_mbuf(to);
+		m_tag_delete_chain(to, NULL);
 #endif
-	to->m_flags = from->m_flags & M_COPYFLAGS;
-	to->m_data = to->m_pktdat;
+	to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
+	if ((to->m_flags & M_EXT) == 0)
+		to->m_data = to->m_pktdat;
 	to->m_pkthdr = from->m_pkthdr;
-#ifdef MAC
-	mac_init_mbuf(to, M_WAITOK);		/* XXXMAC no way to fail */
-	mac_create_mbuf_from_mbuf(from, to);
-#endif
 	SLIST_INIT(&to->m_pkthdr.tags);
-	return (m_tag_copy_chain(to, from, (how & M_TRYWAIT) ? M_WAITOK :
-	    M_NOWAIT));
+	return (m_tag_copy_chain(to, from, MBTOM(how)));
 }
 
 /*
@@ -148,12 +144,8 @@
 		m_freem(m);
 		return (NULL);
 	}
-	if (m->m_flags & M_PKTHDR) {
+	if (m->m_flags & M_PKTHDR)
 		M_MOVE_PKTHDR(mn, m);
-#ifdef MAC
-		mac_destroy_mbuf(m);
-#endif
-	}
 	mn->m_next = m;
 	m = mn;
 	if (len < MHLEN)

==== //depot/projects/trustedbsd/mac/sys/kern/uipc_mbuf2.c#11 (text+ko) ====

@@ -68,10 +68,13 @@
 
 /*#define PULLDOWN_DEBUG*/
 
+#include "opt_mac.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
+#include <sys/mac.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
@@ -327,6 +330,10 @@
 void
 m_tag_free(struct m_tag *t)
 {
+#ifdef MAC
+	if (t->m_tag_id == PACKET_TAG_MACLABEL)
+		mac_destroy_mbuf_tag(t);
+#endif
 	free(t, M_PACKET_TAGS);
 }
 
@@ -402,7 +409,21 @@
 	p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how);
 	if (p == NULL)
 		return (NULL);
-	bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */
+#ifdef MAC
+	/*
+	 * XXXMAC: we should probably pass off the initialization, and
+	 * copying here?  can we hide that PACKET_TAG_MACLABEL is
+	 * special from the mbuf code?
+	 */
+	if (t->m_tag_id == PACKET_TAG_MACLABEL) {
+		if (mac_init_mbuf_tag(p, how) != 0) {
+			m_tag_free(p);
+			return (NULL);
+		}
+		mac_copy_mbuf_tag(t, p);
+	} else
+#endif
+		bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */
 	return p;
 }
 

==== //depot/projects/trustedbsd/mac/sys/net/if_loop.c#19 (text+ko) ====

@@ -214,14 +214,6 @@
 		if (!n)
 			goto contiguousfail;
 		M_MOVE_PKTHDR(n, m);
-#ifdef MAC
-		/* 
-		 * XXXMAC: Once we put labels in tags and proper
-		 * primitives are used for relocating mbuf header
-		 * data, this will no longer be required.
-		 */
-		m->m_pkthdr.label.l_flags &= ~MAC_FLAG_INITIALIZED;
-#endif
 		MCLGET(n, M_DONTWAIT);
 		if (! (n->m_flags & M_EXT)) {
 			m_freem(n);

==== //depot/projects/trustedbsd/mac/sys/netinet/ip_input.c#29 (text+ko) ====

@@ -1798,13 +1798,10 @@
 		mcopy->m_len = imin((ip->ip_hl << 2) + 8,
 		    (int)ip->ip_len);
 		m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
-#ifdef MAC
 		/*
-		 * XXXMAC: This will eventually become an explicit
-		 * labeling point.
+		 * XXXMAC: Eventually, we may have an explicit labeling
+		 * point here.
 		 */
-		mac_create_mbuf_from_mbuf(m, mcopy);
-#endif
 	}
 
 #ifdef IPSTEALTH

==== //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.c#203 (text+ko) ====

@@ -2770,4 +2770,4 @@
 };
 
 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
-    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
+    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);

==== //depot/projects/trustedbsd/mac/sys/security/mac_lomac/mac_lomac.c#57 (text+ko) ====

@@ -2767,4 +2767,5 @@
 };
 
 MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
-    MPC_LOADTIME_FLAG_NOTLATE, &mac_lomac_slot);
+    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
+    &mac_lomac_slot);

==== //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#162 (text+ko) ====

@@ -2536,4 +2536,4 @@
 };
 
 MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS",
-    MPC_LOADTIME_FLAG_NOTLATE, &mac_mls_slot);
+    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot);

==== //depot/projects/trustedbsd/mac/sys/security/mac_test/mac_test.c#98 (text+ko) ====

@@ -392,6 +392,14 @@
 mac_test_destroy_mbuf_label(struct label *label)
 {
 
+	/*
+	 * If we're loaded dynamically, there may be mbufs in flight that
+	 * didn't have label storage allocated for them.  Handle this
+	 * gracefully.
+	 */
+	if (label == NULL)
+		return;
+
 	if (SLOT(label) == MBUFMAGIC || SLOT(label) == 0) {
 		atomic_add_int(&destroy_count_mbuf, 1);
 		SLOT(label) = EXMAGIC;
@@ -1515,4 +1523,4 @@
 };
 
 MAC_POLICY_SET(&mac_test_ops, mac_test, "TrustedBSD MAC/Test",
-    MPC_LOADTIME_FLAG_UNLOADOK, &test_slot);
+    MPC_LOADTIME_FLAG_UNLOADOK | MPC_LOADTIME_FLAG_LABELMBUFS, &test_slot);

==== //depot/projects/trustedbsd/mac/sys/sys/mac.h#233 (text+ko) ====

@@ -109,6 +109,7 @@
 struct ifreq;
 struct image_params;
 struct ipq;
+struct m_tag;
 struct mbuf;
 struct mount;
 struct proc;
@@ -136,11 +137,13 @@
 int	mac_init_ipq(struct ipq *, int flag);
 int	mac_init_socket(struct socket *, int flag);
 void	mac_init_pipe(struct pipe *);
-int	mac_init_mbuf(struct mbuf *m, int flag);
+int	mac_init_mbuf(struct mbuf *mbuf, int flag);
+int	mac_init_mbuf_tag(struct m_tag *, int flag);
 void	mac_init_mount(struct mount *);
 void	mac_init_proc(struct proc *);
 void	mac_init_vnode(struct vnode *);
 void	mac_init_vnode_label(struct label *);
+void	mac_copy_mbuf_tag(struct m_tag *, struct m_tag *);
 void	mac_copy_vnode_label(struct label *, struct label *label);
 void	mac_destroy_bpfdesc(struct bpf_d *);
 void	mac_destroy_cred(struct ucred *);
@@ -150,7 +153,7 @@
 void	mac_destroy_socket(struct socket *);
 void	mac_destroy_pipe(struct pipe *);
 void	mac_destroy_proc(struct proc *);
-void	mac_destroy_mbuf(struct mbuf *);
+void	mac_destroy_mbuf_tag(struct m_tag *);
 void	mac_destroy_mount(struct mount *);
 void	mac_destroy_vnode(struct vnode *);
 void	mac_destroy_vnode_label(struct label *);

==== //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h#185 (text+ko) ====

@@ -95,6 +95,8 @@
 	void	(*mpo_destroy_pipe_label)(struct label *label);
 	void	(*mpo_destroy_proc_label)(struct label *label);
 	void	(*mpo_destroy_vnode_label)(struct label *label);
+	void	(*mpo_copy_mbuf_label)(struct label *src,
+		    struct label *dest);
 	void	(*mpo_copy_pipe_label)(struct label *src,
 		    struct label *dest);
 	void	(*mpo_copy_vnode_label)(struct label *src,
@@ -434,6 +436,7 @@
 /* Flags for the mpc_loadtime_flags field. */
 #define	MPC_LOADTIME_FLAG_NOTLATE	0x00000001
 #define	MPC_LOADTIME_FLAG_UNLOADOK	0x00000002
+#define	MPC_LOADTIME_FLAG_LABELMBUFS	0x00000004
 
 /* Flags for the mpc_runtime_flags field. */
 #define	MPC_RUNTIME_FLAG_REGISTERED	0x00000001

==== //depot/projects/trustedbsd/mac/sys/sys/mbuf.h#27 (text+ko) ====

@@ -37,7 +37,6 @@
 #ifndef _SYS_MBUF_H_
 #define	_SYS_MBUF_H_
 
-#include <sys/_label.h>
 #include <sys/queue.h>
 
 /*
@@ -98,7 +97,6 @@
 	int	csum_flags;		/* flags regarding checksum */
 	int	csum_data;		/* data field used by csum routines */
 	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
-	struct	label label;		/* MAC label of data in packet */
 };
 
 /*
@@ -527,6 +525,7 @@
 #define	PACKET_TAG_IPFW				16 /* ipfw classification */
 #define	PACKET_TAG_DIVERT			17 /* divert info */
 #define	PACKET_TAG_IPFORWARD			18 /* ipforward info */
+#define	PACKET_TAG_MACLABEL			19 /* MAC label */
 
 /* Packet tag routines */
 struct	m_tag 	*m_tag_alloc(u_int32_t, int, int, int);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304101707.h3AH7HB8093395>