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