Commit 14a72f53fb1bb5d5c2bdd8cf172219519664729a

Authored by Paul Moore
Committed by David S. Miller
1 parent 597811ec16

[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