From owner-p4-projects@FreeBSD.ORG Mon Jan 22 15:18:36 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DBF0016A401; Mon, 22 Jan 2007 15:18:35 +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 A211A16A404 for ; Mon, 22 Jan 2007 15:18:35 +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 90DB213C45B for ; Mon, 22 Jan 2007 15:18:35 +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 l0MFIZrg004188 for ; Mon, 22 Jan 2007 15:18:35 GMT (envelope-from millert@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l0MFIZ2G004185 for perforce@freebsd.org; Mon, 22 Jan 2007 15:18:35 GMT (envelope-from millert@freebsd.org) Date: Mon, 22 Jan 2007 15:18:35 GMT Message-Id: <200701221518.l0MFIZ2G004185@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 113321 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jan 2007 15:18:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=113321 Change 113321 by millert@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 #include +#include #include #include @@ -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,