-#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 */
-