Date: Mon, 22 Jan 2007 15:17:28 GMT From: Todd Miller <millert@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 113320 for review Message-ID: <200701221517.l0MFHSHR003988@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=113320 Change 113320 by millert@millert_macbook on 2007/01/22 15:17:03 Add ifnet label support. Also add the ifnet label as an argument to mpo_mbuf_label_associate_ifnet like FreeBSD. Note that some network pseudo-devices (faith, gif, lo, stf) do not use dlil for allocation so we have to call mac_ifnet_label_init() directly for those. Affected files ... .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/dlil.c#6 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if.c#3 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_faith.c#3 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_gif.c#3 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_loop.c#3 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_stf.c#2 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_var.h#3 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/sockio.h#3 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#28 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_net.c#7 edit .. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#36 edit .. //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#26 edit .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#59 edit .. //depot/projects/trustedbsd/sedarwin8/policies/test/mac_test.c#19 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/dlil.c#6 (text+ko) ==== @@ -1093,7 +1093,13 @@ } do { - +#ifdef MAC + retval = mac_ifnet_check_transmit(ifp, m); + if (retval) { + m_freem(m); + goto cleanup; + } +#endif if (ifp->if_framer) { retval = ifp->if_framer(ifp, &m, dest, dst_linkaddr, frame_type); @@ -1219,6 +1225,14 @@ goto cleanup; } } + +#ifdef MAC + retval = mac_ifnet_check_transmit(ifp, m); + if (retval) { + m_freem(m); + goto cleanup; + } +#endif /* * Call framing module @@ -2384,6 +2398,9 @@ ifa->ifa_debug |= IFA_ATTACHED; TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); } +#ifdef MAC + mac_ifnet_label_associate(ifp); +#endif TAILQ_INSERT_TAIL(&ifnet_head, ifp, if_link); ifindex2ifnet[ifp->if_index] = ifp; @@ -2758,6 +2775,9 @@ ifp1 = (struct ifnet *)dlifp1; ifp1->if_eflags |= IFEF_INUSE; ifp1->if_name = dlifp1->if_namestorage; +#ifdef MAC + mac_ifnet_label_init(ifp1); +#endif TAILQ_INSERT_TAIL(&dlil_ifnet_head, dlifp1, dl_if_link); @@ -2785,6 +2805,15 @@ strncpy(dlifp->if_namestorage, ifp->if_name, IFNAMSIZ); ifp->if_name = dlifp->if_namestorage; +#ifdef MAC + /* + * We can either recycle the MAC label here or in dlil_if_acquire(). + * It seems logical to do it here but this means that anything that + * still has a handle on ifp will now see it as unlabeled. + * Since the interface is "dead" that may be OK. Revisit later. + */ + mac_ifnet_label_recycle(ifp); +#endif if (ifp->if_lock) ifnet_lock_done(ifp); ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if.c#3 (text+ko) ==== @@ -104,6 +104,10 @@ #endif #endif +#ifdef MAC +#include <security/mac_framework.h> +#endif + /* * System initialization */ @@ -1086,6 +1090,13 @@ ifnet_lock_done(ifp); break; +#ifdef MAC + case SIOCGIFMAC: + error = mac_ifnet_label_get(proc_ucred(p), ifr, ifp); + if (error) + return (error); + break; +#endif case SIOCGIFMETRIC: ifnet_lock_shared(ifp); ifr->ifr_metric = ifp->if_metric; @@ -1131,6 +1142,13 @@ ifnet_touch_lastchange(ifp); break; +#ifdef MAC + case SIOCSIFMAC: + error = mac_ifnet_label_set(proc_ucred(p), ifr, ifp); + if (error) + return (error); + break; +#endif case SIOCSIFMETRIC: error = proc_suser(p); if (error) ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_faith.c#3 (text+ko) ==== @@ -274,6 +274,9 @@ ifp->if_type = IFT_FAITH; ifp->if_hdrlen = 0; ifp->if_addrlen = 0; +#ifdef MAC + mac_ifnet_label_init(ifp); +#endif dlil_if_attach(ifp); #if NBPFILTER > 0 #ifdef HAVE_OLD_BPF ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_gif.c#3 (text+ko) ==== @@ -325,6 +325,9 @@ sc->gif_if.if_type = IFT_GIF; sc->gif_if.if_add_proto = gif_add_proto; sc->gif_if.if_del_proto = gif_del_proto; +#ifdef MAC + mac_ifnet_label_init(&sc->gif_if); +#endif dlil_if_attach(&sc->gif_if); bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int)); TAILQ_INSERT_TAIL(&gifs, sc, gif_link); ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_loop.c#3 (text+ko) ==== @@ -472,6 +472,9 @@ ifp->if_type = IFT_LOOP; ifp->if_hwassist = IF_HWASSIST_CSUM_IP | IF_HWASSIST_CSUM_TCP | IF_HWASSIST_CSUM_UDP; ifp->if_hdrlen = sizeof(struct loopback_header); +#ifdef MAC + mac_ifnet_label_init(ifp); +#endif lo_ifp = ifp; dlil_if_attach(ifp); #if NBPFILTER > 0 ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_stf.c#2 (text+ko) ==== @@ -270,6 +270,9 @@ sc->sc_if.if_flags |= IFF_LINK2; #endif sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; +#ifdef MAC + mac_ifnet_label_init(&sc->sc_if); +#endif if (error = dlil_if_attach(&sc->sc_if)) printf("stfattach: can't dlil_if_attach error=%d\n"); @@ -635,6 +638,10 @@ ifp = &sc->sc_if; +#ifdef MAC + mac_mbuf_label_associate_ifnet(ifp, m); +#endif + /* * perform sanity check against outer src/dst. * for source, perform ingress filter as well. ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/net/if_var.h#3 (text+ko) ==== @@ -439,6 +439,7 @@ u_char *ptr; } u; } if_broadcast; + struct label *if_label; /* interface MAC label */ }; #define if_add_proto if_add_proto_u.original ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/sockio.h#3 (text+ko) ==== @@ -179,4 +179,7 @@ #define SIOCSETOT _IOW('s', 128, int) /* set socket for LibOT */ #endif /* PRIVATE */ +#define SIOCGIFMAC _IOWR('i', 130, struct ifreq) /* get IF MAC label */ +#define SIOCSIFMAC _IOW('i', 131, struct ifreq) /* set IF MAC label */ + #endif /* !_SYS_SOCKIO_H_ */ ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#28 (text+ko) ==== @@ -60,6 +60,7 @@ struct fdescnode; struct fileglob; struct ifnet; +struct ifreq; struct lctx; struct mac; struct mac_module_data; @@ -146,6 +147,15 @@ void mac_file_label_associate(struct ucred *cred, struct fileglob *fg); void mac_file_label_destroy(struct fileglob *fg); void mac_file_label_init(struct fileglob *fg); +int mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *mbuf); +void mac_ifnet_label_associate(struct ifnet *ifp); +void mac_ifnet_label_destroy(struct ifnet *ifp); +int mac_ifnet_label_get(struct ucred *cred, struct ifreq *ifr, + struct ifnet *ifp); +void mac_ifnet_label_init(struct ifnet *ifp); +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); struct label *mac_lctx_label_alloc(void); ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_net.c#7 (text+ko) ==== @@ -2,6 +2,7 @@ * Copyright (c) 1999-2002 Robert N. M. Watson * Copyright (c) 2001 Ilmar S. Habibulin * Copyright (c) 2001-2004 Networks Associates Technology, Inc. + * Copyright (c) 2006 SPARTA, Inc. * All rights reserved. * * This software was developed by Robert Watson and Ilmar Habibulin for the @@ -38,6 +39,11 @@ #include <sys/kernel.h> #include <sys/mbuf.h> +#include <net/if.h> + +#include <bsd/bsm/audit.h> +#include <bsd/bsm/audit_kernel.h> + #include <security/mac_internal.h> int mac_label_mbufs = 1; /* Exported via sysctl in mac_base.c */ @@ -67,6 +73,23 @@ return (label); } +static struct label * +mac_ifnet_label_alloc(void) +{ + struct label *label; + + label = mac_labelzone_alloc(M_WAITOK); + MAC_PERFORM(ifnet_label_init, label); + return (label); +} + +void +mac_ifnet_label_init(struct ifnet *ifp) +{ + + ifp->if_label = mac_ifnet_label_alloc(); +} + /* * On failure, caller should cleanup with m_tag_free(). */ @@ -86,7 +109,30 @@ return (error); } +static void +mac_ifnet_label_free(struct label *label) +{ + + MAC_PERFORM(ifnet_label_destroy, label); + mac_labelzone_free(label); +} + +void +mac_ifnet_label_destroy(struct ifnet *ifp) +{ + + mac_ifnet_label_free(ifp->if_label); + ifp->if_label = NULL; +} + void +mac_ifnet_label_recycle(struct ifnet *ifp) +{ + + MAC_PERFORM(ifnet_label_recycle, ifp->if_label); +} + +void mac_mbuf_tag_destroy(struct m_tag *tag) { struct label *label; @@ -132,6 +178,41 @@ MAC_PERFORM(mbuf_label_copy, src_label, dest_label); } +static void +mac_ifnet_label_copy(struct label *src, struct label *dest) +{ + + MAC_PERFORM(ifnet_label_copy, src, dest); +} + +static int +mac_ifnet_label_externalize(struct label *label, char *elements, + char *outbuf, size_t outbuflen) +{ + int error; + + error = MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen); + + return (error); +} + +static int +mac_ifnet_label_internalize(struct label *label, char *string) +{ + int error; + + error = MAC_INTERNALIZE(ifnet, label, string); + + return (error); +} + +void +mac_ifnet_label_associate(struct ifnet *ifp) +{ + + MAC_PERFORM(ifnet_label_associate, ifp, ifp->if_label); +} + int mac_mbuf_label_init(struct mbuf *m, int flag) { @@ -171,16 +252,17 @@ } void -mac_mbuf_label_associate_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) +mac_mbuf_label_associate_ifnet(struct ifnet *ifp, struct mbuf *mbuf) { - struct label *label; + struct label *m_label; - /* ifnet must be locked */ + /* ifp must be locked */ - label = mac_mbuf_to_label(mbuf); + m_label = mac_mbuf_to_label(mbuf); /* Policy must deal with NULL label (unlabeled mbufs) */ - MAC_PERFORM(mbuf_label_associate_ifnet, ifnet, mbuf, label); + MAC_PERFORM(mbuf_label_associate_ifnet, ifp, ifp->if_label, mbuf, + m_label); } void @@ -192,9 +274,133 @@ /* socket must be locked */ label = mac_mbuf_to_label(mbuf); - + /* Policy must deal with NULL label (unlabeled mbufs) */ sotoxsocket(socket, &xso); MAC_PERFORM(mbuf_label_associate_socket, &xso, socket->so_label, mbuf, label); } + +int +mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *mbuf) +{ + struct label *label; + int error; + + label = mac_mbuf_to_label(mbuf); + + ifnet_lock_shared(ifp); + MAC_CHECK(ifnet_check_transmit, ifp, ifp->if_label, mbuf, label); + ifnet_lock_done(ifp); + + return (error); +} + +int +mac_ifnet_label_get(__unused struct ucred *cred, struct ifreq *ifr, + struct ifnet *ifp) +{ + char *elements, *buffer; + struct label *intlabel; + struct mac mac; + int error; + size_t len; + + error = copyin(CAST_USER_ADDR_T(ifr->ifr_ifru.ifru_data), + &mac, sizeof(mac)); + if (error) + return (error); + + error = mac_check_structmac_consistent(&mac); + if (error) + return (error); + + MALLOC(elements, char *, mac.m_buflen, M_MACTEMP, M_WAITOK); + error = copyinstr(CAST_USER_ADDR_T(mac.m_string), elements, + mac.m_buflen, &len); + if (error) { + FREE(elements, M_MACTEMP); + return (error); + } + AUDIT_ARG(mac_string, elements); + + MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); + intlabel = mac_ifnet_label_alloc(); + ifnet_lock_shared(ifp); + mac_ifnet_label_copy(ifp->if_label, intlabel); + ifnet_lock_done(ifp); + error = mac_ifnet_label_externalize(intlabel, elements, + buffer, mac.m_buflen); + mac_ifnet_label_free(intlabel); + FREE(elements, M_MACTEMP); + + if (error == 0) + error = copyout(buffer, CAST_USER_ADDR_T(mac.m_string), + strlen(buffer) + 1); + FREE(buffer, M_MACTEMP); + + return (error); +} + +int +mac_ifnet_label_set(struct ucred *cred, struct ifreq *ifr, + struct ifnet *ifp) +{ + struct label *intlabel; + struct mac mac; + char *buffer; + int error; + size_t len; + + error = copyin(CAST_USER_ADDR_T(ifr->ifr_ifru.ifru_data), + &mac, sizeof(mac)); + if (error) + return (error); + + error = mac_check_structmac_consistent(&mac); + if (error) + return (error); + + MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK); + error = copyinstr(CAST_USER_ADDR_T(mac.m_string), buffer, + mac.m_buflen, &len); + if (error) { + FREE(buffer, M_MACTEMP); + return (error); + } + AUDIT_ARG(mac_string, buffer); + + intlabel = mac_ifnet_label_alloc(); + error = mac_ifnet_label_internalize(intlabel, buffer); + FREE(buffer, M_MACTEMP); + if (error) { + mac_ifnet_label_free(intlabel); + return (error); + } + + /* + * XXX: Note that this is a redundant privilege check, since + * policies impose this check themselves if required by the + * policy. Eventually, this should go away. + */ + error = suser(cred, NULL); + if (error) { + mac_ifnet_label_free(intlabel); + return (error); + } + + ifnet_lock_exclusive(ifp); + MAC_CHECK(ifnet_check_label_update, cred, ifp, ifp->if_label, + intlabel); + if (error) { + ifnet_lock_done(ifp); + mac_ifnet_label_free(intlabel); + return (error); + } + + MAC_PERFORM(ifnet_label_update, cred, ifp, ifp->if_label, intlabel); + ifnet_lock_done(ifp); + mac_ifnet_label_free(intlabel); + + return (0); +} ==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#36 (text+ko) ==== @@ -61,7 +61,6 @@ struct devnode; struct fileglob; struct ifnet; -struct ipq; struct label; struct lctx; struct mac_module_data; @@ -814,6 +813,159 @@ struct label *label ); /** + @brief Access control check for relabeling network interfaces + @param cred Subject credential + @param ifp network interface being relabeled + @param ifnetlabel Current label of the network interfaces + @param newlabel New label to apply to the network interfaces + @see mpo_ifnet_label_update_t + + Determine whether the subject identified by the credential can + relabel the network interface represented by ifp to the supplied + new label (newlabel). + + @return Return 0 if access is granted, otherwise an appropriate value for + errno should be returned. +*/ +typedef int mpo_ifnet_check_label_update_t( + struct ucred *cred, + struct ifnet *ifp, + struct label *ifnetlabel, + struct label *newlabel +); +/** + @brief Access control check for relabeling network interfaces + @param ifp Network interface mbuf will be transmitted through + @param ifnetlabel Label of the network interfaces + @param m The mbuf to be transmitted + @param mbuflabel Label of the mbuf to be transmitted + + Determine whether the mbuf with label mbuflabel may be transmitted + through the network interface represented by ifp that has the + label ifnetlabel. + + @return Return 0 if access is granted, otherwise an appropriate value for + errno should be returned. +*/ +typedef int mpo_ifnet_check_transmit_t( + struct ifnet *ifp, + struct label *ifnetlabel, + struct mbuf *m, + struct label *mbuflabel +); +/** + @brief Create a network interface label + @param ifp Network interface labeled + @param ifnetlabel Label for the network interface + + Set the label of a newly created network interface, most likely + using the information in the supplied network interface struct. +*/ +typedef void mpo_ifnet_label_associate_t( + struct ifnet *ifp, + struct label *ifnetlabel +); +/** + @brief Copy an ifnet label + @param src Source ifnet label + @param dest Destination ifnet label + + Copy the label information from src to dest. +*/ +typedef void mpo_ifnet_label_copy_t( + struct label *src, + struct label *dest +); +/** + @brief Destroy ifnet label + @param label The label to be destroyed +*/ +typedef void mpo_ifnet_label_destroy_t( + struct label *label +); +/** + @brief Externalize an ifnet label + @param label Label to be externalized + @param element_name Name of the label namespace for which labels should be + externalized + @param sb String buffer to be filled with a text representation of the label + + Produce an external representation of the label on an interface. + An externalized label consists of a text representation of the + label contents that can be used with user applications. + Policy-agnostic user space tools will display this externalized + version. + + @return 0 on success, return non-zero if an error occurs while + externalizing the label data. + +*/ +typedef int mpo_ifnet_label_externalize_t( + struct label *label, + char *element_name, + struct sbuf *sb +); +/** + @brief Initialize ifnet label + @param label New label to initialize +*/ +typedef void mpo_ifnet_label_init_t( + struct label *label +); +/** + @brief Internalize an interface label + @param label Label to be internalized + @param element_name Name of the label namespace for which the label should + be internalized + @param element_data Text data to be internalized + + Produce an interface label from an external representation. An + externalized label consists of a text representation of the label + contents that can be used with user applications. Policy-agnostic + user space tools will forward text version to the kernel for + processing by individual policy modules. + + The policy's internalize entry points will be called only if the + policy has registered interest in the label namespace. + + @return 0 on success, Otherwise, return non-zero if an error occurs + while internalizing the label data. + +*/ +typedef int mpo_ifnet_label_internalize_t( + struct label *label, + char *element_name, + char *element_data +); +/** + @brief Recycle up a network interface label + @param label The label to be recycled + + Recycle a network interface label. Darwin caches the struct ifnet + of detached ifnets in a "free pool". Before ifnets are returned + to the "free pool", policies can cleanup or overwrite any information + present in the label. +*/ +typedef void mpo_ifnet_label_recycle_t( + struct label *label +); +/** + @brief Update a network interface label + @param cred Subject credential + @param ifp The network interface to be relabeled + @param ifnetlabel The current label of the network interface + @param newlabel A new label to apply to the network interface + @see mpo_ifnet_check_label_update_t + + Update the label on a network interface, using the supplied new label. +*/ +typedef void mpo_ifnet_label_update_t( + struct ucred *cred, + struct ifnet *ifp, + struct label *ifnetlabel, + struct label *newlabel +); +/** @brief Device hardware access control @param devtype Type of device connected @param properties XML-formatted property list @@ -990,7 +1142,7 @@ ); /** @brief Assign a label to a new mbuf - @param ifnet Interface descriptor + @param ifp Interface descriptor @param m Object; mbuf @param m_label Policy label to fill in for m @@ -998,6 +1150,7 @@ */ typedef void mpo_mbuf_label_associate_ifnet_t( struct ifnet *ifp, + struct label *i_label, struct mbuf *m, struct label *m_label ); @@ -5025,6 +5178,16 @@ mpo_file_label_init_t *mpo_file_label_init; mpo_file_label_destroy_t *mpo_file_label_destroy; mpo_file_label_associate_t *mpo_file_label_associate; + mpo_ifnet_check_label_update_t *mpo_ifnet_check_label_update; + mpo_ifnet_check_transmit_t *mpo_ifnet_check_transmit; + mpo_ifnet_label_associate_t *mpo_ifnet_label_associate; + mpo_ifnet_label_copy_t *mpo_ifnet_label_copy; + mpo_ifnet_label_destroy_t *mpo_ifnet_label_destroy; + mpo_ifnet_label_externalize_t *mpo_ifnet_label_externalize; + mpo_ifnet_label_init_t *mpo_ifnet_label_init; + 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_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; ==== //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#26 (text+ko) ==== @@ -1543,16 +1543,17 @@ static void mac_mls_mbuf_label_associate_ifnet(struct ifnet *ifnet, - struct mbuf *mbuf, struct label *mbuflabel) + struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel) { - struct mac_mls *dest; + struct mac_mls *source, *dest; - if (mbuflabel == NULL) + if (ifnetlabel == NULL || mbuflabel == NULL) return; + source = SLOT(ifnetlabel); dest = SLOT(mbuflabel); - mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); + mac_mls_copy_effective(source, dest); } static void ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#59 (text+ko) ==== @@ -919,6 +919,7 @@ network_label_copy(blabel, mlabel); } +#endif static void sebsd_mbuf_label_associate_ifnet(struct ifnet *ifn, struct label *ilabel, @@ -927,7 +928,6 @@ network_label_copy(ilabel, mlabel); } -#endif static void sebsd_posixsem_label_associate(struct ucred *cred, struct pseminfo *psem, @@ -1800,7 +1800,7 @@ struct label *oldlabel, struct label *newlabel) { - network_label_copy(oldlabel, newlabel); + network_label_copy(newlabel, oldlabel); } static void @@ -3023,7 +3023,86 @@ return (file_has_perm(cred, fg, fglabel, 0)); } +static void +sebsd_ifnet_label_update(struct ucred *cred, struct ifnet *ifp, + struct label *ifnetlabel, struct label *newlabel) +{ + + network_label_copy(newlabel, ifnetlabel); +} + +static void +sebsd_ifnet_label_associate(struct ifnet *ifp, struct label *ifnetlabel) +{ + struct network_security_struct *nsec; + + /* + * We just set the label to a default value and require that + * the system set a more specific value at ifconfig time. + */ + nsec = SLOT(ifnetlabel); + if (nsec != NULL) { + nsec->sid = SECINITSID_NETIF; + nsec->sclass = SECCLASS_NETIF; + } +} + +#if 0 +static int +sebsd_ifnet_check_label_update(struct ucred *cred, struct ifnet *ifp, + struct label *ifnetlabel, struct label *newlabel) +{ + struct network_security_struct *nsec, *tsec; + int rc; + + nsec = SLOT(newlabel); + tsec = SLOT(socklabel); + + if (nsec == NULL) + return (0); + + /* XXX - no NETIF__RELABEL{TO,FROM} */ + rc = avc_has_perm(tsec->sid, tsec->sid, SECCLASS_NETIF, + SOCKET__RELABELFROM, NULL); + if (rc) + return (rc); + + rc = avc_has_perm(tsec->sid, nsec->sid, SECCLASS_NETIF, + SOCKET__RELABELTO, NULL); + if (rc) + return (rc); + + return (0); +} +#endif + static int +sebsd_ifnet_check_transmit(struct ifnet *ifp, + struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel) +{ + struct network_security_struct *ifsec, *msec; + int error; + + if (ifnetlabel == NULL || mbuflabel == NULL) { + /* XXX - mbufs are not always labelled! */ + return (0); + } + + ifsec = SLOT(ifnetlabel); + msec = SLOT(mbuflabel); + + if (ifsec == NULL || msec == NULL) { + /* XXX - should not happen, log and fix */ + return (0); + } + + /* XXX - use an audit struct so we can log useful info */ + error = avc_has_perm(msec->sid, ifsec->sid, SECCLASS_PACKET, + PACKET__SEND, NULL); + return (error); +} + +static int ipc_has_perm(struct ucred *cred, struct label *label, u_int32_t perm) { struct task_security_struct *task; @@ -3396,6 +3475,17 @@ .mpo_file_label_associate = sebsd_file_label_associate, .mpo_file_label_destroy = sebsd_label_destroy, .mpo_file_label_init = sebsd_label_init, + //.mpo_ifnet_check_label_update = XXX, + .mpo_ifnet_check_transmit = sebsd_ifnet_check_transmit, + .mpo_ifnet_label_associate = sebsd_ifnet_label_associate, + .mpo_ifnet_label_copy = sebsd_label_copy, + .mpo_ifnet_label_destroy = sebsd_label_destroy, + .mpo_ifnet_label_externalize = sebsd_label_externalize, + .mpo_ifnet_label_init = sebsd_label_init, + .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_ifnet = sebsd_mbuf_label_associate_ifnet, .mpo_mbuf_label_associate_socket = sebsd_mbuf_label_associate_socket, .mpo_mbuf_label_copy = network_label_copy, .mpo_mbuf_label_destroy = sebsd_label_destroy, ==== //depot/projects/trustedbsd/sedarwin8/policies/test/mac_test.c#19 (text+ko) ==== @@ -1637,12 +1637,14 @@ } static void -mac_test_mbuf_label_associate_ifnet(struct ifnet *ifnet, +mac_test_mbuf_label_associate_ifnet(struct ifnet *ifnet, struct label *i_label, struct mbuf *m, struct label *m_label) { CHECKNULL(ifnet); CHECKNULL(m); + if (i_label != NULL) + INIT_LABEL(i_label, SOCKETTYPE); if (m_label != NULL) INIT_LABEL(m_label, SOCKETTYPE); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701221517.l0MFHSHR003988>