Implement sockets support for __mac_get_fd() and __mac_set_fd()
system calls, and prefer these calls over getsockopt()/setsockopt() for ABI reasons. When addressing UNIX domain sockets, these calls retrieve and modify the socket label, not the label of the rendezvous vnode. - Create mac_copy_socket_label() entry point based on mac_copy_pipe_label() entry point, intended to copy the socket label into temporary storage that doesn't require a socket lock to be held (currently Giant). - Implement mac_copy_socket_label() for various policies. - Expose socket label allocation, free, internalize, externalize entry points as non-static from mac_net.c. - Use mac_socket_label_set() in __mac_set_fd(). MAC-aware applications may now use mac_get_fd(), mac_set_fd(), and mac_get_peer() to retrieve and set various socket labels without directly invoking the getsockopt() interface. Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories
This commit is contained in:
parent
b9c29fa9ae
commit
b0323ea3aa
@ -701,6 +701,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
|
|||||||
struct mac mac;
|
struct mac mac;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
struct socket *so;
|
||||||
short label_type;
|
short label_type;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -751,6 +752,19 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
|
|||||||
mac_pipe_label_free(intlabel);
|
mac_pipe_label_free(intlabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTYPE_SOCKET:
|
||||||
|
so = fp->f_data;
|
||||||
|
intlabel = mac_socket_label_alloc(M_WAITOK);
|
||||||
|
mtx_lock(&Giant); /* Sockets */
|
||||||
|
/* XXX: Socket lock here. */
|
||||||
|
mac_copy_socket_label(so->so_label, intlabel);
|
||||||
|
/* XXX: Socket unlock here. */
|
||||||
|
mtx_unlock(&Giant); /* Sockets */
|
||||||
|
error = mac_externalize_socket_label(intlabel, elements,
|
||||||
|
buffer, mac.m_buflen);
|
||||||
|
mac_socket_label_free(intlabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
@ -881,6 +895,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
|
|||||||
{
|
{
|
||||||
struct label *intlabel;
|
struct label *intlabel;
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
struct socket *so;
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
@ -945,6 +960,21 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
|
|||||||
mac_pipe_label_free(intlabel);
|
mac_pipe_label_free(intlabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTYPE_SOCKET:
|
||||||
|
intlabel = mac_socket_label_alloc(M_WAITOK);
|
||||||
|
error = mac_internalize_socket_label(intlabel, buffer);
|
||||||
|
if (error == 0) {
|
||||||
|
so = fp->f_data;
|
||||||
|
mtx_lock(&Giant); /* Sockets */
|
||||||
|
/* XXX: Socket lock here. */
|
||||||
|
error = mac_socket_label_set(td->td_ucred, so,
|
||||||
|
intlabel);
|
||||||
|
/* XXX: Socket unlock here. */
|
||||||
|
mtx_unlock(&Giant); /* Sockets */
|
||||||
|
}
|
||||||
|
mac_socket_label_free(intlabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -701,6 +701,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
|
|||||||
struct mac mac;
|
struct mac mac;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
struct socket *so;
|
||||||
short label_type;
|
short label_type;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -751,6 +752,19 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
|
|||||||
mac_pipe_label_free(intlabel);
|
mac_pipe_label_free(intlabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTYPE_SOCKET:
|
||||||
|
so = fp->f_data;
|
||||||
|
intlabel = mac_socket_label_alloc(M_WAITOK);
|
||||||
|
mtx_lock(&Giant); /* Sockets */
|
||||||
|
/* XXX: Socket lock here. */
|
||||||
|
mac_copy_socket_label(so->so_label, intlabel);
|
||||||
|
/* XXX: Socket unlock here. */
|
||||||
|
mtx_unlock(&Giant); /* Sockets */
|
||||||
|
error = mac_externalize_socket_label(intlabel, elements,
|
||||||
|
buffer, mac.m_buflen);
|
||||||
|
mac_socket_label_free(intlabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
@ -881,6 +895,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
|
|||||||
{
|
{
|
||||||
struct label *intlabel;
|
struct label *intlabel;
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
struct socket *so;
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
@ -945,6 +960,21 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
|
|||||||
mac_pipe_label_free(intlabel);
|
mac_pipe_label_free(intlabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTYPE_SOCKET:
|
||||||
|
intlabel = mac_socket_label_alloc(M_WAITOK);
|
||||||
|
error = mac_internalize_socket_label(intlabel, buffer);
|
||||||
|
if (error == 0) {
|
||||||
|
so = fp->f_data;
|
||||||
|
mtx_lock(&Giant); /* Sockets */
|
||||||
|
/* XXX: Socket lock here. */
|
||||||
|
error = mac_socket_label_set(td->td_ucred, so,
|
||||||
|
intlabel);
|
||||||
|
/* XXX: Socket unlock here. */
|
||||||
|
mtx_unlock(&Giant); /* Sockets */
|
||||||
|
}
|
||||||
|
mac_socket_label_free(intlabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,8 @@ int mac_allocate_slot(void);
|
|||||||
*/
|
*/
|
||||||
struct label *mac_pipe_label_alloc(void);
|
struct label *mac_pipe_label_alloc(void);
|
||||||
void mac_pipe_label_free(struct label *label);
|
void mac_pipe_label_free(struct label *label);
|
||||||
|
struct label *mac_socket_label_alloc(int flag);
|
||||||
|
void mac_socket_label_free(struct label *label);
|
||||||
|
|
||||||
int mac_check_cred_relabel(struct ucred *cred, struct label *newlabel);
|
int mac_check_cred_relabel(struct ucred *cred, struct label *newlabel);
|
||||||
int mac_externalize_cred_label(struct label *label, char *elements,
|
int mac_externalize_cred_label(struct label *label, char *elements,
|
||||||
@ -123,6 +125,10 @@ int mac_internalize_pipe_label(struct label *label, char *string);
|
|||||||
|
|
||||||
int mac_socket_label_set(struct ucred *cred, struct socket *so,
|
int mac_socket_label_set(struct ucred *cred, struct socket *so,
|
||||||
struct label *label);
|
struct label *label);
|
||||||
|
void mac_copy_socket_label(struct label *src, struct label *dest);
|
||||||
|
int mac_externalize_socket_label(struct label *label, char *elements,
|
||||||
|
char *outbuf, size_t outbuflen);
|
||||||
|
int mac_internalize_socket_label(struct label *label, char *string);
|
||||||
|
|
||||||
int mac_externalize_vnode_label(struct label *label, char *elements,
|
int mac_externalize_vnode_label(struct label *label, char *elements,
|
||||||
char *outbuf, size_t outbuflen);
|
char *outbuf, size_t outbuflen);
|
||||||
|
@ -91,9 +91,6 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
|
|||||||
&nmacsockets, 0, "number of sockets in use");
|
&nmacsockets, 0, "number of sockets in use");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void mac_socket_label_free(struct label *label);
|
|
||||||
|
|
||||||
|
|
||||||
static struct label *
|
static struct label *
|
||||||
mbuf_to_label(struct mbuf *mbuf)
|
mbuf_to_label(struct mbuf *mbuf)
|
||||||
{
|
{
|
||||||
@ -220,7 +217,7 @@ mac_init_mbuf(struct mbuf *m, int flag)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct label *
|
struct label *
|
||||||
mac_socket_label_alloc(int flag)
|
mac_socket_label_alloc(int flag)
|
||||||
{
|
{
|
||||||
struct label *label;
|
struct label *label;
|
||||||
@ -339,7 +336,7 @@ mac_destroy_mbuf_tag(struct m_tag *tag)
|
|||||||
MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
|
MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
mac_socket_label_free(struct label *label)
|
mac_socket_label_free(struct label *label)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -382,6 +379,13 @@ mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
|
|||||||
MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
|
MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mac_copy_socket_label(struct label *src, struct label *dest)
|
||||||
|
{
|
||||||
|
|
||||||
|
MAC_PERFORM(copy_socket_label, src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mac_externalize_ifnet_label(struct label *label, char *elements,
|
mac_externalize_ifnet_label(struct label *label, char *elements,
|
||||||
char *outbuf, size_t outbuflen)
|
char *outbuf, size_t outbuflen)
|
||||||
@ -393,7 +397,7 @@ mac_externalize_ifnet_label(struct label *label, char *elements,
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
mac_externalize_socket_label(struct label *label, char *elements,
|
mac_externalize_socket_label(struct label *label, char *elements,
|
||||||
char *outbuf, size_t outbuflen)
|
char *outbuf, size_t outbuflen)
|
||||||
{
|
{
|
||||||
@ -425,7 +429,7 @@ mac_internalize_ifnet_label(struct label *label, char *string)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
mac_internalize_socket_label(struct label *label, char *string)
|
mac_internalize_socket_label(struct label *label, char *string)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
@ -112,6 +112,8 @@ struct mac_policy_ops {
|
|||||||
struct label *dest);
|
struct label *dest);
|
||||||
void (*mpo_copy_pipe_label)(struct label *src,
|
void (*mpo_copy_pipe_label)(struct label *src,
|
||||||
struct label *dest);
|
struct label *dest);
|
||||||
|
void (*mpo_copy_socket_label)(struct label *src,
|
||||||
|
struct label *dest);
|
||||||
void (*mpo_copy_vnode_label)(struct label *src,
|
void (*mpo_copy_vnode_label)(struct label *src,
|
||||||
struct label *dest);
|
struct label *dest);
|
||||||
int (*mpo_externalize_cred_label)(struct label *label,
|
int (*mpo_externalize_cred_label)(struct label *label,
|
||||||
|
@ -701,6 +701,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
|
|||||||
struct mac mac;
|
struct mac mac;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
struct socket *so;
|
||||||
short label_type;
|
short label_type;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -751,6 +752,19 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
|
|||||||
mac_pipe_label_free(intlabel);
|
mac_pipe_label_free(intlabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTYPE_SOCKET:
|
||||||
|
so = fp->f_data;
|
||||||
|
intlabel = mac_socket_label_alloc(M_WAITOK);
|
||||||
|
mtx_lock(&Giant); /* Sockets */
|
||||||
|
/* XXX: Socket lock here. */
|
||||||
|
mac_copy_socket_label(so->so_label, intlabel);
|
||||||
|
/* XXX: Socket unlock here. */
|
||||||
|
mtx_unlock(&Giant); /* Sockets */
|
||||||
|
error = mac_externalize_socket_label(intlabel, elements,
|
||||||
|
buffer, mac.m_buflen);
|
||||||
|
mac_socket_label_free(intlabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
@ -881,6 +895,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
|
|||||||
{
|
{
|
||||||
struct label *intlabel;
|
struct label *intlabel;
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
struct socket *so;
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
@ -945,6 +960,21 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
|
|||||||
mac_pipe_label_free(intlabel);
|
mac_pipe_label_free(intlabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTYPE_SOCKET:
|
||||||
|
intlabel = mac_socket_label_alloc(M_WAITOK);
|
||||||
|
error = mac_internalize_socket_label(intlabel, buffer);
|
||||||
|
if (error == 0) {
|
||||||
|
so = fp->f_data;
|
||||||
|
mtx_lock(&Giant); /* Sockets */
|
||||||
|
/* XXX: Socket lock here. */
|
||||||
|
error = mac_socket_label_set(td->td_ucred, so,
|
||||||
|
intlabel);
|
||||||
|
/* XXX: Socket unlock here. */
|
||||||
|
mtx_unlock(&Giant); /* Sockets */
|
||||||
|
}
|
||||||
|
mac_socket_label_free(intlabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -2635,6 +2635,7 @@ static struct mac_policy_ops mac_biba_ops =
|
|||||||
.mpo_destroy_vnode_label = mac_biba_destroy_label,
|
.mpo_destroy_vnode_label = mac_biba_destroy_label,
|
||||||
.mpo_copy_mbuf_label = mac_biba_copy_label,
|
.mpo_copy_mbuf_label = mac_biba_copy_label,
|
||||||
.mpo_copy_pipe_label = mac_biba_copy_label,
|
.mpo_copy_pipe_label = mac_biba_copy_label,
|
||||||
|
.mpo_copy_socket_label = mac_biba_copy_label,
|
||||||
.mpo_copy_vnode_label = mac_biba_copy_label,
|
.mpo_copy_vnode_label = mac_biba_copy_label,
|
||||||
.mpo_externalize_cred_label = mac_biba_externalize_label,
|
.mpo_externalize_cred_label = mac_biba_externalize_label,
|
||||||
.mpo_externalize_ifnet_label = mac_biba_externalize_label,
|
.mpo_externalize_ifnet_label = mac_biba_externalize_label,
|
||||||
|
@ -2615,6 +2615,7 @@ static struct mac_policy_ops mac_lomac_ops =
|
|||||||
.mpo_destroy_vnode_label = mac_lomac_destroy_label,
|
.mpo_destroy_vnode_label = mac_lomac_destroy_label,
|
||||||
.mpo_copy_mbuf_label = mac_lomac_copy_label,
|
.mpo_copy_mbuf_label = mac_lomac_copy_label,
|
||||||
.mpo_copy_pipe_label = mac_lomac_copy_label,
|
.mpo_copy_pipe_label = mac_lomac_copy_label,
|
||||||
|
.mpo_copy_socket_label = mac_lomac_copy_label,
|
||||||
.mpo_copy_vnode_label = mac_lomac_copy_label,
|
.mpo_copy_vnode_label = mac_lomac_copy_label,
|
||||||
.mpo_externalize_cred_label = mac_lomac_externalize_label,
|
.mpo_externalize_cred_label = mac_lomac_externalize_label,
|
||||||
.mpo_externalize_ifnet_label = mac_lomac_externalize_label,
|
.mpo_externalize_ifnet_label = mac_lomac_externalize_label,
|
||||||
|
@ -2407,6 +2407,7 @@ static struct mac_policy_ops mac_mls_ops =
|
|||||||
.mpo_destroy_vnode_label = mac_mls_destroy_label,
|
.mpo_destroy_vnode_label = mac_mls_destroy_label,
|
||||||
.mpo_copy_mbuf_label = mac_mls_copy_label,
|
.mpo_copy_mbuf_label = mac_mls_copy_label,
|
||||||
.mpo_copy_pipe_label = mac_mls_copy_label,
|
.mpo_copy_pipe_label = mac_mls_copy_label,
|
||||||
|
.mpo_copy_socket_label = mac_mls_copy_label,
|
||||||
.mpo_copy_vnode_label = mac_mls_copy_label,
|
.mpo_copy_vnode_label = mac_mls_copy_label,
|
||||||
.mpo_externalize_cred_label = mac_mls_externalize_label,
|
.mpo_externalize_cred_label = mac_mls_externalize_label,
|
||||||
.mpo_externalize_ifnet_label = mac_mls_externalize_label,
|
.mpo_externalize_ifnet_label = mac_mls_externalize_label,
|
||||||
|
@ -1032,6 +1032,7 @@ static struct mac_policy_ops mac_stub_ops =
|
|||||||
.mpo_destroy_vnode_label = stub_destroy_label,
|
.mpo_destroy_vnode_label = stub_destroy_label,
|
||||||
.mpo_copy_mbuf_label = stub_copy_label,
|
.mpo_copy_mbuf_label = stub_copy_label,
|
||||||
.mpo_copy_pipe_label = stub_copy_label,
|
.mpo_copy_pipe_label = stub_copy_label,
|
||||||
|
.mpo_copy_socket_label = stub_copy_label,
|
||||||
.mpo_copy_vnode_label = stub_copy_label,
|
.mpo_copy_vnode_label = stub_copy_label,
|
||||||
.mpo_externalize_cred_label = stub_externalize_label,
|
.mpo_externalize_cred_label = stub_externalize_label,
|
||||||
.mpo_externalize_ifnet_label = stub_externalize_label,
|
.mpo_externalize_ifnet_label = stub_externalize_label,
|
||||||
|
@ -569,6 +569,14 @@ mac_test_copy_pipe_label(struct label *src, struct label *dest)
|
|||||||
ASSERT_PIPE_LABEL(dest);
|
ASSERT_PIPE_LABEL(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mac_test_copy_socket_label(struct label *src, struct label *dest)
|
||||||
|
{
|
||||||
|
|
||||||
|
ASSERT_SOCKET_LABEL(src);
|
||||||
|
ASSERT_SOCKET_LABEL(dest);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mac_test_copy_vnode_label(struct label *src, struct label *dest)
|
mac_test_copy_vnode_label(struct label *src, struct label *dest)
|
||||||
{
|
{
|
||||||
@ -1805,6 +1813,7 @@ static struct mac_policy_ops mac_test_ops =
|
|||||||
.mpo_destroy_vnode_label = mac_test_destroy_vnode_label,
|
.mpo_destroy_vnode_label = mac_test_destroy_vnode_label,
|
||||||
.mpo_copy_mbuf_label = mac_test_copy_mbuf_label,
|
.mpo_copy_mbuf_label = mac_test_copy_mbuf_label,
|
||||||
.mpo_copy_pipe_label = mac_test_copy_pipe_label,
|
.mpo_copy_pipe_label = mac_test_copy_pipe_label,
|
||||||
|
.mpo_copy_socket_label = mac_test_copy_socket_label,
|
||||||
.mpo_copy_vnode_label = mac_test_copy_vnode_label,
|
.mpo_copy_vnode_label = mac_test_copy_vnode_label,
|
||||||
.mpo_externalize_cred_label = mac_test_externalize_label,
|
.mpo_externalize_cred_label = mac_test_externalize_label,
|
||||||
.mpo_externalize_ifnet_label = mac_test_externalize_label,
|
.mpo_externalize_ifnet_label = mac_test_externalize_label,
|
||||||
|
@ -112,6 +112,8 @@ struct mac_policy_ops {
|
|||||||
struct label *dest);
|
struct label *dest);
|
||||||
void (*mpo_copy_pipe_label)(struct label *src,
|
void (*mpo_copy_pipe_label)(struct label *src,
|
||||||
struct label *dest);
|
struct label *dest);
|
||||||
|
void (*mpo_copy_socket_label)(struct label *src,
|
||||||
|
struct label *dest);
|
||||||
void (*mpo_copy_vnode_label)(struct label *src,
|
void (*mpo_copy_vnode_label)(struct label *src,
|
||||||
struct label *dest);
|
struct label *dest);
|
||||||
int (*mpo_externalize_cred_label)(struct label *label,
|
int (*mpo_externalize_cred_label)(struct label *label,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user