PERFORCE change 113321 for review

Todd Miller millert at FreeBSD.org
Mon Jan 22 15:18:57 UTC 2007


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

Change 113321 by millert at millert_macbook on 2007/01/22 15:18:10

	Add support for labeling BPF descriptors.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/bpf.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/bpf.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/bpfdesc.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#29 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_net.c#8 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#37 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#60 edit

Differences ...

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

@@ -525,7 +525,7 @@
  */
 /* ARGSUSED */
 	int
-bpfopen(dev_t dev, __unused int flags, __unused int fmt, __unused struct proc *p)
+bpfopen(dev_t dev, __unused int flags, __unused int fmt, struct proc *p)
 {
 	register struct bpf_d *d;
 
@@ -575,6 +575,10 @@
 	d->bd_bufsize = bpf_bufsize;
 	d->bd_sig = SIGIO;
 	d->bd_seesent = 1;
+#ifdef MAC
+	mac_bpfdesc_label_init(d);
+	mac_bpfdesc_label_associate(proc_ucred(p), d);
+#endif
 	bpf_dtab[minor(dev)] = d; 				/* Mark opened */
 
 	return (0);
@@ -602,6 +606,9 @@
 	if (d->bd_bif)
 		bpf_detachd(d);
 	selthreadclear(&d->bd_sel);
+#ifdef MAC
+	mac_bpfdesc_label_destroy(d);
+#endif
 	bpf_freed(d);
 
 	lck_mtx_unlock(bpf_mlock);
@@ -1334,8 +1341,13 @@
 		for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
 			++d->bd_rcount;
 			slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
-			if (slen != 0)
+			if (slen != 0) {
+#ifdef MAC
+				if (mac_bpfdesc_check_receive(d, bp->bif_ifp) != 0)
+					continue;
+#endif
 				catchpacket(d, pkt, pktlen, slen, bcopy);
+			}
 		}
 #ifdef __APPLE__
     }
@@ -1391,8 +1403,13 @@
 				continue;
 			++d->bd_rcount;
 			slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
-			if (slen != 0)
+			if (slen != 0) {
+#ifdef MAC
+				if (mac_bpfdesc_check_receive(d, bp->bif_ifp) != 0)
+					continue;
+#endif
 				catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
+			}
 		}
 	}
 	
@@ -1679,6 +1696,22 @@
 SYSINIT(bpfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bpf_drvinit,NULL)
 #endif
 
+#ifdef MAC
+struct label *
+mac_bpfdesc_label_get(struct bpf_d *d)
+{
+
+	return (d->bd_label);
+}
+
+void
+mac_bpfdesc_label_set(struct bpf_d *d, struct label *label)
+{
+
+	d->bd_label = label;
+}
+#endif
+
 #else /* !BPF */
 #ifndef __APPLE__
 /*

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

@@ -399,6 +399,13 @@
 	@param header_length The length, in bytes, of the data link header.
  */
 void	 bpfattach(ifnet_t interface, u_int data_link_type, u_int header_length);
+
+#ifdef MAC
+struct label;
+struct bpf_d;
+struct label *mac_bpfdesc_label_get(struct bpf_d *d);
+void mac_bpfdesc_label_set(struct bpf_d *d, struct label *label);
+#endif
 #endif /* KERNEL */
 
 /*

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

@@ -128,7 +128,7 @@
 #endif
 	int		bd_hdrcmplt;	/* false to fill in src lladdr automatically */
 	int		bd_seesent;	/* true if bpf should see sent packets */
