diff options
author | rwatson <rwatson@FreeBSD.org> | 2003-11-16 23:31:45 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2003-11-16 23:31:45 +0000 |
commit | 7aa5c2497a67b36cc05ec3c76dca0423b69c9400 (patch) | |
tree | fede3115e7ef270fd4883e1c4206febe55c2efa7 /sys | |
parent | 44e24b4739d0c28d3ffa69afb7e63d3229969a27 (diff) | |
download | FreeBSD-src-7aa5c2497a67b36cc05ec3c76dca0423b69c9400.zip FreeBSD-src-7aa5c2497a67b36cc05ec3c76dca0423b69c9400.tar.gz |
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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_mac.c | 30 | ||||
-rw-r--r-- | sys/security/mac/mac_framework.c | 30 | ||||
-rw-r--r-- | sys/security/mac/mac_internal.h | 6 | ||||
-rw-r--r-- | sys/security/mac/mac_net.c | 18 | ||||
-rw-r--r-- | sys/security/mac/mac_policy.h | 2 | ||||
-rw-r--r-- | sys/security/mac/mac_syscalls.c | 30 | ||||
-rw-r--r-- | sys/security/mac_biba/mac_biba.c | 1 | ||||
-rw-r--r-- | sys/security/mac_lomac/mac_lomac.c | 1 | ||||
-rw-r--r-- | sys/security/mac_mls/mac_mls.c | 1 | ||||
-rw-r--r-- | sys/security/mac_stub/mac_stub.c | 1 | ||||
-rw-r--r-- | sys/security/mac_test/mac_test.c | 9 | ||||
-rw-r--r-- | sys/sys/mac_policy.h | 2 |
12 files changed, 124 insertions, 7 deletions
diff --git a/sys/kern/kern_mac.c b/sys/kern/kern_mac.c index c1710f2..f42b075 100644 --- a/sys/kern/kern_mac.c +++ b/sys/kern/kern_mac.c @@ -701,6 +701,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) struct mac mac; struct vnode *vp; struct pipe *pipe; + struct socket *so; short label_type; int error; @@ -751,6 +752,19 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) mac_pipe_label_free(intlabel); 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: error = EINVAL; } @@ -881,6 +895,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) { struct label *intlabel; struct pipe *pipe; + struct socket *so; struct file *fp; struct mount *mp; struct vnode *vp; @@ -945,6 +960,21 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) mac_pipe_label_free(intlabel); 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: error = EINVAL; } diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index c1710f2..f42b075 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -701,6 +701,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) struct mac mac; struct vnode *vp; struct pipe *pipe; + struct socket *so; short label_type; int error; @@ -751,6 +752,19 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) mac_pipe_label_free(intlabel); 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: error = EINVAL; } @@ -881,6 +895,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) { struct label *intlabel; struct pipe *pipe; + struct socket *so; struct file *fp; struct mount *mp; struct vnode *vp; @@ -945,6 +960,21 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) mac_pipe_label_free(intlabel); 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: error = EINVAL; } diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index b6983e3..b214528 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -109,6 +109,8 @@ int mac_allocate_slot(void); */ struct label *mac_pipe_label_alloc(void); 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_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, 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, char *outbuf, size_t outbuflen); diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c index 183e79c..7ff0d28 100644 --- a/sys/security/mac/mac_net.c +++ b/sys/security/mac/mac_net.c @@ -91,9 +91,6 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, &nmacsockets, 0, "number of sockets in use"); #endif -static void mac_socket_label_free(struct label *label); - - static struct label * mbuf_to_label(struct mbuf *mbuf) { @@ -220,7 +217,7 @@ mac_init_mbuf(struct mbuf *m, int flag) return (0); } -static struct label * +struct label * mac_socket_label_alloc(int flag) { struct label *label; @@ -339,7 +336,7 @@ mac_destroy_mbuf_tag(struct m_tag *tag) MAC_DEBUG_COUNTER_DEC(&nmacmbufs); } -static void +void 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); } +void +mac_copy_socket_label(struct label *src, struct label *dest) +{ + + MAC_PERFORM(copy_socket_label, src, dest); +} + static int mac_externalize_ifnet_label(struct label *label, char *elements, char *outbuf, size_t outbuflen) @@ -393,7 +397,7 @@ mac_externalize_ifnet_label(struct label *label, char *elements, return (error); } -static int +int mac_externalize_socket_label(struct label *label, char *elements, char *outbuf, size_t outbuflen) { @@ -425,7 +429,7 @@ mac_internalize_ifnet_label(struct label *label, char *string) return (error); } -static int +int mac_internalize_socket_label(struct label *label, char *string) { int error; diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index 005d6c7..3c72d09 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -112,6 +112,8 @@ struct mac_policy_ops { struct label *dest); void (*mpo_copy_pipe_label)(struct label *src, struct label *dest); + void (*mpo_copy_socket_label)(struct label *src, + struct label *dest); void (*mpo_copy_vnode_label)(struct label *src, struct label *dest); int (*mpo_externalize_cred_label)(struct label *label, diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index c1710f2..f42b075 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -701,6 +701,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) struct mac mac; struct vnode *vp; struct pipe *pipe; + struct socket *so; short label_type; int error; @@ -751,6 +752,19 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) mac_pipe_label_free(intlabel); 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: error = EINVAL; } @@ -881,6 +895,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) { struct label *intlabel; struct pipe *pipe; + struct socket *so; struct file *fp; struct mount *mp; struct vnode *vp; @@ -945,6 +960,21 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) mac_pipe_label_free(intlabel); 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: error = EINVAL; } diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c index fd021eb..3ad8bd5 100644 --- a/sys/security/mac_biba/mac_biba.c +++ b/sys/security/mac_biba/mac_biba.c @@ -2635,6 +2635,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_destroy_vnode_label = mac_biba_destroy_label, .mpo_copy_mbuf_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_externalize_cred_label = mac_biba_externalize_label, .mpo_externalize_ifnet_label = mac_biba_externalize_label, diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c index be13a47..7c2f3cb 100644 --- a/sys/security/mac_lomac/mac_lomac.c +++ b/sys/security/mac_lomac/mac_lomac.c @@ -2615,6 +2615,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_destroy_vnode_label = mac_lomac_destroy_label, .mpo_copy_mbuf_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_externalize_cred_label = mac_lomac_externalize_label, .mpo_externalize_ifnet_label = mac_lomac_externalize_label, diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c index 89ecf27..9edcad7 100644 --- a/sys/security/mac_mls/mac_mls.c +++ b/sys/security/mac_mls/mac_mls.c @@ -2407,6 +2407,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_destroy_vnode_label = mac_mls_destroy_label, .mpo_copy_mbuf_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_externalize_cred_label = mac_mls_externalize_label, .mpo_externalize_ifnet_label = mac_mls_externalize_label, diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c index a0c7d95..1d48210 100644 --- a/sys/security/mac_stub/mac_stub.c +++ b/sys/security/mac_stub/mac_stub.c @@ -1032,6 +1032,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_destroy_vnode_label = stub_destroy_label, .mpo_copy_mbuf_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_externalize_cred_label = stub_externalize_label, .mpo_externalize_ifnet_label = stub_externalize_label, diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c index 0b4b037..8b591902 100644 --- a/sys/security/mac_test/mac_test.c +++ b/sys/security/mac_test/mac_test.c @@ -570,6 +570,14 @@ mac_test_copy_pipe_label(struct label *src, struct 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 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_copy_mbuf_label = mac_test_copy_mbuf_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_externalize_cred_label = mac_test_externalize_label, .mpo_externalize_ifnet_label = mac_test_externalize_label, diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index 005d6c7..3c72d09 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -112,6 +112,8 @@ struct mac_policy_ops { struct label *dest); void (*mpo_copy_pipe_label)(struct label *src, struct label *dest); + void (*mpo_copy_socket_label)(struct label *src, + struct label *dest); void (*mpo_copy_vnode_label)(struct label *src, struct label *dest); int (*mpo_externalize_cred_label)(struct label *label, |