Verify that all security modules agree on the network labeling for sendmsg and connect. Signed-off-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> --- security/security.c | 43 ++++++++++++++++++++++---------- security/selinux/hooks.c | 2 +- security/smack/smack_netfilter.c | 5 ++-- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/security/security.c b/security/security.c index 3c1d2f47b09f..dfee44ee4d19 100644 --- a/security/security.c +++ b/security/security.c @@ -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. */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4a8996b7b477..c924b454246b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -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; diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index 55cc38ae07f5..de4145c2cdd5 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -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; } -- 2.17.0