diff --git a/security/security.c b/security/security.c
index bfe40c11f5bf..4897c68cdb71 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2496,7 +2496,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)@@ -2511,6 +2517,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);
}
@@ -3016,28 +3028,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.
*/diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 48468a4b478c..293350b672a8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5522,6 +5522,9 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
return NF_DROP;
+ if (sk && security_reconcile_netlbl(sk))
+ return NF_DROP;
+
return NF_ACCEPT;
}
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index 7b9c8d5d8408..92aeffbbb27c 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -75,7 +75,7 @@ static unsigned int smack_ipv4_output(void *priv,
const struct nf_hook_state *state)
{
struct sock *sk = skb_to_full_sk(skb);
- struct socket_smack *ssp;
+ struct socket_smack *ssp = NULL;
struct smack_known *skp;
if (!smack_checked_secmark) {@@ -84,11 +84,15 @@ static unsigned int smack_ipv4_output(void *priv,
smack_checked_secmark = true;
}
- if (smack_use_secmark && sk && smack_sock(sk)) {
+ if (sk && smack_sock(sk))
ssp = smack_sock(sk);
+
+ if (smack_use_secmark && ssp) {
skp = ssp->smk_out;
skb->secmark = skp->smk_secid;
}
+ if (sk && security_reconcile_netlbl(sk))
+ return NF_DROP;
return NF_ACCEPT;
}--
2.20.1