@@ -2355,7 +2355,13 @@ int security_socket_bind(struct socket *sock, struct sockaddr *address, int addr
int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
{
- return call_int_hook(socket_connect, 0, sock, address, addrlen);
+ int rc;
+
+ rc = call_int_hook(socket_connect, 0, sock, address, addrlen);
+ if (rc)
+ return rc;
+
+ return security_reconcile_netlbl(sock->sk);
}
int security_socket_listen(struct socket *sock, int backlog)
@@ -2370,6 +2376,12 @@ int security_socket_accept(struct socket *sock, struct socket *newsock)
int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
{
+ int rc;
+
+ rc = security_reconcile_netlbl(sock->sk);
+ if (rc)
+ return rc;
+
return call_int_hook(socket_sendmsg, 0, sock, msg, size);
}
@@ -2788,28 +2800,33 @@ int security_reconcile_netlbl(struct sock *sk)
int this_set = 0;
struct security_hook_list *hp;
+ if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
+ return 0;
+
hlist_for_each_entry(hp, &security_hook_heads.socket_netlbl_secattr,
list) {
hp->hook.socket_netlbl_secattr(sk, &this, &this_set);
+ /*
+ * If the NLTYPE has been deferred it's not
+ * possible to decide now. A decision will be made
+ * later.
+ */
+ if (this_set == NETLBL_NLTYPE_ADDRSELECT)
+ return 0;
if (this_set == 0 || this == NULL)
continue;
if (prev != NULL) {
- /*
- * Both unlabeled is easily acceptable.
- */
- if (prev_set == NETLBL_NLTYPE_UNLABELED &&
- this_set == NETLBL_NLTYPE_UNLABELED)
- continue;
/*
* The nltype being different means that
- * the secattrs aren't comparible. Except
- * that ADDRSELECT means that couldn't know
- * when the socket was created.
+ * the secattrs aren't comparible.
*/
- if (prev_set != this_set &&
- prev_set != NETLBL_NLTYPE_ADDRSELECT &&
- this_set != NETLBL_NLTYPE_ADDRSELECT)
+ if (prev_set != this_set)
return -EACCES;
+ /*
+ * Both unlabeled is easily acceptable.
+ */
+ if (this_set == NETLBL_NLTYPE_UNLABELED)
+ continue;
/*
* Count on the Netlabel system's judgement.
*/
@@ -5400,7 +5400,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
sid = SECINITSID_KERNEL;
if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
return NF_DROP;
- /* verify that this IP option works with other security modules */
+
if (sk && security_reconcile_netlbl(sk))
return NF_DROP;
@@ -88,9 +88,10 @@ static unsigned int smack_ipv4_output(void *priv,
if (rc < 0)
return NF_DROP;
ssp->smk_set = rc;
+ rc = security_reconcile_netlbl(sk);
+ if (rc < 0)
+ return NF_DROP;
}
- if (security_reconcile_netlbl(sk))
- return NF_DROP;
return NF_ACCEPT;
}
Verify that all security modules agree on the network labeling for sendmsg and connect. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- security/security.c | 43 ++++++++++++++++++++++---------- security/selinux/hooks.c | 2 +- security/smack/smack_netfilter.c | 5 ++-- 3 files changed, 34 insertions(+), 16 deletions(-)