diff options
author | Venkat Yekkirala <vyekkirala@trustedcs.com> | 2006-11-08 18:04:09 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:21:33 -0500 |
commit | 6b877699c6f1efede4545bcecc367786a472eedb (patch) | |
tree | c0a60dc90578fa9f16d4496e2700bc285eab47c0 /security/selinux/hooks.c | |
parent | c1a856c9640c9ff3d70bbd8214b6a0974609eef8 (diff) |
SELinux: Return correct context for SO_PEERSEC
Fix SO_PEERSEC for tcp sockets to return the security context of
the peer (as represented by the SA from the peer) as opposed to the
SA used by the local/source socket.
Signed-off-by: Venkat Yekkirala <vyekkirala@TrustedCS.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 28ee187ed224..5bbd599a4471 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3535,8 +3535,10 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op | |||
3535 | } | 3535 | } |
3536 | else if (isec->sclass == SECCLASS_TCP_SOCKET) { | 3536 | else if (isec->sclass == SECCLASS_TCP_SOCKET) { |
3537 | peer_sid = selinux_netlbl_socket_getpeersec_stream(sock); | 3537 | peer_sid = selinux_netlbl_socket_getpeersec_stream(sock); |
3538 | if (peer_sid == SECSID_NULL) | 3538 | if (peer_sid == SECSID_NULL) { |
3539 | peer_sid = selinux_socket_getpeer_stream(sock->sk); | 3539 | ssec = sock->sk->sk_security; |
3540 | peer_sid = ssec->peer_sid; | ||
3541 | } | ||
3540 | if (peer_sid == SECSID_NULL) { | 3542 | if (peer_sid == SECSID_NULL) { |
3541 | err = -ENOPROTOOPT; | 3543 | err = -ENOPROTOOPT; |
3542 | goto out; | 3544 | goto out; |
@@ -3647,11 +3649,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3647 | return 0; | 3649 | return 0; |
3648 | } | 3650 | } |
3649 | 3651 | ||
3650 | err = selinux_xfrm_decode_session(skb, &peersid, 0); | 3652 | selinux_skb_xfrm_sid(skb, &peersid); |
3651 | BUG_ON(err); | ||
3652 | 3653 | ||
3653 | if (peersid == SECSID_NULL) { | 3654 | if (peersid == SECSID_NULL) { |
3654 | req->secid = sksec->sid; | 3655 | req->secid = sksec->sid; |
3656 | req->peer_secid = 0; | ||
3655 | return 0; | 3657 | return 0; |
3656 | } | 3658 | } |
3657 | 3659 | ||
@@ -3660,6 +3662,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3660 | return err; | 3662 | return err; |
3661 | 3663 | ||
3662 | req->secid = newsid; | 3664 | req->secid = newsid; |
3665 | req->peer_secid = peersid; | ||
3663 | return 0; | 3666 | return 0; |
3664 | } | 3667 | } |
3665 | 3668 | ||
@@ -3669,6 +3672,7 @@ static void selinux_inet_csk_clone(struct sock *newsk, | |||
3669 | struct sk_security_struct *newsksec = newsk->sk_security; | 3672 | struct sk_security_struct *newsksec = newsk->sk_security; |
3670 | 3673 | ||
3671 | newsksec->sid = req->secid; | 3674 | newsksec->sid = req->secid; |
3675 | newsksec->peer_sid = req->peer_secid; | ||
3672 | /* NOTE: Ideally, we should also get the isec->sid for the | 3676 | /* NOTE: Ideally, we should also get the isec->sid for the |
3673 | new socket in sync, but we don't have the isec available yet. | 3677 | new socket in sync, but we don't have the isec available yet. |
3674 | So we will wait until sock_graft to do it, by which | 3678 | So we will wait until sock_graft to do it, by which |
@@ -3677,6 +3681,14 @@ static void selinux_inet_csk_clone(struct sock *newsk, | |||
3677 | selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family); | 3681 | selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family); |
3678 | } | 3682 | } |
3679 | 3683 | ||
3684 | static void selinux_inet_conn_established(struct sock *sk, | ||
3685 | struct sk_buff *skb) | ||
3686 | { | ||
3687 | struct sk_security_struct *sksec = sk->sk_security; | ||
3688 | |||
3689 | selinux_skb_xfrm_sid(skb, &sksec->peer_sid); | ||
3690 | } | ||
3691 | |||
3680 | static void selinux_req_classify_flow(const struct request_sock *req, | 3692 | static void selinux_req_classify_flow(const struct request_sock *req, |
3681 | struct flowi *fl) | 3693 | struct flowi *fl) |
3682 | { | 3694 | { |
@@ -4739,6 +4751,7 @@ static struct security_operations selinux_ops = { | |||
4739 | .sock_graft = selinux_sock_graft, | 4751 | .sock_graft = selinux_sock_graft, |
4740 | .inet_conn_request = selinux_inet_conn_request, | 4752 | .inet_conn_request = selinux_inet_conn_request, |
4741 | .inet_csk_clone = selinux_inet_csk_clone, | 4753 | .inet_csk_clone = selinux_inet_csk_clone, |
4754 | .inet_conn_established = selinux_inet_conn_established, | ||
4742 | .req_classify_flow = selinux_req_classify_flow, | 4755 | .req_classify_flow = selinux_req_classify_flow, |
4743 | 4756 | ||
4744 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 4757 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |