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_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac) { struct label *intlabel; char *buffer; int error; if (!(mac_labeled & MPC_OBJECT_SOCKET)) return (EINVAL); error = mac_check_structmac_consistent(mac); if (error) return (error); buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); if (error) { free(buffer, M_MACTEMP); return (error); } intlabel = mac_socket_label_alloc(M_WAITOK); error = mac_socket_internalize_label(intlabel, buffer); free(buffer, M_MACTEMP); if (error) goto out; error = mac_socket_label_set(cred, so, intlabel); out: mac_socket_label_free(intlabel); return (error); }
int mac_execve_enter(user_addr_t mac_p, struct image_params *imgp) { struct user_mac mac; struct label *execlabel; char *buffer; int error; size_t ulen; if (mac_p == USER_ADDR_NULL) return (0); if (IS_64BIT_PROCESS(current_proc())) { struct user64_mac mac64; error = copyin(mac_p, &mac64, sizeof(mac64)); mac.m_buflen = mac64.m_buflen; mac.m_string = mac64.m_string; } else { struct user32_mac mac32; error = copyin(mac_p, &mac32, sizeof(mac32)); mac.m_buflen = mac32.m_buflen; mac.m_string = mac32.m_string; } if (error) return (error); error = mac_check_structmac_consistent(&mac); if (error) return (error); execlabel = mac_cred_label_alloc(); MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(CAST_USER_ADDR_T(mac.m_string), buffer, mac.m_buflen, &ulen); if (error) goto out; AUDIT_ARG(mac_string, buffer); error = mac_cred_label_internalize(execlabel, buffer); out: if (error) { mac_cred_label_free(execlabel); execlabel = NULL; } imgp->ip_execlabelp = execlabel; FREE(buffer, M_MACTEMP); return (error); }
int mac_ifnet_ioctl_get(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifp) { char *elements, *buffer; struct label *intlabel; struct mac mac; int error; if (!(mac_labeled & MPC_OBJECT_IFNET)) return (EINVAL); error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); if (error) return (error); error = mac_check_structmac_consistent(&mac); if (error) return (error); elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); if (error) { free(elements, M_MACTEMP); return (error); } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); intlabel = mac_ifnet_label_alloc(); MAC_IFNET_LOCK(ifp); mac_ifnet_copy_label(ifp->if_label, intlabel); MAC_IFNET_UNLOCK(ifp); error = mac_ifnet_externalize_label(intlabel, elements, buffer, mac.m_buflen); mac_ifnet_label_free(intlabel); if (error == 0) error = copyout(buffer, mac.m_string, strlen(buffer)+1); free(buffer, M_MACTEMP); free(elements, M_MACTEMP); return (error); }
int mac_execve_enter(struct image_params *imgp, struct mac *mac_p) { struct label *label; struct mac mac; char *buffer; int error; if (mac_p == NULL) return (0); if (!(mac_labeled & MPC_OBJECT_CRED)) return (EINVAL); error = copyin(mac_p, &mac, sizeof(mac)); if (error) return (error); error = mac_check_structmac_consistent(&mac); if (error) return (error); buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); if (error) { free(buffer, M_MACTEMP); return (error); } label = mac_cred_label_alloc(); error = mac_cred_internalize_label(label, buffer); free(buffer, M_MACTEMP); if (error) { mac_cred_label_free(label); return (error); } imgp->execlabel = label; return (0); }
int mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, struct mac *mac) { char *elements, *buffer; struct label *intlabel; int error; if (!(mac_labeled & MPC_OBJECT_SOCKET)) return (EINVAL); error = mac_check_structmac_consistent(mac); if (error) return (error); elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); if (error) { free(elements, M_MACTEMP); return (error); } buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); intlabel = mac_socket_label_alloc(M_WAITOK); SOCK_LOCK(so); mac_socket_copy_label(so->so_peerlabel, intlabel); SOCK_UNLOCK(so); error = mac_socketpeer_externalize_label(intlabel, elements, buffer, mac->m_buflen); mac_socket_label_free(intlabel); if (error == 0) error = copyout(buffer, 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); }
int mac_ifnet_ioctl_set(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifp) { struct label *intlabel; struct mac mac; char *buffer; int error; if (!(mac_labeled & MPC_OBJECT_IFNET)) return (EINVAL); error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); if (error) return (error); error = mac_check_structmac_consistent(&mac); if (error) return (error); buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); if (error) { free(buffer, M_MACTEMP); return (error); } intlabel = mac_ifnet_label_alloc(); error = mac_ifnet_internalize_label(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 = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); if (error) { mac_ifnet_label_free(intlabel); return (error); } MAC_IFNET_LOCK(ifp); MAC_POLICY_CHECK_NOSLEEP(ifnet_check_relabel, cred, ifp, ifp->if_label, intlabel); if (error) { MAC_IFNET_UNLOCK(ifp); mac_ifnet_label_free(intlabel); return (error); } MAC_POLICY_PERFORM_NOSLEEP(ifnet_relabel, cred, ifp, ifp->if_label, intlabel); MAC_IFNET_UNLOCK(ifp); mac_ifnet_label_free(intlabel); return (0); }