X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/316670eb35587141e969394ae8537d66b9211e80..c3c9b80d004dbbfdf763edeb97968c6997e3b45b:/security/mac_socket.c diff --git a/security/mac_socket.c b/security/mac_socket.c index 32acf01f5..45fce6951 100644 --- a/security/mac_socket.c +++ b/security/mac_socket.c @@ -2,7 +2,7 @@ * Copyright (c) 2007-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /*- @@ -39,7 +39,7 @@ * Research, the Technology Research Division of Network Associates, Inc. * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the * DARPA CHATS research program. - * + * * This software was enhanced by SPARTA ISSO under SPAWAR contract * N66001-04-C-6019 ("SEFOS"). * @@ -84,412 +84,47 @@ #include -#if CONFIG_MACF_SOCKET -struct label * -mac_socket_label_alloc(int flag) -{ - struct label *label; - int error; - - label = mac_labelzone_alloc(flag); - if (label == NULL) - return (NULL); - - MAC_CHECK(socket_label_init, label, flag); - if (error) { - MAC_PERFORM(socket_label_destroy, label); - mac_labelzone_free(label); - return (NULL); - } - - return (label); -} - -static struct label * -mac_socket_peer_label_alloc(int flag) -{ - struct label *label; - int error; - - label = mac_labelzone_alloc(flag); - if (label == NULL) - return (NULL); - - MAC_CHECK(socketpeer_label_init, label, flag); - if (error) { - MAC_PERFORM(socketpeer_label_destroy, label); - mac_labelzone_free(label); - return (NULL); - } - - return (label); -} - -int -mac_socket_label_init(struct socket *so, int flag) -{ - - so->so_label = mac_socket_label_alloc(flag); - if (so->so_label == NULL) - return (ENOMEM); - so->so_peerlabel = mac_socket_peer_label_alloc(flag); - if (so->so_peerlabel == NULL) { - mac_socket_label_free(so->so_label); - so->so_label = NULL; - return (ENOMEM); - } - return (0); -} - -void -mac_socket_label_free(struct label *label) -{ - - MAC_PERFORM(socket_label_destroy, label); - mac_labelzone_free(label); -} - -static void -mac_socket_peer_label_free(struct label *label) -{ - - MAC_PERFORM(socketpeer_label_destroy, label); - mac_labelzone_free(label); -} - -void -mac_socket_label_destroy(struct socket *so) -{ - - if (so->so_label != NULL) { - mac_socket_label_free(so->so_label); - so->so_label = NULL; - } - if (so->so_peerlabel != NULL) { - mac_socket_peer_label_free(so->so_peerlabel); - so->so_peerlabel = NULL; - } -} - -void -mac_socket_label_copy(struct label *src, struct label *dest) -{ - - MAC_PERFORM(socket_label_copy, src, dest); -} - -int -mac_socket_label_externalize(struct label *label, char *elements, - char *outbuf, size_t outbuflen) -{ - int error; - - error = MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen); - - return (error); -} - -static int -mac_socketpeer_label_externalize(struct label *label, char *elements, - char *outbuf, size_t outbuflen) -{ - int error; - - error = MAC_EXTERNALIZE(socketpeer, label, elements, outbuf, outbuflen); - - return (error); -} - -int -mac_socket_label_internalize(struct label *label, char *string) -{ - int error; - - error = MAC_INTERNALIZE(socket, label, string); - - return (error); -} - -void -mac_socket_label_associate(struct ucred *cred, struct socket *so) -{ - if (!mac_socket_enforce) - return; - - MAC_PERFORM(socket_label_associate, cred, - (socket_t)so, so->so_label); -} - -void -mac_socket_label_associate_accept(struct socket *oldsocket, - struct socket *newsocket) -{ - if (!mac_socket_enforce) - return; - - MAC_PERFORM(socket_label_associate_accept, - (socket_t)oldsocket, oldsocket->so_label, - (socket_t)newsocket, newsocket->so_label); -} - -#if CONFIG_MACF_SOCKET && CONFIG_MACF_NET -void -mac_socketpeer_label_associate_mbuf(struct mbuf *mbuf, struct socket *so) -{ - struct label *label; - - if (!mac_socket_enforce && !mac_net_enforce) - return; - - label = mac_mbuf_to_label(mbuf); - - /* Policy must deal with NULL label (unlabeled mbufs) */ - MAC_PERFORM(socketpeer_label_associate_mbuf, mbuf, label, - (socket_t)so, so->so_peerlabel); -} -#else -void -mac_socketpeer_label_associate_mbuf(__unused struct mbuf *mbuf, - __unused struct socket *so) -{ - return; -} -#endif - -void -mac_socketpeer_label_associate_socket(struct socket *oldsocket, - struct socket *newsocket) -{ - if (!mac_socket_enforce) - return; - - MAC_PERFORM(socketpeer_label_associate_socket, - (socket_t)oldsocket, oldsocket->so_label, - (socket_t)newsocket, newsocket->so_peerlabel); -} - -int -mac_socket_check_kqfilter(kauth_cred_t cred, struct knote *kn, - struct socket *so) -{ - int error; - - if (!mac_socket_enforce) - return 0; - - MAC_CHECK(socket_check_kqfilter, cred, kn, - (socket_t)so, so->so_label); - return (error); -} - -static int -mac_socket_check_label_update(kauth_cred_t cred, struct socket *so, - struct label *newlabel) -{ - int error; - - if (!mac_socket_enforce) - return 0; - - MAC_CHECK(socket_check_label_update, cred, - (socket_t)so, so->so_label, - newlabel); - return (error); -} - -int -mac_socket_check_select(kauth_cred_t cred, struct socket *so, int which) -{ - int error; - - if (!mac_socket_enforce) - return 0; - - MAC_CHECK(socket_check_select, cred, - (socket_t)so, so->so_label, which); - return (error); -} - -int -mac_socket_check_stat(kauth_cred_t cred, struct socket *so) -{ - int error; - - if (!mac_socket_enforce) - return 0; - - MAC_CHECK(socket_check_stat, cred, - (socket_t)so, so->so_label); - return (error); -} - - -int -mac_socket_label_update(kauth_cred_t cred, struct socket *so, struct label *label) -{ - int error; -#if 0 - if (!mac_socket_enforce) - return; -#endif - error = mac_socket_check_label_update(cred, so, label); - if (error) - return (error); - - MAC_PERFORM(socket_label_update, cred, - (socket_t)so, so->so_label, label); - -#if CONFIG_MACF_NET - /* - * 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? - */ - mac_inpcb_label_update(so); -#endif - return (0); -} - -int -mac_setsockopt_label(kauth_cred_t cred, struct socket *so, struct mac *mac) -{ - struct label *intlabel; - char *buffer; - int error; - size_t len; - - 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); - } - - intlabel = mac_socket_label_alloc(MAC_WAITOK); - error = mac_socket_label_internalize(intlabel, buffer); - FREE(buffer, M_MACTEMP); - if (error) - goto out; - - error = mac_socket_label_update(cred, so, intlabel); -out: - mac_socket_label_free(intlabel); - return (error); -} - -int -mac_socket_label_get(__unused kauth_cred_t cred, struct socket *so, - struct mac *mac) -{ - char *buffer, *elements; - struct label *intlabel; - int error; - size_t len; - - 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); - } - - MALLOC(buffer, char *, mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - intlabel = mac_socket_label_alloc(MAC_WAITOK); - mac_socket_label_copy(so->so_label, intlabel); - error = mac_socket_label_externalize(intlabel, elements, buffer, - mac->m_buflen); - mac_socket_label_free(intlabel); - if (error == 0) - error = copyout(buffer, CAST_USER_ADDR_T(mac->m_string), - strlen(buffer)+1); - - FREE(buffer, M_MACTEMP); - FREE(elements, M_MACTEMP); - - return (error); -} - -int -mac_socketpeer_label_get(__unused kauth_cred_t cred, struct socket *so, - struct mac *mac) -{ - char *elements, *buffer; - struct label *intlabel; - int error; - size_t len; - - 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); - } - - MALLOC(buffer, char *, mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - intlabel = mac_socket_label_alloc(MAC_WAITOK); - mac_socket_label_copy(so->so_peerlabel, intlabel); - error = mac_socketpeer_label_externalize(intlabel, elements, buffer, - mac->m_buflen); - mac_socket_label_free(intlabel); - if (error == 0) - error = copyout(buffer, CAST_USER_ADDR_T(mac->m_string), - strlen(buffer)+1); - - FREE(buffer, M_MACTEMP); - FREE(elements, M_MACTEMP); - - return (error); -} -#endif /* MAC_SOCKET */ - int mac_socket_check_accept(kauth_cred_t cred, struct socket *so) { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_accept, cred, - (socket_t)so, so->so_label); - return (error); + (socket_t)so, so->so_label); + return error; } +#if CONFIG_MACF_SOCKET_SUBSET int mac_socket_check_accepted(kauth_cred_t cred, struct socket *so) { struct sockaddr *sockaddr; int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif if (sock_getaddr((socket_t)so, &sockaddr, 1) != 0) { error = ECONNABORTED; } else { MAC_CHECK(socket_check_accepted, cred, - (socket_t)so, so->so_label, sockaddr); + (socket_t)so, so->so_label, sockaddr); sock_freeaddr(sockaddr); } - return (error); + return error; } +#endif int mac_socket_check_bind(kauth_cred_t ucred, struct socket *so, @@ -497,12 +132,16 @@ mac_socket_check_bind(kauth_cred_t ucred, struct socket *so, { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_bind, ucred, - (socket_t)so, so->so_label, sockaddr); - return (error); + (socket_t)so, so->so_label, sockaddr); + return error; } int @@ -511,13 +150,17 @@ mac_socket_check_connect(kauth_cred_t cred, struct socket *so, { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_connect, cred, - (socket_t)so, so->so_label, - sockaddr); - return (error); + (socket_t)so, so->so_label, + sockaddr); + return error; } int @@ -525,49 +168,66 @@ mac_socket_check_create(kauth_cred_t cred, int domain, int type, int protocol) { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_create, cred, domain, type, protocol); - return (error); + return error; } -#if CONFIG_MACF_SOCKET && CONFIG_MACF_NET int -mac_socket_check_deliver(struct socket *so, struct mbuf *mbuf) +mac_socket_check_ioctl(kauth_cred_t cred, struct socket *so, u_long cmd) { - struct label *label; int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif - label = mac_mbuf_to_label(mbuf); - - /* Policy must deal with NULL label (unlabeled mbufs) */ - MAC_CHECK(socket_check_deliver, - (socket_t)so, so->so_label, mbuf, label); - return (error); + MAC_CHECK(socket_check_ioctl, cred, + (socket_t)so, cmd, so->so_label); + return error; } -#else + int -mac_socket_check_deliver(__unused struct socket *so, __unused struct mbuf *mbuf) +mac_socket_check_stat(kauth_cred_t cred, struct socket *so) { - return (0); -} + int error; + +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { + return 0; + } #endif + MAC_CHECK(socket_check_stat, cred, + (socket_t)so, so->so_label); + return error; +} + int mac_socket_check_listen(kauth_cred_t cred, struct socket *so) { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_listen, cred, - (socket_t)so, so->so_label); - return (error); + (socket_t)so, so->so_label); + return error; } int @@ -575,12 +235,16 @@ mac_socket_check_receive(kauth_cred_t cred, struct socket *so) { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_receive, cred, - (socket_t)so, so->so_label); - return (error); + (socket_t)so, so->so_label); + return error; } int @@ -588,51 +252,68 @@ mac_socket_check_received(kauth_cred_t cred, struct socket *so, struct sockaddr { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; - + } +#endif + MAC_CHECK(socket_check_received, cred, - so, so->so_label, saddr); - return (error); + so, so->so_label, saddr); + return error; } int mac_socket_check_send(kauth_cred_t cred, struct socket *so, - struct sockaddr *sockaddr) + struct sockaddr *sockaddr) { int error; - if (!mac_socket_enforce) +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { return 0; + } +#endif MAC_CHECK(socket_check_send, cred, - (socket_t)so, so->so_label, sockaddr); - return (error); + (socket_t)so, so->so_label, sockaddr); + return error; } int mac_socket_check_setsockopt(kauth_cred_t cred, struct socket *so, - struct sockopt *sopt) + struct sockopt *sopt) { int error; - if (!mac_socket_enforce) - return (0); +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { + return 0; + } +#endif MAC_CHECK(socket_check_setsockopt, cred, - (socket_t)so, so->so_label, sopt); - return (error); + (socket_t)so, so->so_label, sopt); + return error; } -int mac_socket_check_getsockopt(kauth_cred_t cred, struct socket *so, - struct sockopt *sopt) +int +mac_socket_check_getsockopt(kauth_cred_t cred, struct socket *so, + struct sockopt *sopt) { int error; - if (!mac_socket_enforce) - return (0); +#if SECURITY_MAC_CHECK_ENFORCE + /* 21167099 - only check if we allow write */ + if (!mac_socket_enforce) { + return 0; + } +#endif MAC_CHECK(socket_check_getsockopt, cred, - (socket_t)so, so->so_label, sopt); - return (error); + (socket_t)so, so->so_label, sopt); + return error; }