diff options
author | Paul Moore <paul.moore@hp.com> | 2006-09-25 18:52:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-09-25 18:52:01 -0400 |
commit | 14a72f53fb1bb5d5c2bdd8cf172219519664729a (patch) | |
tree | 95a077fb9289a95c352af77f18f12e5aba3313c6 | |
parent | 597811ec167fa01c926a0957a91d9e39baa30e64 (diff) |
[NetLabel]: correct improper handling of non-NetLabel peer contexts
Fix a problem where NetLabel would always set the value of
sk_security_struct->peer_sid in selinux_netlbl_sock_graft() to the context of
the socket, causing problems when users would query the context of the
connection. This patch fixes this so that the value in
sk_security_struct->peer_sid is only set when the connection is NetLabel based,
otherwise the value is untouched.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/cipso_ipv4.h | 7 | ||||
-rw-r--r-- | include/net/netlabel.h | 8 | ||||
-rw-r--r-- | net/ipv4/cipso_ipv4.c | 48 | ||||
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 23 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 12 |
5 files changed, 82 insertions, 16 deletions
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index 59406e0dc5b2..6718452a5cd0 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h | |||
@@ -205,6 +205,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway); | |||
205 | int cipso_v4_socket_setattr(const struct socket *sock, | 205 | int cipso_v4_socket_setattr(const struct socket *sock, |
206 | const struct cipso_v4_doi *doi_def, | 206 | const struct cipso_v4_doi *doi_def, |
207 | const struct netlbl_lsm_secattr *secattr); | 207 | const struct netlbl_lsm_secattr *secattr); |
208 | int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr); | ||
208 | int cipso_v4_socket_getattr(const struct socket *sock, | 209 | int cipso_v4_socket_getattr(const struct socket *sock, |
209 | struct netlbl_lsm_secattr *secattr); | 210 | struct netlbl_lsm_secattr *secattr); |
210 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | 211 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, |
@@ -225,6 +226,12 @@ static inline int cipso_v4_socket_setattr(const struct socket *sock, | |||
225 | return -ENOSYS; | 226 | return -ENOSYS; |
226 | } | 227 | } |
227 | 228 | ||
229 | static inline int cipso_v4_sock_getattr(struct sock *sk, | ||
230 | struct netlbl_lsm_secattr *secattr) | ||
231 | { | ||
232 | return -ENOSYS; | ||
233 | } | ||
234 | |||
228 | static inline int cipso_v4_socket_getattr(const struct socket *sock, | 235 | static inline int cipso_v4_socket_getattr(const struct socket *sock, |
229 | struct netlbl_lsm_secattr *secattr) | 236 | struct netlbl_lsm_secattr *secattr) |
230 | { | 237 | { |
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index dd5780b36919..bf7b564e3540 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
@@ -238,6 +238,8 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr, | |||
238 | #ifdef CONFIG_NETLABEL | 238 | #ifdef CONFIG_NETLABEL |
239 | int netlbl_socket_setattr(const struct socket *sock, | 239 | int netlbl_socket_setattr(const struct socket *sock, |
240 | const struct netlbl_lsm_secattr *secattr); | 240 | const struct netlbl_lsm_secattr *secattr); |
241 | int netlbl_sock_getattr(struct sock *sk, | ||
242 | struct netlbl_lsm_secattr *secattr); | ||
241 | int netlbl_socket_getattr(const struct socket *sock, | 243 | int netlbl_socket_getattr(const struct socket *sock, |
242 | struct netlbl_lsm_secattr *secattr); | 244 | struct netlbl_lsm_secattr *secattr); |
243 | int netlbl_skbuff_getattr(const struct sk_buff *skb, | 245 | int netlbl_skbuff_getattr(const struct sk_buff *skb, |
@@ -250,6 +252,12 @@ static inline int netlbl_socket_setattr(const struct socket *sock, | |||
250 | return -ENOSYS; | 252 | return -ENOSYS; |
251 | } | 253 | } |
252 | 254 | ||
255 | static inline int netlbl_sock_getattr(struct sock *sk, | ||
256 | struct netlbl_lsm_secattr *secattr) | ||
257 | { | ||
258 | return -ENOSYS; | ||
259 | } | ||
260 | |||
253 | static inline int netlbl_socket_getattr(const struct socket *sock, | 261 | static inline int netlbl_socket_getattr(const struct socket *sock, |
254 | struct netlbl_lsm_secattr *secattr) | 262 | struct netlbl_lsm_secattr *secattr) |
255 | { | 263 | { |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 80a2a0911b49..a3bae2ca8acc 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -1486,43 +1486,40 @@ socket_setattr_failure: | |||
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | /** | 1488 | /** |
1489 | * cipso_v4_socket_getattr - Get the security attributes from a socket | 1489 | * cipso_v4_sock_getattr - Get the security attributes from a sock |
1490 | * @sock: the socket | 1490 | * @sk: the sock |
1491 | * @secattr: the security attributes | 1491 | * @secattr: the security attributes |
1492 | * | 1492 | * |
1493 | * Description: | 1493 | * Description: |
1494 | * Query @sock to see if there is a CIPSO option attached to the socket and if | 1494 | * Query @sk to see if there is a CIPSO option attached to the sock and if |
1495 | * there is return the CIPSO security attributes in @secattr. Returns zero on | 1495 | * there is return the CIPSO security attributes in @secattr. This function |
1496 | * success and negative values on failure. | 1496 | * requires that @sk be locked, or privately held, but it does not do any |
1497 | * locking itself. Returns zero on success and negative values on failure. | ||
1497 | * | 1498 | * |
1498 | */ | 1499 | */ |
1499 | int cipso_v4_socket_getattr(const struct socket *sock, | 1500 | int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) |
1500 | struct netlbl_lsm_secattr *secattr) | ||
1501 | { | 1501 | { |
1502 | int ret_val = -ENOMSG; | 1502 | int ret_val = -ENOMSG; |
1503 | struct sock *sk; | ||
1504 | struct inet_sock *sk_inet; | 1503 | struct inet_sock *sk_inet; |
1505 | unsigned char *cipso_ptr; | 1504 | unsigned char *cipso_ptr; |
1506 | u32 doi; | 1505 | u32 doi; |
1507 | struct cipso_v4_doi *doi_def; | 1506 | struct cipso_v4_doi *doi_def; |
1508 | 1507 | ||
1509 | sk = sock->sk; | ||
1510 | lock_sock(sk); | ||
1511 | sk_inet = inet_sk(sk); | 1508 | sk_inet = inet_sk(sk); |
1512 | if (sk_inet->opt == NULL || sk_inet->opt->cipso == 0) | 1509 | if (sk_inet->opt == NULL || sk_inet->opt->cipso == 0) |
1513 | goto socket_getattr_return; | 1510 | return -ENOMSG; |
1514 | cipso_ptr = sk_inet->opt->__data + sk_inet->opt->cipso - | 1511 | cipso_ptr = sk_inet->opt->__data + sk_inet->opt->cipso - |
1515 | sizeof(struct iphdr); | 1512 | sizeof(struct iphdr); |
1516 | ret_val = cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr); | 1513 | ret_val = cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr); |
1517 | if (ret_val == 0) | 1514 | if (ret_val == 0) |
1518 | goto socket_getattr_return; | 1515 | return ret_val; |
1519 | 1516 | ||
1520 | doi = ntohl(*(u32 *)&cipso_ptr[2]); | 1517 | doi = ntohl(*(u32 *)&cipso_ptr[2]); |
1521 | rcu_read_lock(); | 1518 | rcu_read_lock(); |
1522 | doi_def = cipso_v4_doi_getdef(doi); | 1519 | doi_def = cipso_v4_doi_getdef(doi); |
1523 | if (doi_def == NULL) { | 1520 | if (doi_def == NULL) { |
1524 | rcu_read_unlock(); | 1521 | rcu_read_unlock(); |
1525 | goto socket_getattr_return; | 1522 | return -ENOMSG; |
1526 | } | 1523 | } |
1527 | switch (cipso_ptr[6]) { | 1524 | switch (cipso_ptr[6]) { |
1528 | case CIPSO_V4_TAG_RBITMAP: | 1525 | case CIPSO_V4_TAG_RBITMAP: |
@@ -1533,8 +1530,29 @@ int cipso_v4_socket_getattr(const struct socket *sock, | |||
1533 | } | 1530 | } |
1534 | rcu_read_unlock(); | 1531 | rcu_read_unlock(); |
1535 | 1532 | ||
1536 | socket_getattr_return: | 1533 | return ret_val; |
1537 | release_sock(sk); | 1534 | } |
1535 | |||
1536 | /** | ||
1537 | * cipso_v4_socket_getattr - Get the security attributes from a socket | ||
1538 | * @sock: the socket | ||
1539 | * @secattr: the security attributes | ||
1540 | * | ||
1541 | * Description: | ||
1542 | * Query @sock to see if there is a CIPSO option attached to the socket and if | ||
1543 | * there is return the CIPSO security attributes in @secattr. Returns zero on | ||
1544 | * success and negative values on failure. | ||
1545 | * | ||
1546 | */ | ||
1547 | int cipso_v4_socket_getattr(const struct socket *sock, | ||
1548 | struct netlbl_lsm_secattr *secattr) | ||
1549 | { | ||
1550 | int ret_val; | ||
1551 | |||
1552 | lock_sock(sock->sk); | ||
1553 | ret_val = cipso_v4_sock_getattr(sock->sk, secattr); | ||
1554 | release_sock(sock->sk); | ||
1555 | |||
1538 | return ret_val; | 1556 | return ret_val; |
1539 | } | 1557 | } |
1540 | 1558 | ||
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 0fd8aaafe23f..54fb7de3c2b1 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -85,6 +85,29 @@ socket_setattr_return: | |||
85 | } | 85 | } |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * netlbl_sock_getattr - Determine the security attributes of a sock | ||
89 | * @sk: the sock | ||
90 | * @secattr: the security attributes | ||
91 | * | ||
92 | * Description: | ||
93 | * Examines the given sock to see any NetLabel style labeling has been | ||
94 | * applied to the sock, if so it parses the socket label and returns the | ||
95 | * security attributes in @secattr. Returns zero on success, negative values | ||
96 | * on failure. | ||
97 | * | ||
98 | */ | ||
99 | int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | ||
100 | { | ||
101 | int ret_val; | ||
102 | |||
103 | ret_val = cipso_v4_sock_getattr(sk, secattr); | ||
104 | if (ret_val == 0) | ||
105 | return 0; | ||
106 | |||
107 | return netlbl_unlabel_getattr(secattr); | ||
108 | } | ||
109 | |||
110 | /** | ||
88 | * netlbl_socket_getattr - Determine the security attributes of a socket | 111 | * netlbl_socket_getattr - Determine the security attributes of a socket |
89 | * @sock: the socket | 112 | * @sock: the socket |
90 | * @secattr: the security attributes | 113 | * @secattr: the security attributes |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 7eb69a602d8f..d67f7e658529 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2502,14 +2502,24 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
2502 | { | 2502 | { |
2503 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; | 2503 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; |
2504 | struct sk_security_struct *sksec = sk->sk_security; | 2504 | struct sk_security_struct *sksec = sk->sk_security; |
2505 | struct netlbl_lsm_secattr secattr; | ||
2506 | u32 nlbl_peer_sid; | ||
2505 | 2507 | ||
2506 | sksec->sclass = isec->sclass; | 2508 | sksec->sclass = isec->sclass; |
2507 | 2509 | ||
2508 | if (sk->sk_family != PF_INET) | 2510 | if (sk->sk_family != PF_INET) |
2509 | return; | 2511 | return; |
2510 | 2512 | ||
2513 | netlbl_secattr_init(&secattr); | ||
2514 | if (netlbl_sock_getattr(sk, &secattr) == 0 && | ||
2515 | selinux_netlbl_secattr_to_sid(NULL, | ||
2516 | &secattr, | ||
2517 | sksec->sid, | ||
2518 | &nlbl_peer_sid) == 0) | ||
2519 | sksec->peer_sid = nlbl_peer_sid; | ||
2520 | netlbl_secattr_destroy(&secattr, 0); | ||
2521 | |||
2511 | sksec->nlbl_state = NLBL_REQUIRE; | 2522 | sksec->nlbl_state = NLBL_REQUIRE; |
2512 | sksec->peer_sid = sksec->sid; | ||
2513 | 2523 | ||
2514 | /* Try to set the NetLabel on the socket to save time later, if we fail | 2524 | /* Try to set the NetLabel on the socket to save time later, if we fail |
2515 | * here we will pick up the pieces in later calls to | 2525 | * here we will pick up the pieces in later calls to |