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