Changeset View
Changeset View
Standalone View
Standalone View
head/sys/security/mac/mac_syscalls.c
Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#include <security/mac/mac_internal.h> | #include <security/mac/mac_internal.h> | ||||
#include <security/mac/mac_policy.h> | #include <security/mac/mac_policy.h> | ||||
#ifdef MAC | #ifdef MAC | ||||
FEATURE(security_mac, "Mandatory Access Control Framework support"); | FEATURE(security_mac, "Mandatory Access Control Framework support"); | ||||
static int kern___mac_get_path(struct thread *td, const char *path_p, | |||||
struct mac *mac_p, int follow); | |||||
static int kern___mac_set_path(struct thread *td, const char *path_p, | |||||
struct mac *mac_p, int follow); | |||||
int | int | ||||
sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) | sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) | ||||
{ | { | ||||
char *elements, *buffer; | char *elements, *buffer; | ||||
struct mac mac; | struct mac mac; | ||||
struct proc *tproc; | struct proc *tproc; | ||||
struct ucred *tcred; | struct ucred *tcred; | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | out: | ||||
free(buffer, M_MACTEMP); | free(buffer, M_MACTEMP); | ||||
free(elements, M_MACTEMP); | free(elements, M_MACTEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap) | sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap) | ||||
{ | { | ||||
char *elements, *buffer; | |||||
struct nameidata nd; | |||||
struct label *intlabel; | |||||
struct mac mac; | |||||
int error; | |||||
if (!(mac_labeled & MPC_OBJECT_VNODE)) | return (kern___mac_get_path(td, uap->path_p, uap->mac_p, FOLLOW)); | ||||
return (EINVAL); | |||||
error = copyin(uap->mac_p, &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); | int | ||||
NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, | sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap) | ||||
uap->path_p, td); | { | ||||
error = namei(&nd); | |||||
if (error) | |||||
goto out; | |||||
intlabel = mac_vnode_label_alloc(); | return (kern___mac_get_path(td, uap->path_p, uap->mac_p, NOFOLLOW)); | ||||
mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); | |||||
error = mac_vnode_externalize_label(intlabel, elements, buffer, | |||||
mac.m_buflen); | |||||
NDFREE(&nd, 0); | |||||
mac_vnode_label_free(intlabel); | |||||
if (error == 0) | |||||
error = copyout(buffer, mac.m_string, strlen(buffer)+1); | |||||
out: | |||||
free(buffer, M_MACTEMP); | |||||
free(elements, M_MACTEMP); | |||||
return (error); | |||||
} | } | ||||
int | static int | ||||
sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap) | kern___mac_get_path(struct thread *td, const char *path_p, struct mac *mac_p, | ||||
int follow) | |||||
{ | { | ||||
char *elements, *buffer; | char *elements, *buffer; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
struct label *intlabel; | struct label *intlabel; | ||||
struct mac mac; | struct mac mac; | ||||
int error; | int error; | ||||
if (!(mac_labeled & MPC_OBJECT_VNODE)) | if (!(mac_labeled & MPC_OBJECT_VNODE)) | ||||
return (EINVAL); | return (EINVAL); | ||||
error = copyin(uap->mac_p, &mac, sizeof(mac)); | error = copyin(mac_p, &mac, sizeof(mac)); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
error = mac_check_structmac_consistent(&mac); | error = mac_check_structmac_consistent(&mac); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); | elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); | ||||
error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); | error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); | ||||
if (error) { | if (error) { | ||||
free(elements, M_MACTEMP); | free(elements, M_MACTEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); | buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); | ||||
NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, | NDINIT(&nd, LOOKUP, LOCKLEAF | follow, UIO_USERSPACE, path_p, td); | ||||
uap->path_p, td); | |||||
error = namei(&nd); | error = namei(&nd); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
intlabel = mac_vnode_label_alloc(); | intlabel = mac_vnode_label_alloc(); | ||||
mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); | mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); | ||||
error = mac_vnode_externalize_label(intlabel, elements, buffer, | error = mac_vnode_externalize_label(intlabel, elements, buffer, | ||||
mac.m_buflen); | mac.m_buflen); | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
free(buffer, M_MACTEMP); | free(buffer, M_MACTEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap) | sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap) | ||||
{ | { | ||||
struct label *intlabel; | |||||
struct nameidata nd; | |||||
struct mount *mp; | |||||
struct mac mac; | |||||
char *buffer; | |||||
int error; | |||||
if (!(mac_labeled & MPC_OBJECT_VNODE)) | return (kern___mac_set_path(td, uap->path_p, uap->mac_p, FOLLOW)); | ||||
return (EINVAL); | |||||
error = copyin(uap->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); | |||||
} | } | ||||
intlabel = mac_vnode_label_alloc(); | int | ||||
error = mac_vnode_internalize_label(intlabel, buffer); | sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap) | ||||
free(buffer, M_MACTEMP); | { | ||||
if (error) | |||||
goto out; | |||||
NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, | return (kern___mac_set_path(td, uap->path_p, uap->mac_p, NOFOLLOW)); | ||||
uap->path_p, td); | |||||
error = namei(&nd); | |||||
if (error == 0) { | |||||
error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); | |||||
if (error == 0) { | |||||
error = vn_setlabel(nd.ni_vp, intlabel, | |||||
td->td_ucred); | |||||
vn_finished_write(mp); | |||||
} | } | ||||
} | |||||
NDFREE(&nd, 0); | static int | ||||
out: | kern___mac_set_path(struct thread *td, const char *path_p, struct mac *mac_p, | ||||
mac_vnode_label_free(intlabel); | int follow) | ||||
return (error); | |||||
} | |||||
int | |||||
sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap) | |||||
{ | { | ||||
struct label *intlabel; | struct label *intlabel; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
struct mount *mp; | struct mount *mp; | ||||
struct mac mac; | struct mac mac; | ||||
char *buffer; | char *buffer; | ||||
int error; | int error; | ||||
if (!(mac_labeled & MPC_OBJECT_VNODE)) | if (!(mac_labeled & MPC_OBJECT_VNODE)) | ||||
return (EINVAL); | return (EINVAL); | ||||
error = copyin(uap->mac_p, &mac, sizeof(mac)); | error = copyin(mac_p, &mac, sizeof(mac)); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
error = mac_check_structmac_consistent(&mac); | error = mac_check_structmac_consistent(&mac); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); | buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); | ||||
error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); | error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); | ||||
if (error) { | if (error) { | ||||
free(buffer, M_MACTEMP); | free(buffer, M_MACTEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
intlabel = mac_vnode_label_alloc(); | intlabel = mac_vnode_label_alloc(); | ||||
error = mac_vnode_internalize_label(intlabel, buffer); | error = mac_vnode_internalize_label(intlabel, buffer); | ||||
free(buffer, M_MACTEMP); | free(buffer, M_MACTEMP); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, | NDINIT(&nd, LOOKUP, LOCKLEAF | follow, UIO_USERSPACE, path_p, td); | ||||
uap->path_p, td); | |||||
error = namei(&nd); | error = namei(&nd); | ||||
if (error == 0) { | if (error == 0) { | ||||
error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); | error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); | ||||
if (error == 0) { | if (error == 0) { | ||||
error = vn_setlabel(nd.ni_vp, intlabel, | error = vn_setlabel(nd.ni_vp, intlabel, | ||||
td->td_ucred); | td->td_ucred); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 118 Lines • Show Last 20 Lines |