diff options
Diffstat (limited to 'security/selinux/netlabel.c')
-rw-r--r-- | security/selinux/netlabel.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6235d052338b..0364120d1ec8 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) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr | ||
105 | * @sk: the socket | ||
106 | * @sid: the SID | ||
107 | * | ||
108 | * Query the socket's cached secattr and if the SID matches the cached value | ||
109 | * return the cache, otherwise return NULL. | ||
110 | * | ||
111 | */ | ||
112 | static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( | ||
113 | const struct sock *sk, | ||
114 | u32 sid) | ||
115 | { | ||
116 | struct sk_security_struct *sksec = sk->sk_security; | ||
117 | struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; | ||
118 | |||
119 | if (secattr == NULL) | ||
120 | return NULL; | ||
121 | |||
122 | if ((secattr->flags & NETLBL_SECATTR_SECID) && | ||
123 | (secattr->attr.secid == sid)) | ||
124 | return secattr; | ||
125 | |||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | /** | ||
104 | * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache | 130 | * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache |
105 | * | 131 | * |
106 | * Description: | 132 | * Description: |
@@ -224,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, | |||
224 | struct sk_security_struct *sksec = sk->sk_security; | 250 | struct sk_security_struct *sksec = sk->sk_security; |
225 | if (sksec->nlbl_state != NLBL_REQSKB) | 251 | if (sksec->nlbl_state != NLBL_REQSKB) |
226 | return 0; | 252 | return 0; |
227 | secattr = sksec->nlbl_secattr; | 253 | secattr = selinux_netlbl_sock_getattr(sk, sid); |
228 | } | 254 | } |
229 | if (secattr == NULL) { | 255 | if (secattr == NULL) { |
230 | secattr = &secattr_storage; | 256 | secattr = &secattr_storage; |
@@ -410,6 +436,9 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
410 | sksec->nlbl_state == NLBL_CONNLABELED)) { | 436 | sksec->nlbl_state == NLBL_CONNLABELED)) { |
411 | netlbl_secattr_init(&secattr); | 437 | netlbl_secattr_init(&secattr); |
412 | lock_sock(sk); | 438 | lock_sock(sk); |
439 | /* call the netlabel function directly as we want to see the | ||
440 | * on-the-wire label that is assigned via the socket's options | ||
441 | * and not the cached netlabel/lsm attributes */ | ||
413 | rc = netlbl_sock_getattr(sk, &secattr); | 442 | rc = netlbl_sock_getattr(sk, &secattr); |
414 | release_sock(sk); | 443 | release_sock(sk); |
415 | if (rc == 0) | 444 | if (rc == 0) |