From: Venkat Yekkirala <vyekkirala@trustedcs.com>
To: netdev@vger.kernel.org
Cc: selinux@tycho.nsa.gov, jmorris@namei.org, sds@tycho.nsa.gov
Subject: [PATCH 2/3] labeled-ipsec: Return correct context for SO_PEERSEC
Date: Wed, 08 Nov 2006 17:04:09 -0600 [thread overview]
Message-ID: <45526269.4010809@trustedcs.com> (raw)
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>
---
include/linux/security.h | 14 ++++++++++
include/net/request_sock.h | 1
net/ipv4/tcp_input.c | 2 +
security/dummy.c | 6 ++++
security/selinux/hooks.c | 21 ++++++++++++---
security/selinux/include/xfrm.h | 12 ++++-----
security/selinux/xfrm.c | 40 ++----------------------------
7 files changed, 49 insertions(+), 47 deletions(-)
--- net-2.6.lx1/include/linux/security.h 2006-11-08 09:40:42.000000000 -0600
+++ net-2.6/include/linux/security.h 2006-11-08 09:47:42.000000000 -0600
@@ -826,6 +826,8 @@ struct request_sock;
* Sets the openreq's sid to socket's sid with MLS portion taken from peer sid.
* @inet_csk_clone:
* Sets the new child socket's sid to the openreq sid.
+ * @inet_conn_established:
+ * Sets the connection's peersid to the secmark on skb.
* @req_classify_flow:
* Sets the flow's sid to the openreq sid.
*
@@ -1368,6 +1370,7 @@ struct security_operations {
int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req);
void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req);
+ void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb);
void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl);
#endif /* CONFIG_SECURITY_NETWORK */
@@ -2961,6 +2964,12 @@ static inline void security_inet_csk_clo
{
security_ops->inet_csk_clone(newsk, req);
}
+
+static inline void security_inet_conn_established(struct sock *sk,
+ struct sk_buff *skb)
+{
+ security_ops->inet_conn_established(sk, skb);
+}
#else /* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct socket * sock,
struct socket * other,
@@ -3110,6 +3119,11 @@ static inline void security_inet_csk_clo
const struct request_sock *req)
{
}
+
+static inline void security_inet_conn_established(struct sock *sk,
+ struct sk_buff *skb)
+{
+}
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM
--- net-2.6.lx1/include/net/request_sock.h 2006-11-08 09:38:06.000000000 -0600
+++ net-2.6/include/net/request_sock.h 2006-11-08 09:47:42.000000000 -0600
@@ -54,6 +54,7 @@ struct request_sock {
struct request_sock_ops *rsk_ops;
struct sock *sk;
u32 secid;
+ u32 peer_secid;
};
static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops)
--- net-2.6.lx1/net/ipv4/tcp_input.c 2006-11-08 09:38:06.000000000 -0600
+++ net-2.6/net/ipv4/tcp_input.c 2006-11-08 09:47:42.000000000 -0600
@@ -4230,6 +4230,8 @@ static int tcp_rcv_synsent_state_process
mb();
tcp_set_state(sk, TCP_ESTABLISHED);
+ security_inet_conn_established(sk, skb);
+
/* Make sure socket is routed, for correct metrics. */
icsk->icsk_af_ops->rebuild_header(sk);
--- net-2.6.lx1/security/dummy.c 2006-11-08 09:40:42.000000000 -0600
+++ net-2.6/security/dummy.c 2006-11-08 09:47:42.000000000 -0600
@@ -828,6 +828,11 @@ static inline void dummy_inet_csk_clone(
{
}
+static inline void dummy_inet_conn_established(struct sock *sk,
+ struct sk_buff *skb)
+{
+}
+
static inline void dummy_req_classify_flow(const struct request_sock *req,
struct flowi *fl)
{
@@ -1108,6 +1113,7 @@ void security_fixup_ops (struct security
set_to_dummy_if_null(ops, sock_graft);
set_to_dummy_if_null(ops, inet_conn_request);
set_to_dummy_if_null(ops, inet_csk_clone);
+ set_to_dummy_if_null(ops, inet_conn_established);
set_to_dummy_if_null(ops, req_classify_flow);
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM
--- net-2.6.lx1/security/selinux/include/xfrm.h 2006-11-08 09:40:42.000000000 -0600
+++ net-2.6/security/selinux/include/xfrm.h 2006-11-08 09:47:42.000000000 -0600
@@ -39,7 +39,6 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s
struct avc_audit_data *ad);
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
struct avc_audit_data *ad);
-u32 selinux_socket_getpeer_stream(struct sock *sk);
u32 selinux_socket_getpeer_dgram(struct sk_buff *skb);
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
#else
@@ -55,11 +54,6 @@ static inline int selinux_xfrm_postroute
return 0;
}
-static inline int selinux_socket_getpeer_stream(struct sock *sk)
-{
- return SECSID_NULL;
-}
-
static inline int selinux_socket_getpeer_dgram(struct sk_buff *skb)
{
return SECSID_NULL;
@@ -71,4 +65,10 @@ static inline int selinux_xfrm_decode_se
}
#endif
+static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
+{
+ int err = selinux_xfrm_decode_session(skb, sid, 0);
+ BUG_ON(err);
+}
+
#endif /* _SELINUX_XFRM_H_ */
--- net-2.6.lx1/security/selinux/hooks.c 2006-11-08 09:38:06.000000000 -0600
+++ net-2.6/security/selinux/hooks.c 2006-11-08 09:47:42.000000000 -0600
@@ -3534,8 +3534,10 @@ static int selinux_socket_getpeersec_str
}
else if (isec->sclass == SECCLASS_TCP_SOCKET) {
peer_sid = selinux_netlbl_socket_getpeersec_stream(sock);
- if (peer_sid == SECSID_NULL)
- peer_sid = selinux_socket_getpeer_stream(sock->sk);
+ if (peer_sid == SECSID_NULL) {
+ ssec = sock->sk->sk_security;
+ peer_sid = ssec->peer_sid;
+ }
if (peer_sid == SECSID_NULL) {
err = -ENOPROTOOPT;
goto out;
@@ -3646,11 +3648,11 @@ static int selinux_inet_conn_request(str
return 0;
}
- err = selinux_xfrm_decode_session(skb, &peersid, 0);
- BUG_ON(err);
+ selinux_skb_xfrm_sid(skb, &peersid);
if (peersid == SECSID_NULL) {
req->secid = sksec->sid;
+ req->peer_secid = 0;
return 0;
}
@@ -3659,6 +3661,7 @@ static int selinux_inet_conn_request(str
return err;
req->secid = newsid;
+ req->peer_secid = peersid;
return 0;
}
@@ -3668,6 +3671,7 @@ static void selinux_inet_csk_clone(struc
struct sk_security_struct *newsksec = newsk->sk_security;
newsksec->sid = req->secid;
+ newsksec->peer_sid = req->peer_secid;
/* NOTE: Ideally, we should also get the isec->sid for the
new socket in sync, but we don't have the isec available yet.
So we will wait until sock_graft to do it, by which
@@ -3676,6 +3680,14 @@ static void selinux_inet_csk_clone(struc
selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family);
}
+static void selinux_inet_conn_established(struct sock *sk,
+ struct sk_buff *skb)
+{
+ struct sk_security_struct *sksec = sk->sk_security;
+
+ selinux_skb_xfrm_sid(skb, &sksec->peer_sid);
+}
+
static void selinux_req_classify_flow(const struct request_sock *req,
struct flowi *fl)
{
@@ -4738,6 +4750,7 @@ static struct security_operations selinu
.sock_graft = selinux_sock_graft,
.inet_conn_request = selinux_inet_conn_request,
.inet_csk_clone = selinux_inet_csk_clone,
+ .inet_conn_established = selinux_inet_conn_established,
.req_classify_flow = selinux_req_classify_flow,
#ifdef CONFIG_SECURITY_NETWORK_XFRM
--- net-2.6.lx1/security/selinux/xfrm.c 2006-11-08 09:40:42.000000000 -0600
+++ net-2.6/security/selinux/xfrm.c 2006-11-08 09:47:42.000000000 -0600
@@ -184,7 +184,8 @@ int selinux_xfrm_flow_state_match(struct
}
/*
- * LSM hook implementation that determines the sid for the session.
+ * LSM hook implementation that checks and/or returns the xfrm sid for the
+ * incoming packet.
*/
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
@@ -403,43 +404,8 @@ void selinux_xfrm_state_free(struct xfrm
}
/*
- * SELinux internal function to retrieve the context of a connected
- * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security
- * association used to connect to the remote socket.
- *
- * Retrieve via getsockopt SO_PEERSEC.
- */
-u32 selinux_socket_getpeer_stream(struct sock *sk)
-{
- struct dst_entry *dst, *dst_test;
- u32 peer_sid = SECSID_NULL;
-
- if (sk->sk_state != TCP_ESTABLISHED)
- goto out;
-
- dst = sk_dst_get(sk);
- if (!dst)
- goto out;
-
- for (dst_test = dst; dst_test != 0;
- dst_test = dst_test->child) {
- struct xfrm_state *x = dst_test->xfrm;
-
- if (x && selinux_authorizable_xfrm(x)) {
- struct xfrm_sec_ctx *ctx = x->security;
- peer_sid = ctx->ctx_sid;
- break;
- }
- }
- dst_release(dst);
-
-out:
- return peer_sid;
-}
-
-/*
* SELinux internal function to retrieve the context of a UDP packet
- * based on its security association used to connect to the remote socket.
+ * based on its security association.
*
* Retrieve via setsockopt IP_PASSSEC and recvmsg with control message
* type SCM_SECURITY.
reply other threads:[~2006-11-08 23:04 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45526269.4010809@trustedcs.com \
--to=vyekkirala@trustedcs.com \
--cc=jmorris@namei.org \
--cc=netdev@vger.kernel.org \
--cc=sds@tycho.nsa.gov \
--cc=selinux@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).