From owner-trustedbsd-cvs@FreeBSD.ORG Mon Jan 22 15:46:23 2007 Return-Path: X-Original-To: trustedbsd-cvs@freebsd.org Delivered-To: trustedbsd-cvs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 73EFB16A403 for ; Mon, 22 Jan 2007 15:46:23 +0000 (UTC) (envelope-from owner-perforce@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.freebsd.org (Postfix) with ESMTP id 7D92D13C457 for ; Mon, 22 Jan 2007 15:46:13 +0000 (UTC) (envelope-from owner-perforce@freebsd.org) Received: from mx2.freebsd.org (mx2.freebsd.org [69.147.83.53]) by cyrus.watson.org (Postfix) with ESMTP id 59D534A1E6 for ; Mon, 22 Jan 2007 10:46:10 -0500 (EST) Received: from hub.freebsd.org (hub.freebsd.org [69.147.83.54]) by mx2.freebsd.org (Postfix) with ESMTP id CD4F792DA7; Mon, 22 Jan 2007 15:45:31 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: by hub.freebsd.org (Postfix, from userid 32767) id 5902B16A537; Mon, 22 Jan 2007 15:45:25 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id DD14816A476 for ; Mon, 22 Jan 2007 15:45:24 +0000 (UTC) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 40E2213C467 for ; Mon, 22 Jan 2007 15:45:14 +0000 (UTC) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l0MFjEKt022237 for ; Mon, 22 Jan 2007 15:45:14 GMT (envelope-from millert@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l0MFjDUi022234 for perforce@freebsd.org; Mon, 22 Jan 2007 15:45:13 GMT (envelope-from millert@freebsd.org) Date: Mon, 22 Jan 2007 15:45:13 GMT Message-Id: <200701221545.l0MFjDUi022234@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to millert@freebsd.org using -f From: Todd Miller To: Perforce Change Reviews Cc: Subject: PERFORCE change 113332 for review X-BeenThere: trustedbsd-cvs@FreeBSD.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: TrustedBSD CVS and Perforce commit message list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jan 2007 15:46:23 -0000 http://perforce.freebsd.org/chv.cgi?CH=113332 Change 113332 by millert@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 /* 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,