]> git.saurik.com Git - apple/xnu.git/blobdiff - security/mac_socket.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / security / mac_socket.c
index 32acf01f56bbb3307c0e09e861dd0ee3c98006eb..45fce695161cd9ba31dbf1bc9cb7f1b0a4698b78 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2007-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 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
  * 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
  * 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.
  * 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.
  * 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,
  * 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.
  * 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@
  */
 /*-
  * @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.
  * 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").
  *
  * This software was enhanced by SPARTA ISSO under SPAWAR contract
  * N66001-04-C-6019 ("SEFOS").
  *
 
 #include <security/mac_internal.h>
 
 
 #include <security/mac_internal.h>
 
-#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;
 
 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;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_accept, cred,
 
        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;
 
 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;
                return 0;
+       }
+#endif
 
        if (sock_getaddr((socket_t)so, &sockaddr, 1) != 0) {
                error = ECONNABORTED;
        } else {
                MAC_CHECK(socket_check_accepted, cred,
 
        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);
        }
                sock_freeaddr(sockaddr);
        }
-       return (error);
+       return error;
 }
 }
+#endif
 
 int
 mac_socket_check_bind(kauth_cred_t ucred, struct socket *so,
 
 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;
 
 {
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_bind, ucred,
 
        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
 }
 
 int
@@ -511,13 +150,17 @@ mac_socket_check_connect(kauth_cred_t cred, struct socket *so,
 {
        int error;
 
 {
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_connect, cred,
 
        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
 }
 
 int
@@ -525,49 +168,66 @@ mac_socket_check_create(kauth_cred_t cred, int domain, int type, int protocol)
 {
        int error;
 
 {
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_create, cred, domain, type, protocol);
 
        MAC_CHECK(socket_check_create, cred, domain, type, protocol);
-       return (error);
+       return error;
 }
 
 }
 
-#if CONFIG_MACF_SOCKET && CONFIG_MACF_NET
 int
 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;
 
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                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
 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
 
 #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;
 
 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;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_listen, cred,
 
        MAC_CHECK(socket_check_listen, cred,
-                 (socket_t)so, so->so_label);
-       return (error);
+           (socket_t)so, so->so_label);
+       return error;
 }
 
 int
 }
 
 int
@@ -575,12 +235,16 @@ mac_socket_check_receive(kauth_cred_t cred, struct socket *so)
 {
        int error;
 
 {
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_receive, cred,
 
        MAC_CHECK(socket_check_receive, cred,
-                 (socket_t)so, so->so_label);
-       return (error);
+           (socket_t)so, so->so_label);
+       return error;
 }
 
 int
 }
 
 int
@@ -588,51 +252,68 @@ mac_socket_check_received(kauth_cred_t cred, struct socket *so, struct sockaddr
 {
        int error;
 
 {
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                return 0;
-       
+       }
+#endif
+
        MAC_CHECK(socket_check_received, cred,
        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,
 }
 
 int
 mac_socket_check_send(kauth_cred_t cred, struct socket *so,
-                     struct sockaddr *sockaddr)
+    struct sockaddr *sockaddr)
 {
        int error;
 
 {
        int error;
 
-       if (!mac_socket_enforce)
+#if SECURITY_MAC_CHECK_ENFORCE
+       /* 21167099 - only check if we allow write */
+       if (!mac_socket_enforce) {
                return 0;
                return 0;
+       }
+#endif
 
        MAC_CHECK(socket_check_send, cred,
 
        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,
 }
 
 int
 mac_socket_check_setsockopt(kauth_cred_t cred, struct socket *so,
-                           struct sockopt *sopt)
+    struct sockopt *sopt)
 {
        int error;
 
 {
        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,
 
        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;
 
 {
        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,
 
        MAC_CHECK(socket_check_getsockopt, cred,
-                 (socket_t)so, so->so_label, sopt);
-       return (error);
+           (socket_t)so, so->so_label, sopt);
+       return error;
 }
 }