-
+	struct label *	bd_label;	/* MAC label for descriptor */
 };
 
 /*

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

@@ -95,6 +95,10 @@
 	    void *args, int error, int retval, int mac_forced);
 int	mac_audit_check_preselect(struct ucred *cred, unsigned short syscode,
 	    void *args);
+int	mac_bpfdesc_check_receive(struct bpf_d *bpf_d, struct ifnet *ifp);
+void	mac_bpfdesc_label_destroy(struct bpf_d *bpf_d);
+void	mac_bpfdesc_label_init(struct bpf_d *bpf_d);
+void	mac_bpfdesc_label_associate(struct ucred *cred, struct bpf_d *bpf_d);
 int	mac_cred_check_label_update(struct ucred *cred,
 	    struct label *newlabel);
 int	mac_cred_check_label_update_execve(struct ucred *old,

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

@@ -39,6 +39,7 @@
 #include <sys/kernel.h>
 #include <sys/mbuf.h>
 
+#include <net/bpf.h>
 #include <net/if.h>
 
 #include <bsd/bsm/audit.h>
@@ -74,6 +75,25 @@
 }
 
 static struct label *
+mac_bpfdesc_label_alloc(void)
+{
+	struct label *label;
+
+	label = mac_labelzone_alloc(M_WAITOK);
+	MAC_PERFORM(bpfdesc_label_init, label);
+	return (label);
+}
+
+void
+mac_bpfdesc_label_init(struct bpf_d *bpf_d)
+{
+	struct label *label;
+
+	label = mac_bpfdesc_label_alloc();
+	mac_bpfdesc_label_set(bpf_d, label);
+}
+
+static struct label *
 mac_ifnet_label_alloc(void)
 {
 	struct label *label;
@@ -110,6 +130,24 @@
 }
 
 static void
+mac_bpfdesc_label_free(struct label *label)
+{
+
+	MAC_PERFORM(bpfdesc_label_destroy, label);
+	mac_labelzone_free(label);
+}
+
+void
+mac_bpfdesc_label_destroy(struct bpf_d *bpf_d)
+{
+	struct label *label;
+
+	label = mac_bpfdesc_label_get(bpf_d);
+	mac_bpfdesc_label_free(label);
+	mac_bpfdesc_label_set(bpf_d, NULL);
+}
+
+static void
 mac_ifnet_label_free(struct label *label)
 {
 
@@ -213,7 +251,31 @@
 	MAC_PERFORM(ifnet_label_associate, ifp, ifp->if_label);
 }
 
+void
+mac_bpfdesc_label_associate(struct ucred *cred, struct bpf_d *bpf_d)
+{
+	struct label *label;
+
+	label = mac_bpfdesc_label_get(bpf_d);
+	MAC_PERFORM(bpfdesc_label_associate, cred, bpf_d, label);
+}
+
 int
+mac_bpfdesc_check_receive(struct bpf_d *bpf_d, struct ifnet *ifp)
+{
+	struct label *label;
+	int error;
+
+	label = mac_bpfdesc_label_get(bpf_d);
+	ifnet_lock_shared(ifp);
+	MAC_CHECK(bpfdesc_check_receive, bpf_d, label, ifp,
+	    ifp->if_label);
+	ifnet_lock_done(ifp);
+
+	return (error);
+}
+
+int
 mac_mbuf_label_init(struct mbuf *m, int flag)
 {
 	struct m_tag *tag;
@@ -241,14 +303,16 @@
 void
 mac_mbuf_label_associate_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
 {
-	struct label *label;
+	struct label *m_label, *b_label;
 
 	/* bpf_d must be locked */
 
-	label = mac_mbuf_to_label(mbuf);
+	m_label = mac_mbuf_to_label(mbuf);
+	b_label = mac_bpfdesc_label_get(bpf_d);
 
 	/* Policy must deal with NULL label (unlabeled mbufs) */
-	MAC_PERFORM(mbuf_label_associate_bpfdesc, bpf_d, mbuf, label);
+	MAC_PERFORM(mbuf_label_associate_bpfdesc, bpf_d, b_label, mbuf,
+	    m_label);
 }
 
 void

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

