* 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
* 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,
* 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@
*/
/*-
* 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").
*
#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;
- 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,
{
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
{
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
{
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
{
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
{
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;
}