diff options
| -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) |