@@ -184,6 +184,61 @@
 	void *args
 );
 /**
+  @brief Initialize BPF descriptor label
+  @param label New label to initialize
+
+  Initialize the label for a newly instantiated BPF descriptor.
+  Sleeping is permitted.
+*/
+typedef void mpo_bpfdesc_label_init_t(
+	struct label *label
+);
+/**
+  @brief Destroy BPF descriptor label
+  @param label The label to be destroyed
+
+  Destroy a BPF descriptor label.  Since the BPF descriptor
+  is going out of scope, policy modules should free any internal
+  storage associated with the label so that it may be destroyed.
+*/
+typedef void mpo_bpfdesc_label_destroy_t(
+	struct label *label
+);
+/**
+  @brief Associate a BPF descriptor with a label
+  @param cred User credential creating the BPF descriptor
+  @param bpf_d The BPF descriptor
+  @param bpflabel The new label
+
+  Set the label on a newly created BPF descriptor from the passed
+  subject credential. This call will be made when a BPF device node
+  is opened by a process with the passed subject credential.
+*/
+typedef void mpo_bpfdesc_label_associate_t(
+	struct ucred *cred,
+	struct bpf_d *bpf_d,
+	struct label *bpflabel
+);
+/**
+  @brief Check whether BPF can read from a network interface
+  @param bpf_d Subject; the BPF descriptor
+  @param bpflabel Policy label for bpf_d 
+  @param ifp Object; the network interface 
+  @param ifnetlabel Policy label for ifp
+
+  Determine whether the MAC framework should permit datagrams from
+  the passed network interface to be delivered to the buffers of
+  the passed BPF descriptor.  Return (0) for success, or an errno
+  value for failure.  Suggested failure: EACCES for label mismatches,
+  EPERM for lack of privilege.
+*/
+typedef int mpo_bpfdesc_check_receive_t(
+	struct bpf_d *bpf_d,
+	struct label *bpflabel,
+	struct ifnet *ifp,
+	struct label *ifnetlabel
+);
+/**
   @brief Indicate desire to change the process label at exec time
   @param old Existing subject credential
   @param vp File being executed
@@ -1130,19 +1185,25 @@
 /**
  @brief Assign a label to a new mbuf
  @param bpf_d BPF descriptor
+ @param b_label Policy label for bpf_d
  @param m Object; mbuf
  @param m_label Policy label to fill in for m
 
- Label an mbuf based on the BPF descriptor from which it was received.
+ Set the label on the mbuf header of a newly created datagram
+ generated using the passed BPF descriptor. This call is made when
+ a write is performed to the BPF device associated with the passed
+ BPF descriptor.
 */
 typedef void mpo_mbuf_label_associate_bpfdesc_t(
 	struct bpf_d *bpf_d,
+	struct label *b_label,
 	struct mbuf *m,
 	struct label *m_label
 );
 /**
  @brief Assign a label to a new mbuf
  @param ifp Interface descriptor
+ @param i_label Existing label of ifp
  @param m Object; mbuf
  @param m_label Policy label to fill in for m
 
@@ -5143,6 +5204,10 @@
 struct mac_policy_ops {
 	mpo_audit_check_postselect_t		*mpo_audit_check_postselect;
 	mpo_audit_check_preselect_t		*mpo_audit_check_preselect;
+	mpo_bpfdesc_label_associate_t		*mpo_bpfdesc_label_associate;
+	mpo_bpfdesc_label_destroy_t		*mpo_bpfdesc_label_destroy;
+	mpo_bpfdesc_label_init_t		*mpo_bpfdesc_label_init;
+	mpo_bpfdesc_check_receive_t		*mpo_bpfdesc_check_receive;
 	mpo_cred_check_label_update_execve_t	*mpo_cred_check_label_update_execve;
 	mpo_cred_check_label_update_t		*mpo_cred_check_label_update;
 	mpo_cred_check_visible_t		*mpo_cred_check_visible;

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

@@ -910,8 +910,21 @@
 	psec->sclass = SECCLASS_MACH_PORT;
 }
 
-/* XXX - the Darwin framework lacks ifnet and bpf labels */
-#if 0
+static void
+sebsd_bpfdesc_label_associate(struct ucred *cred, struct bpf_d *bpf_d,
+    struct label *bpflabel)
+{
+	struct task_security_struct *tsec;
+	struct network_security_struct *nsec;
+
+	nsec = SLOT(bpflabel);
+	tsec = SLOT(cred->cr_label);
+
+	nsec->sid = tsec->sid;
+	nsec->task_sid = tsec->sid;
+	nsec->sclass = SECCLASS_PACKET; /* XXX - probably want a bpf class */
+}
+
 static void
 sebsd_mbuf_label_associate_bpfdesc(struct bpf_d *b, struct label *blabel,
     struct mbuf *m, struct label *mlabel)
@@ -919,7 +932,6 @@
 
 	network_label_copy(blabel, mlabel);
 }
-#endif
 
 static void
 sebsd_mbuf_label_associate_ifnet(struct ifnet *ifn, struct label *ilabel,
@@ -1845,8 +1857,9 @@
 }
 
 static void
-sebsd_socketpeer_label_associate_socket(struct xsocket *olds, struct label *oldslabel,
-    struct xsocket *news, struct label *newsockpeerlabel)
+sebsd_socketpeer_label_associate_socket(struct xsocket *olds,
+    struct label *oldslabel, struct xsocket *news,
+    struct label *newsockpeerlabel)
 {
 
 	network_label_copy(oldslabel, newsockpeerlabel);
@@ -3084,7 +3097,7 @@
 	int error;
 
 	if (ifnetlabel == NULL || mbuflabel == NULL) {
-		/* XXX - mbufs are not always labelled! */
+		/* XXX - mbufs are not always labeled! */
 		return (0);
 	}
 
@@ -3445,7 +3458,10 @@
 }
 
 static struct mac_policy_ops sebsd_ops = {
-	.mpo_cred_check_label_update =sebsd_cred_check_label_update,
+	.mpo_bpfdesc_label_associate = sebsd_bpfdesc_label_associate,
+	.mpo_bpfdesc_label_destroy = sebsd_label_destroy,
+	.mpo_bpfdesc_label_init = sebsd_label_init,
+	.mpo_cred_check_label_update = sebsd_cred_check_label_update,
 	.mpo_cred_check_label_update_execve = sebsd_cred_check_label_update_execve,
 	.mpo_cred_label_associate = sebsd_cred_label_associate,
 	.mpo_cred_label_associate_kernel = sebsd_cred_label_associate_kproc,
@@ -3485,6 +3501,7 @@
 	.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_bpfdesc = sebsd_mbuf_label_associate_bpfdesc,
 	.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,


More information about the trustedbsd-cvs mailing list