Commit 14a72f53fb1bb5d5c2bdd8cf172219519664729a
Committed by
David S. Miller
1 parent
597811ec16
Exists in
master
and in
7 other branches
[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>
Showing 5 changed files with 82 additions and 16 deletions Side-by-side Diff
include/net/cipso_ipv4.h
... | ... | @@ -205,6 +205,7 @@ |
205 | 205 | int cipso_v4_socket_setattr(const struct socket *sock, |
206 | 206 | const struct cipso_v4_doi *doi_def, |
207 | 207 | const struct netlbl_lsm_secattr *secattr); |
208 | +int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr); | |
208 | 209 | int cipso_v4_socket_getattr(const struct socket *sock, |
209 | 210 | struct netlbl_lsm_secattr *secattr); |
210 | 211 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, |
... | ... | @@ -221,6 +222,12 @@ |
221 | 222 | static inline int cipso_v4_socket_setattr(const struct socket *sock, |
222 | 223 | const struct cipso_v4_doi *doi_def, |
223 | 224 | const struct netlbl_lsm_secattr *secattr) |
225 | +{ | |
226 | + return -ENOSYS; | |
227 | +} | |
228 | + | |
229 | +static inline int cipso_v4_sock_getattr(struct sock *sk, | |
230 | + struct netlbl_lsm_secattr *secattr) | |
224 | 231 | { |
225 | 232 | return -ENOSYS; |
226 | 233 | } |
include/net/netlabel.h
... | ... | @@ -238,6 +238,8 @@ |
238 | 238 | #ifdef CONFIG_NETLABEL |
239 | 239 | int netlbl_socket_setattr(const struct socket *sock, |
240 | 240 | const struct netlbl_lsm_secattr *secattr); |
241 | +int netlbl_sock_getattr(struct sock *sk, | |
242 | + struct netlbl_lsm_secattr *secattr); | |
241 | 243 | int netlbl_socket_getattr(const struct socket *sock, |
242 | 244 | struct netlbl_lsm_secattr *secattr); |
243 | 245 | int netlbl_skbuff_getattr(const struct sk_buff *skb, |
... | ... | @@ -246,6 +248,12 @@ |
246 | 248 | #else |
247 | 249 | static inline int netlbl_socket_setattr(const struct socket *sock, |
248 | 250 | const struct netlbl_lsm_secattr *secattr) |
251 | +{ | |
252 | + return -ENOSYS; | |
253 | +} | |
254 | + | |
255 | +static inline int netlbl_sock_getattr(struct sock *sk, | |
256 | + struct netlbl_lsm_secattr *secattr) | |
249 | 257 | { |
250 | 258 | return -ENOSYS; |
251 | 259 | } |
net/ipv4/cipso_ipv4.c
... | ... | @@ -1486,43 +1486,40 @@ |
1486 | 1486 | } |
1487 | 1487 | |
1488 | 1488 | /** |
1489 | - * cipso_v4_socket_getattr - Get the security attributes from a socket | |
1490 | - * @sock: the socket | |
1489 | + * cipso_v4_sock_getattr - Get the security attributes from a sock | |
1490 | + * @sk: the sock | |
1491 | 1491 | * @secattr: the security attributes |
1492 | 1492 | * |
1493 | 1493 | * Description: |
1494 | - * Query @sock to see if there is a CIPSO option attached to the socket and if | |
1495 | - * there is return the CIPSO security attributes in @secattr. Returns zero on | |
1496 | - * success and negative values on failure. | |
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. This function | |
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 | - struct netlbl_lsm_secattr *secattr) | |
1500 | +int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |
1501 | 1501 | { |
1502 | 1502 | int ret_val = -ENOMSG; |
1503 | - struct sock *sk; | |
1504 | 1503 | struct inet_sock *sk_inet; |
1505 | 1504 | unsigned char *cipso_ptr; |
1506 | 1505 | u32 doi; |
1507 | 1506 | struct cipso_v4_doi *doi_def; |
1508 | 1507 | |
1509 | - sk = sock->sk; | |
1510 | - lock_sock(sk); | |
1511 | 1508 | sk_inet = inet_sk(sk); |
1512 | 1509 | if (sk_inet->opt == NULL || sk_inet->opt->cipso == 0) |
1513 | - goto socket_getattr_return; | |
1510 | + return -ENOMSG; | |
1514 | 1511 | cipso_ptr = sk_inet->opt->__data + sk_inet->opt->cipso - |
1515 | 1512 | sizeof(struct iphdr); |
1516 | 1513 | ret_val = cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr); |
1517 | 1514 | if (ret_val == 0) |
1518 | - goto socket_getattr_return; | |
1515 | + return ret_val; | |
1519 | 1516 | |
1520 | 1517 | doi = ntohl(*(u32 *)&cipso_ptr[2]); |
1521 | 1518 | rcu_read_lock(); |
1522 | 1519 | doi_def = cipso_v4_doi_getdef(doi); |
1523 | 1520 | if (doi_def == NULL) { |
1524 | 1521 | rcu_read_unlock(); |
1525 | - goto socket_getattr_return; | |
1522 | + return -ENOMSG; | |
1526 | 1523 | } |
1527 | 1524 | switch (cipso_ptr[6]) { |
1528 | 1525 | case CIPSO_V4_TAG_RBITMAP: |
... | ... | @@ -1533,8 +1530,29 @@ |
1533 | 1530 | } |
1534 | 1531 | rcu_read_unlock(); |
1535 | 1532 | |
1536 | -socket_getattr_return: | |
1537 | - release_sock(sk); | |
1533 | + return ret_val; | |
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 | 1556 | return ret_val; |
1539 | 1557 | } |
1540 | 1558 |
net/netlabel/netlabel_kapi.c
... | ... | @@ -85,6 +85,29 @@ |
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 | 111 | * netlbl_socket_getattr - Determine the security attributes of a socket |
89 | 112 | * @sock: the socket |
90 | 113 | * @secattr: the security attributes |
security/selinux/ss/services.c
... | ... | @@ -2502,14 +2502,24 @@ |
2502 | 2502 | { |
2503 | 2503 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; |
2504 | 2504 | struct sk_security_struct *sksec = sk->sk_security; |
2505 | + struct netlbl_lsm_secattr secattr; | |
2506 | + u32 nlbl_peer_sid; | |
2505 | 2507 | |
2506 | 2508 | sksec->sclass = isec->sclass; |
2507 | 2509 | |
2508 | 2510 | if (sk->sk_family != PF_INET) |
2509 | 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 | 2522 | sksec->nlbl_state = NLBL_REQUIRE; |
2512 | - sksec->peer_sid = sksec->sid; | |
2513 | 2523 | |
2514 | 2524 | /* Try to set the NetLabel on the socket to save time later, if we fail |
2515 | 2525 | * here we will pick up the pieces in later calls to |