aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-12-03 11:36:11 -0500
committerMoyster <oysterized@gmail.com>2019-07-06 11:57:57 +0200
commit10de62e822f4717f116540f6d9563c145933dbd8 (patch)
tree59db09080626c82279c7931fd4f978da4fee4d21
parentcc798e3246f59b365b63788c084601bde0159371 (diff)
selinux: ensure that the cached NetLabel secattr matches the desired SID
In selinux_netlbl_skbuff_setsid() we leverage a cached NetLabel secattr whenever possible. However, we never check to ensure that the desired SID matches the cached NetLabel secattr. This patch checks the SID against the secattr before use and only uses the cached secattr when the SID values match. Change-Id: I25332c6fe00da1e1317c1de56386fa78fd8bb3f9 Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r--security/selinux/netlabel.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 6235d0523..0364120d1 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -101,6 +101,32 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
}
/**
+ * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr
+ * @sk: the socket
+ * @sid: the SID
+ *
+ * Query the socket's cached secattr and if the SID matches the cached value
+ * return the cache, otherwise return NULL.
+ *
+ */
+static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
+ const struct sock *sk,
+ u32 sid)
+{
+ struct sk_security_struct *sksec = sk->sk_security;
+ struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;
+
+ if (secattr == NULL)
+ return NULL;
+
+ if ((secattr->flags & NETLBL_SECATTR_SECID) &&
+ (secattr->attr.secid == sid))
+ return secattr;
+
+ return NULL;
+}
+
+/**
* selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
*
* Description:
@@ -224,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
struct sk_security_struct *sksec = sk->sk_security;
if (sksec->nlbl_state != NLBL_REQSKB)
return 0;
- secattr = sksec->nlbl_secattr;
+ secattr = selinux_netlbl_sock_getattr(sk, sid);
}
if (secattr == NULL) {
secattr = &secattr_storage;
@@ -410,6 +436,9 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
sksec->nlbl_state == NLBL_CONNLABELED)) {
netlbl_secattr_init(&secattr);
lock_sock(sk);
+ /* call the netlabel function directly as we want to see the
+ * on-the-wire label that is assigned via the socket's options
+ * and not the cached netlabel/lsm attributes */
rc = netlbl_sock_getattr(sk, &secattr);
release_sock(sk);
if (rc == 0)