summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_prot.c2
-rw-r--r--sys/kern/sys_socket.c8
-rw-r--r--sys/kern/uipc_socket.c2
-rw-r--r--sys/kern/uipc_syscalls.c48
-rw-r--r--sys/kern/uipc_usrreq.c2
-rw-r--r--sys/netatalk/ddp_input.c6
-rw-r--r--sys/netinet/ip_divert.c2
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/tcp_syncache.c2
-rw-r--r--sys/rpc/svc_vc.c2
-rw-r--r--sys/security/mac/mac_framework.c16
-rw-r--r--sys/security/mac/mac_internal.h1
-rw-r--r--sys/security/mac/mac_socket.c75
13 files changed, 83 insertions, 85 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index a1a55f2..4e0bdf0 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1690,9 +1690,7 @@ cr_canseesocket(struct ucred *cred, struct socket *so)
if (error)
return (ENOENT);
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_visible(cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 61b0361..5e5695c 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -78,9 +78,7 @@ soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
int error;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_receive(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
@@ -99,9 +97,7 @@ soo_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
int error;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
@@ -222,9 +218,7 @@ soo_poll(struct file *fp, int events, struct ucred *active_cred,
#ifdef MAC
int error;
- SOCK_LOCK(so);
error = mac_socket_check_poll(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
@@ -243,9 +237,7 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
bzero((caddr_t)ub, sizeof (*ub));
ub->st_mode = S_IFSOCK;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_stat(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 80f9a55..7341d3f 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -444,9 +444,7 @@ sonewconn(struct socket *head, int connstatus)
so->so_proto = head->so_proto;
so->so_cred = crhold(head->so_cred);
#ifdef MAC
- SOCK_LOCK(head);
mac_socket_newconn(head, so);
- SOCK_UNLOCK(head);
#endif
knlist_init(&so->so_rcv.sb_sel.si_note, SOCKBUF_MTX(&so->so_rcv),
NULL, NULL, NULL);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 66eb7e1..964547c 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -221,16 +221,10 @@ kern_bind(td, fd, sa)
ktrsockaddr(sa);
#endif
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_bind(td->td_ucred, so, sa);
- SOCK_UNLOCK(so);
- if (error)
- goto done;
-#endif
- error = sobind(so, sa, td);
-#ifdef MAC
-done:
+ if (error == 0)
#endif
+ error = sobind(so, sa, td);
fdrop(fp, td);
return (error);
}
@@ -252,17 +246,14 @@ listen(td, uap)
if (error == 0) {
so = fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_listen(td->td_ucred, so);
- SOCK_UNLOCK(so);
- if (error)
- goto done;
+ if (error == 0) {
#endif
- CURVNET_SET(so->so_vnet);
- error = solisten(so, uap->backlog, td);
- CURVNET_RESTORE();
+ CURVNET_SET(so->so_vnet);
+ error = solisten(so, uap->backlog, td);
+ CURVNET_RESTORE();
#ifdef MAC
-done:
+ }
#endif
fdrop(fp, td);
}
@@ -354,9 +345,7 @@ kern_accept(struct thread *td, int s, struct sockaddr **name,
goto done;
}
#ifdef MAC
- SOCK_LOCK(head);
error = mac_socket_check_accept(td->td_ucred, head);
- SOCK_UNLOCK(head);
if (error != 0)
goto done;
#endif
@@ -549,9 +538,7 @@ kern_connect(td, fd, sa)
ktrsockaddr(sa);
#endif
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_connect(td->td_ucred, so, sa);
- SOCK_UNLOCK(so);
if (error)
goto bad;
#endif
@@ -603,7 +590,6 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol,
if (error)
return (error);
#endif
-
error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
if (error)
return (error);
@@ -752,13 +738,13 @@ kern_sendit(td, s, mp, flags, control, segflg)
so = (struct socket *)fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
- if (mp->msg_name != NULL)
+ if (mp->msg_name != NULL) {
error = mac_socket_check_connect(td->td_ucred, so,
mp->msg_name);
- if (error == 0)
- error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
+ if (error)
+ goto bad;
+ }
+ error = mac_socket_check_send(td->td_ucred, so);
if (error)
goto bad;
#endif
@@ -951,9 +937,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
so = fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_receive(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error) {
fdrop(fp, td);
return (error);
@@ -1887,9 +1871,7 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap,
}
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error)
goto out;
#endif
@@ -2417,9 +2399,7 @@ sctp_generic_sendmsg (td, uap)
so = (struct socket *)fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error)
goto sctp_bad;
#endif /* MAC */
@@ -2521,9 +2501,7 @@ sctp_generic_sendmsg_iov(td, uap)
so = (struct socket *)fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error)
goto sctp_bad;
#endif /* MAC */
@@ -2618,9 +2596,7 @@ sctp_generic_recvmsg(td, uap)
so = fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_receive(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error) {
goto out;
return (error);
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 2f33008..c9e7d39 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1246,10 +1246,8 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
UNP_PCB_UNLOCK(unp2);
UNP_PCB_UNLOCK(unp);
#ifdef MAC
- SOCK_LOCK(so);
mac_socketpeer_set_from_socket(so, so3);
mac_socketpeer_set_from_socket(so3, so);
- SOCK_UNLOCK(so);
#endif
so2 = so3;
diff --git a/sys/netatalk/ddp_input.c b/sys/netatalk/ddp_input.c
index 2e7dac8..d90b2e8 100644
--- a/sys/netatalk/ddp_input.c
+++ b/sys/netatalk/ddp_input.c
@@ -410,12 +410,8 @@ ddp_input(struct mbuf *m, struct ifnet *ifp, struct elaphdr *elh, int phase)
goto out;
#ifdef MAC
- SOCK_LOCK(ddp->ddp_socket);
- if (mac_socket_check_deliver(ddp->ddp_socket, m) != 0) {
- SOCK_UNLOCK(ddp->ddp_socket);
+ if (mac_socket_check_deliver(ddp->ddp_socket, m) != 0)
goto out;
- }
- SOCK_UNLOCK(ddp->ddp_socket);
#endif
/*
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 5e71d4d..0894bfa4 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -467,9 +467,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
m->m_pkthdr.rcvif = ifa->ifa_ifp;
}
#ifdef MAC
- SOCK_LOCK(so);
mac_socket_create_mbuf(so, m);
- SOCK_UNLOCK(so);
#endif
/* Send packet to input processing via netisr */
netisr_queue_src(NETISR_IP, (uintptr_t)so, m);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index bbf5d8f..674c77e 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1562,9 +1562,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
TCPSTAT_INC(tcps_connects);
soisconnected(so);
#ifdef MAC
- SOCK_LOCK(so);
mac_socketpeer_set_from_mbuf(m, so);
- SOCK_UNLOCK(so);
#endif
/* Do window scaling on this connection? */
if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 8e80842..2763183 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -635,9 +635,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
goto abort2;
}
#ifdef MAC
- SOCK_LOCK(so);
mac_socketpeer_set_from_mbuf(m, so);
- SOCK_UNLOCK(so);
#endif
inp = sotoinpcb(so);
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 9f6a4a4..be366de 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -271,9 +271,7 @@ svc_vc_accept(struct socket *head, struct socket **sop)
goto done;
}
#ifdef MAC
- SOCK_LOCK(head);
error = mac_socket_check_accept(td->td_ucred, head);
- SOCK_UNLOCK(head);
if (error != 0)
goto done;
#endif
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index 6f675cb..3d2a139 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -179,6 +179,7 @@ static struct sx mac_policy_sx; /* Sleeping entry points. */
struct mac_policy_list_head mac_policy_list;
struct mac_policy_list_head mac_static_policy_list;
+u_int mac_policy_count; /* Registered policy count. */
static void mac_policy_xlock(void);
static void mac_policy_xlock_assert(void);
@@ -351,17 +352,22 @@ mac_policy_getlabeled(struct mac_policy_conf *mpc)
* requiring labels across all policies.
*/
static void
-mac_policy_updateflags(void)
+mac_policy_update(void)
{
struct mac_policy_conf *mpc;
mac_policy_xlock_assert();
mac_labeled = 0;
- LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list)
+ mac_policy_count = 0;
+ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
mac_labeled |= mac_policy_getlabeled(mpc);
- LIST_FOREACH(mpc, &mac_policy_list, mpc_list)
+ mac_policy_count++;
+ }
+ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
mac_labeled |= mac_policy_getlabeled(mpc);
+ mac_policy_count++;
+ }
}
static int
@@ -434,7 +440,7 @@ mac_policy_register(struct mac_policy_conf *mpc)
*/
if (mpc->mpc_ops->mpo_init != NULL)
(*(mpc->mpc_ops->mpo_init))(mpc);
- mac_policy_updateflags();
+ mac_policy_update();
SDT_PROBE(mac, kernel, policy, register, mpc, 0, 0, 0, 0);
printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
@@ -480,7 +486,7 @@ mac_policy_unregister(struct mac_policy_conf *mpc)
LIST_REMOVE(mpc, mpc_list);
mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
- mac_policy_updateflags();
+ mac_policy_update();
mac_policy_xunlock();
SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0);
diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h
index 45bd524..39fc404 100644
--- a/sys/security/mac/mac_internal.h
+++ b/sys/security/mac/mac_internal.h
@@ -189,6 +189,7 @@ struct label {
*/
extern struct mac_policy_list_head mac_policy_list;
extern struct mac_policy_list_head mac_static_policy_list;
+extern u_int mac_policy_count;
extern uint64_t mac_labeled;
extern struct mtx mac_ifnet_mtx;
diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c
index 25f8dae..704c60b 100644
--- a/sys/security/mac/mac_socket.c
+++ b/sys/security/mac/mac_socket.c
@@ -234,10 +234,13 @@ void
mac_socket_newconn(struct socket *oldso, struct socket *newso)
{
- SOCK_LOCK_ASSERT(oldso);
+ if (mac_policy_count == 0)
+ return;
+ SOCK_LOCK(oldso);
MAC_POLICY_PERFORM_NOSLEEP(socket_newconn, oldso, oldso->so_label,
newso, newso->so_label);
+ SOCK_UNLOCK(oldso);
}
static void
@@ -256,25 +259,30 @@ mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so)
{
struct label *label;
- SOCK_LOCK_ASSERT(so);
-
label = mac_mbuf_to_label(m);
+ SOCK_LOCK(so);
MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_mbuf, m, label, so,
so->so_peerlabel);
+ SOCK_UNLOCK(so);
}
void
mac_socketpeer_set_from_socket(struct socket *oldso, struct socket *newso)
{
+
+ if (mac_policy_count == 0)
+ return;
/*
- * XXXRW: only hold the socket lock on one at a time, as one socket
- * is the original, and one is the new. However, it's called in both
- * directions, so we can't assert the lock here currently.
+ * XXXRW: We want to hold locks on both sockets, but can't currently
+ * due to lock order -- opt to lock the socket where we're accessing
+ * so_label as it's more likely to change.
*/
+ SOCK_LOCK(oldso);
MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_socket, oldso,
oldso->so_label, newso, newso->so_peerlabel);
+ SOCK_UNLOCK(oldso);
}
void
@@ -282,12 +290,15 @@ mac_socket_create_mbuf(struct socket *so, struct mbuf *m)
{
struct label *label;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return;
label = mac_mbuf_to_label(m);
+ SOCK_LOCK(so);
MAC_POLICY_PERFORM_NOSLEEP(socket_create_mbuf, so, so->so_label, m,
label);
+ SOCK_UNLOCK(so);
}
MAC_CHECK_PROBE_DEFINE2(socket_check_accept, "struct ucred *",
@@ -298,11 +309,14 @@ mac_socket_check_accept(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_accept, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_accept, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -316,11 +330,14 @@ mac_socket_check_bind(struct ucred *cred, struct socket *so,
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_bind, cred, so, so->so_label,
sa);
MAC_CHECK_PROBE3(socket_check_bind, error, cred, so, sa);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -334,11 +351,14 @@ mac_socket_check_connect(struct ucred *cred, struct socket *so,
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_connect, cred, so,
so->so_label, sa);
MAC_CHECK_PROBE3(socket_check_connect, error, cred, so, sa);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -368,13 +388,16 @@ mac_socket_check_deliver(struct socket *so, struct mbuf *m)
struct label *label;
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
label = mac_mbuf_to_label(m);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_deliver, so, so->so_label, m,
label);
MAC_CHECK_PROBE2(socket_check_deliver, error, so, m);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -387,11 +410,14 @@ mac_socket_check_listen(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_listen, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_listen, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -404,10 +430,13 @@ mac_socket_check_poll(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_poll, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_poll, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -420,11 +449,14 @@ mac_socket_check_receive(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_receive, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_receive, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -455,10 +487,13 @@ mac_socket_check_send(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_send, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_send, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -471,10 +506,13 @@ mac_socket_check_stat(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_stat, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_stat, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
@@ -487,11 +525,14 @@ mac_socket_check_visible(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
+ SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_visible, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_visible, error, cred, so);
+ SOCK_UNLOCK(so);
return (error);
}
OpenPOWER on IntegriCloud