netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Labeled networking patches for 2.6.30
@ 2009-03-27 21:10 Paul Moore
  2009-03-27 21:10 ` [PATCH 1/6] lsm: Relocate the IPv4 security_inet_conn_request() hooks Paul Moore
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:10 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

This patchset wraps up all the new labeled networking bits for 2.6.30.  This
is mostly a fixup/cleanup release with the main focus being to correct the
TCP labeling of both SELinux and Smack; expect some of this to get backported
to the -stable trees but there will need to be a bit of rework first so it
may take a few weeks for that to happen.  Other than the TCP issue there is a
new Smack feature to configure CIPSO aware hosts in "/smack/netlabel" which
should make the host/network label configuration much more flexible.  The last
change is to get rid of the security_socket_post_accept() hook which isn't
currently being used by anything in-tree and seems to act as a magnet for
bad ideas; if things change we can always add it back later.

The two Smack related patches, "Add a new -CIPSO option ..." and "Cleanup the
Smack/NetLabel code ..." were ACK'd by Casey but had to be modified slightly
today to address a last minute kernel oops and a minor merge collision with
patches already in the security-testing-2.6 tree.  I imagine when Casey sees
this he will ACK them again but I removed his ACK in the meantime since the
patches did change, however slightly.

I did run yesterday's patches (without the kernel oops fix) against Linus' tree
from yesterday on my test systems without problem but I'm having a problem
getting a clean kernel build using Linus' current tree so I'm unable to do a
sanity check at present.  That said, I am able to build the relevant code
sections/modules without issue and am fairly confident there should not be any
issues.

---

Etienne Basset (1):
      smack: Add a new '-CIPSO' option to the network address label configuration

Paul Moore (5):
      netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections
      lsm: Remove the socket_post_accept() hook
      selinux: Remove the "compat_net" compatibility code
      netlabel: Label incoming TCP connections correctly in SELinux
      lsm: Relocate the IPv4 security_inet_conn_request() hooks


 Documentation/Smack.txt                    |   42 ++++
 Documentation/feature-removal-schedule.txt |   11 -
 Documentation/kernel-parameters.txt        |    9 -
 include/linux/security.h                   |   13 -
 include/net/cipso_ipv4.h                   |   17 ++
 include/net/netlabel.h                     |   17 ++
 net/ipv4/cipso_ipv4.c                      |  130 ++++++++++++-
 net/ipv4/syncookies.c                      |    9 +
 net/ipv4/tcp_ipv4.c                        |    7 -
 net/netlabel/netlabel_kapi.c               |  165 +++++++++++++++--
 net/socket.c                               |    2 
 security/capability.c                      |    5 -
 security/security.c                        |    5 -
 security/selinux/hooks.c                   |  207 ++-------------------
 security/selinux/include/netlabel.h        |   27 +--
 security/selinux/netlabel.c                |  186 +++++--------------
 security/selinux/selinuxfs.c               |   68 -------
 security/smack/smack.h                     |    4 
 security/smack/smack_access.c              |    3 
 security/smack/smack_lsm.c                 |  271 ++++++++++++++++------------
 security/smack/smackfs.c                   |   38 +++-
 21 files changed, 618 insertions(+), 618 deletions(-)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/6] lsm: Relocate the IPv4 security_inet_conn_request() hooks
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
@ 2009-03-27 21:10 ` Paul Moore
  2009-03-27 21:10 ` [PATCH 2/6] netlabel: Label incoming TCP connections correctly in SELinux Paul Moore
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:10 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

The current placement of the security_inet_conn_request() hooks do not allow
individual LSMs to override the IP options of the connection's request_sock.
This is a problem as both SELinux and Smack have the ability to use labeled
networking protocols which make use of IP options to carry security attributes
and the inability to set the IP options at the start of the TCP handshake is
problematic.

This patch moves the IPv4 security_inet_conn_request() hooks past the code
where the request_sock's IP options are set/reset so that the LSM can safely
manipulate the IP options as needed.  This patch intentionally does not change
the related IPv6 hooks as IPv6 based labeling protocols which use IPv6 options
are not currently implemented, once they are we will have a better idea of
the correct placement for the IPv6 hooks.

Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: David S. Miller <davem@davemloft.net>
---

 net/ipv4/syncookies.c |    9 +++++----
 net/ipv4/tcp_ipv4.c   |    7 ++++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index d346c22..b35a950 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -288,10 +288,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 	if (!req)
 		goto out;
 
-	if (security_inet_conn_request(sk, skb, req)) {
-		reqsk_free(req);
-		goto out;
-	}
 	ireq = inet_rsk(req);
 	treq = tcp_rsk(req);
 	treq->rcv_isn		= ntohl(th->seq) - 1;
@@ -322,6 +318,11 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 		}
 	}
 
+	if (security_inet_conn_request(sk, skb, req)) {
+		reqsk_free(req);
+		goto out;
+	}
+
 	req->expires	= 0UL;
 	req->retrans	= 0;
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d0a3148..5d427f8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1230,14 +1230,15 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 
 	tcp_openreq_init(req, &tmp_opt, skb);
 
-	if (security_inet_conn_request(sk, skb, req))
-		goto drop_and_free;
-
 	ireq = inet_rsk(req);
 	ireq->loc_addr = daddr;
 	ireq->rmt_addr = saddr;
 	ireq->no_srccheck = inet_sk(sk)->transparent;
 	ireq->opt = tcp_v4_save_options(sk, skb);
+
+	if (security_inet_conn_request(sk, skb, req))
+		goto drop_and_free;
+
 	if (!want_cookie)
 		TCP_ECN_create_request(req, tcp_hdr(skb));
 


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/6] netlabel: Label incoming TCP connections correctly in SELinux
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
  2009-03-27 21:10 ` [PATCH 1/6] lsm: Relocate the IPv4 security_inet_conn_request() hooks Paul Moore
@ 2009-03-27 21:10 ` Paul Moore
  2009-03-28  3:03   ` Casey Schaufler
  2009-03-27 21:10 ` [PATCH 3/6] selinux: Remove the "compat_net" compatibility code Paul Moore
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:10 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

The current NetLabel/SELinux behavior for incoming TCP connections works but
only through a series of happy coincidences that rely on the limited nature of
standard CIPSO (only able to convey MLS attributes) and the write equality
imposed by the SELinux MLS constraints.  The problem is that network sockets
created as the result of an incoming TCP connection were not on-the-wire
labeled based on the security attributes of the parent socket but rather based
on the wire label of the remote peer.  The issue had to do with how IP options
were managed as part of the network stack and where the LSM hooks were in
relation to the code which set the IP options on these newly created child
sockets.  While NetLabel/SELinux did correctly set the socket's on-the-wire
label it was promptly cleared by the network stack and reset based on the IP
options of the remote peer.

This patch, in conjunction with a prior patch that adjusted the LSM hook
locations, works to set the correct on-the-wire label format for new incoming
connections through the security_inet_conn_request() hook.  Besides the
correct behavior there are many advantages to this change, the most significant
is that all of the NetLabel socket labeling code in SELinux now lives in hooks
which can return error codes to the core stack which allows us to finally get
ride of the selinux_netlbl_inode_permission() logic which greatly simplfies
the NetLabel/SELinux glue code.  In the process of developing this patch I
also ran into a small handful of AF_INET6 cleanliness issues that have been
fixed which should make the code safer and easier to extend in the future.

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 include/net/cipso_ipv4.h            |   17 +++
 include/net/netlabel.h              |   12 ++
 net/ipv4/cipso_ipv4.c               |  130 ++++++++++++++++++++++--
 net/netlabel/netlabel_kapi.c        |  152 +++++++++++++++++++++++++----
 security/selinux/hooks.c            |   54 +++-------
 security/selinux/include/netlabel.h |   27 ++---
 security/selinux/netlabel.c         |  186 ++++++++++-------------------------
 security/smack/smack_lsm.c          |    2 
 8 files changed, 360 insertions(+), 220 deletions(-)

diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h
index bedc7f6..abd4436 100644
--- a/include/net/cipso_ipv4.h
+++ b/include/net/cipso_ipv4.h
@@ -40,6 +40,7 @@
 #include <linux/net.h>
 #include <linux/skbuff.h>
 #include <net/netlabel.h>
+#include <net/request_sock.h>
 #include <asm/atomic.h>
 
 /* known doi values */
@@ -215,6 +216,10 @@ int cipso_v4_sock_setattr(struct sock *sk,
 			  const struct netlbl_lsm_secattr *secattr);
 void cipso_v4_sock_delattr(struct sock *sk);
 int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
+int cipso_v4_req_setattr(struct request_sock *req,
+			 const struct cipso_v4_doi *doi_def,
+			 const struct netlbl_lsm_secattr *secattr);
+void cipso_v4_req_delattr(struct request_sock *req);
 int cipso_v4_skbuff_setattr(struct sk_buff *skb,
 			    const struct cipso_v4_doi *doi_def,
 			    const struct netlbl_lsm_secattr *secattr);
@@ -247,6 +252,18 @@ static inline int cipso_v4_sock_getattr(struct sock *sk,
 	return -ENOSYS;
 }
 
+static inline int cipso_v4_req_setattr(struct request_sock *req,
+				       const struct cipso_v4_doi *doi_def,
+				       const struct netlbl_lsm_secattr *secattr)
+{
+	return -ENOSYS;
+}
+
+static inline void cipso_v4_req_delattr(struct request_sock *req)
+{
+	return;
+}
+
 static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
 				      const struct cipso_v4_doi *doi_def,
 				      const struct netlbl_lsm_secattr *secattr)
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 749011e..bdb10e5 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -36,6 +36,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/netlink.h>
+#include <net/request_sock.h>
 #include <asm/atomic.h>
 
 struct cipso_v4_doi;
@@ -406,6 +407,7 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
  */
 int netlbl_enabled(void);
 int netlbl_sock_setattr(struct sock *sk,
+			u16 family,
 			const struct netlbl_lsm_secattr *secattr);
 void netlbl_sock_delattr(struct sock *sk);
 int netlbl_sock_getattr(struct sock *sk,
@@ -413,6 +415,8 @@ int netlbl_sock_getattr(struct sock *sk,
 int netlbl_conn_setattr(struct sock *sk,
 			struct sockaddr *addr,
 			const struct netlbl_lsm_secattr *secattr);
+int netlbl_req_setattr(struct request_sock *req,
+		       const struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_setattr(struct sk_buff *skb,
 			  u16 family,
 			  const struct netlbl_lsm_secattr *secattr);
@@ -519,7 +523,8 @@ static inline int netlbl_enabled(void)
 	return 0;
 }
 static inline int netlbl_sock_setattr(struct sock *sk,
-				     const struct netlbl_lsm_secattr *secattr)
+				      u16 family,
+				      const struct netlbl_lsm_secattr *secattr)
 {
 	return -ENOSYS;
 }
@@ -537,6 +542,11 @@ static inline int netlbl_conn_setattr(struct sock *sk,
 {
 	return -ENOSYS;
 }
+static inline int netlbl_req_setattr(struct request_sock *req,
+				     const struct netlbl_lsm_secattr *secattr)
+{
+	return -ENOSYS;
+}
 static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
 				      u16 family,
 				      const struct netlbl_lsm_secattr *secattr)
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 7bc9929..039cc1f 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1942,23 +1942,85 @@ socket_setattr_failure:
 }
 
 /**
- * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
- * @sk: the socket
+ * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket
+ * @req: the connection request socket
+ * @doi_def: the CIPSO DOI to use
+ * @secattr: the specific security attributes of the socket
  *
  * Description:
- * Removes the CIPSO option from a socket, if present.
+ * Set the CIPSO option on the given socket using the DOI definition and
+ * security attributes passed to the function.  Returns zero on success and
+ * negative values on failure.
  *
  */
-void cipso_v4_sock_delattr(struct sock *sk)
+int cipso_v4_req_setattr(struct request_sock *req,
+			 const struct cipso_v4_doi *doi_def,
+			 const struct netlbl_lsm_secattr *secattr)
 {
-	u8 hdr_delta;
-	struct ip_options *opt;
-	struct inet_sock *sk_inet;
+	int ret_val = -EPERM;
+	unsigned char *buf = NULL;
+	u32 buf_len;
+	u32 opt_len;
+	struct ip_options *opt = NULL;
+	struct inet_request_sock *req_inet;
 
-	sk_inet = inet_sk(sk);
-	opt = sk_inet->opt;
-	if (opt == NULL || opt->cipso == 0)
-		return;
+	/* We allocate the maximum CIPSO option size here so we are probably
+	 * being a little wasteful, but it makes our life _much_ easier later
+	 * on and after all we are only talking about 40 bytes. */
+	buf_len = CIPSO_V4_OPT_LEN_MAX;
+	buf = kmalloc(buf_len, GFP_ATOMIC);
+	if (buf == NULL) {
+		ret_val = -ENOMEM;
+		goto req_setattr_failure;
+	}
+
+	ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
+	if (ret_val < 0)
+		goto req_setattr_failure;
+	buf_len = ret_val;
+
+	/* We can't use ip_options_get() directly because it makes a call to
+	 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
+	 * we won't always have CAP_NET_RAW even though we _always_ want to
+	 * set the IPOPT_CIPSO option. */
+	opt_len = (buf_len + 3) & ~3;
+	opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
+	if (opt == NULL) {
+		ret_val = -ENOMEM;
+		goto req_setattr_failure;
+	}
+	memcpy(opt->__data, buf, buf_len);
+	opt->optlen = opt_len;
+	opt->cipso = sizeof(struct iphdr);
+	kfree(buf);
+	buf = NULL;
+
+	req_inet = inet_rsk(req);
+	opt = xchg(&req_inet->opt, opt);
+	kfree(opt);
+
+	return 0;
+
+req_setattr_failure:
+	kfree(buf);
+	kfree(opt);
+	return ret_val;
+}
+
+/**
+ * cipso_v4_delopt - Delete the CIPSO option from a set of IP options
+ * @opt_ptr: IP option pointer
+ *
+ * Description:
+ * Deletes the CIPSO IP option from a set of IP options and makes the necessary
+ * adjustments to the IP option structure.  Returns zero on success, negative
+ * values on failure.
+ *
+ */
+int cipso_v4_delopt(struct ip_options **opt_ptr)
+{
+	int hdr_delta = 0;
+	struct ip_options *opt = *opt_ptr;
 
 	if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
 		u8 cipso_len;
@@ -2003,11 +2065,34 @@ void cipso_v4_sock_delattr(struct sock *sk)
 	} else {
 		/* only the cipso option was present on the socket so we can
 		 * remove the entire option struct */
-		sk_inet->opt = NULL;
+		*opt_ptr = NULL;
 		hdr_delta = opt->optlen;
 		kfree(opt);
 	}
 
+	return hdr_delta;
+}
+
+/**
+ * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
+ * @sk: the socket
+ *
+ * Description:
+ * Removes the CIPSO option from a socket, if present.
+ *
+ */
+void cipso_v4_sock_delattr(struct sock *sk)
+{
+	int hdr_delta;
+	struct ip_options *opt;
+	struct inet_sock *sk_inet;
+
+	sk_inet = inet_sk(sk);
+	opt = sk_inet->opt;
+	if (opt == NULL || opt->cipso == 0)
+		return;
+
+	hdr_delta = cipso_v4_delopt(&sk_inet->opt);
 	if (sk_inet->is_icsk && hdr_delta > 0) {
 		struct inet_connection_sock *sk_conn = inet_csk(sk);
 		sk_conn->icsk_ext_hdr_len -= hdr_delta;
@@ -2016,6 +2101,27 @@ void cipso_v4_sock_delattr(struct sock *sk)
 }
 
 /**
+ * cipso_v4_req_delattr - Delete the CIPSO option from a request socket
+ * @reg: the request socket
+ *
+ * Description:
+ * Removes the CIPSO option from a request socket, if present.
+ *
+ */
+void cipso_v4_req_delattr(struct request_sock *req)
+{
+	struct ip_options *opt;
+	struct inet_request_sock *req_inet;
+
+	req_inet = inet_rsk(req);
+	opt = req_inet->opt;
+	if (opt == NULL || opt->cipso == 0)
+		return;
+
+	cipso_v4_delopt(&req_inet->opt);
+}
+
+/**
  * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
  * @cipso: the CIPSO v4 option
  * @secattr: the security attributes
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index fd9229d..cae2f5f 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -619,8 +619,9 @@ int netlbl_enabled(void)
 }
 
 /**
- * netlbl_socket_setattr - Label a socket using the correct protocol
+ * netlbl_sock_setattr - Label a socket using the correct protocol
  * @sk: the socket to label
+ * @family: protocol family
  * @secattr: the security attributes
  *
  * Description:
@@ -633,29 +634,45 @@ int netlbl_enabled(void)
  *
  */
 int netlbl_sock_setattr(struct sock *sk,
+			u16 family,
 			const struct netlbl_lsm_secattr *secattr)
 {
-	int ret_val = -ENOENT;
+	int ret_val;
 	struct netlbl_dom_map *dom_entry;
 
 	rcu_read_lock();
 	dom_entry = netlbl_domhsh_getentry(secattr->domain);
-	if (dom_entry == NULL)
+	if (dom_entry == NULL) {
+		ret_val = -ENOENT;
 		goto socket_setattr_return;
-	switch (dom_entry->type) {
-	case NETLBL_NLTYPE_ADDRSELECT:
-		ret_val = -EDESTADDRREQ;
-		break;
-	case NETLBL_NLTYPE_CIPSOV4:
-		ret_val = cipso_v4_sock_setattr(sk,
-						dom_entry->type_def.cipsov4,
-						secattr);
+	}
+	switch (family) {
+	case AF_INET:
+		switch (dom_entry->type) {
+		case NETLBL_NLTYPE_ADDRSELECT:
+			ret_val = -EDESTADDRREQ;
+			break;
+		case NETLBL_NLTYPE_CIPSOV4:
+			ret_val = cipso_v4_sock_setattr(sk,
+						    dom_entry->type_def.cipsov4,
+						    secattr);
+			break;
+		case NETLBL_NLTYPE_UNLABELED:
+			ret_val = 0;
+			break;
+		default:
+			ret_val = -ENOENT;
+		}
 		break;
-	case NETLBL_NLTYPE_UNLABELED:
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		/* since we don't support any IPv6 labeling protocols right
+		 * now we can optimize everything away until we do */
 		ret_val = 0;
 		break;
+#endif /* IPv6 */
 	default:
-		ret_val = -ENOENT;
+		ret_val = -EPROTONOSUPPORT;
 	}
 
 socket_setattr_return:
@@ -689,9 +706,25 @@ void netlbl_sock_delattr(struct sock *sk)
  * on failure.
  *
  */
-int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
+int netlbl_sock_getattr(struct sock *sk,
+			struct netlbl_lsm_secattr *secattr)
 {
-	return cipso_v4_sock_getattr(sk, secattr);
+	int ret_val;
+
+	switch (sk->sk_family) {
+	case AF_INET:
+		ret_val = cipso_v4_sock_getattr(sk, secattr);
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		ret_val = -ENOMSG;
+		break;
+#endif /* IPv6 */
+	default:
+		ret_val = -EPROTONOSUPPORT;
+	}
+
+	return ret_val;
 }
 
 /**
@@ -748,7 +781,7 @@ int netlbl_conn_setattr(struct sock *sk,
 		break;
 #endif /* IPv6 */
 	default:
-		ret_val = 0;
+		ret_val = -EPROTONOSUPPORT;
 	}
 
 conn_setattr_return:
@@ -757,6 +790,77 @@ conn_setattr_return:
 }
 
 /**
+ * netlbl_req_setattr - Label a request socket using the correct protocol
+ * @req: the request socket to label
+ * @secattr: the security attributes
+ *
+ * Description:
+ * Attach the correct label to the given socket using the security attributes
+ * specified in @secattr.  Returns zero on success, negative values on failure.
+ *
+ */
+int netlbl_req_setattr(struct request_sock *req,
+		       const struct netlbl_lsm_secattr *secattr)
+{
+	int ret_val;
+	struct netlbl_dom_map *dom_entry;
+	struct netlbl_domaddr4_map *af4_entry;
+	u32 proto_type;
+	struct cipso_v4_doi *proto_cv4;
+
+	rcu_read_lock();
+	dom_entry = netlbl_domhsh_getentry(secattr->domain);
+	if (dom_entry == NULL) {
+		ret_val = -ENOENT;
+		goto req_setattr_return;
+	}
+	switch (req->rsk_ops->family) {
+	case AF_INET:
+		if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) {
+			struct inet_request_sock *req_inet = inet_rsk(req);
+			af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
+							    req_inet->rmt_addr);
+			if (af4_entry == NULL) {
+				ret_val = -ENOENT;
+				goto req_setattr_return;
+			}
+			proto_type = af4_entry->type;
+			proto_cv4 = af4_entry->type_def.cipsov4;
+		} else {
+			proto_type = dom_entry->type;
+			proto_cv4 = dom_entry->type_def.cipsov4;
+		}
+		switch (proto_type) {
+		case NETLBL_NLTYPE_CIPSOV4:
+			ret_val = cipso_v4_req_setattr(req, proto_cv4, secattr);
+			break;
+		case NETLBL_NLTYPE_UNLABELED:
+			/* just delete the protocols we support for right now
+			 * but we could remove other protocols if needed */
+			cipso_v4_req_delattr(req);
+			ret_val = 0;
+			break;
+		default:
+			ret_val = -ENOENT;
+		}
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		/* since we don't support any IPv6 labeling protocols right
+		 * now we can optimize everything away until we do */
+		ret_val = 0;
+		break;
+#endif /* IPv6 */
+	default:
+		ret_val = -EPROTONOSUPPORT;
+	}
+
+req_setattr_return:
+	rcu_read_unlock();
+	return ret_val;
+}
+
+/**
  * netlbl_skbuff_setattr - Label a packet using the correct protocol
  * @skb: the packet
  * @family: protocol family
@@ -808,7 +912,7 @@ int netlbl_skbuff_setattr(struct sk_buff *skb,
 		break;
 #endif /* IPv6 */
 	default:
-		ret_val = 0;
+		ret_val = -EPROTONOSUPPORT;
 	}
 
 skbuff_setattr_return:
@@ -833,9 +937,17 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
 			  u16 family,
 			  struct netlbl_lsm_secattr *secattr)
 {
-	if (CIPSO_V4_OPTEXIST(skb) &&
-	    cipso_v4_skbuff_getattr(skb, secattr) == 0)
-		return 0;
+	switch (family) {
+	case AF_INET:
+		if (CIPSO_V4_OPTEXIST(skb) &&
+		    cipso_v4_skbuff_getattr(skb, secattr) == 0)
+			return 0;
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		break;
+#endif /* IPv6 */
+	}
 
 	return netlbl_unlabel_getattr(skb, family, secattr);
 }
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7c52ba2..ee2e781 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -311,7 +311,7 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 	ssec->sid = SECINITSID_UNLABELED;
 	sk->sk_security = ssec;
 
-	selinux_netlbl_sk_security_reset(ssec, family);
+	selinux_netlbl_sk_security_reset(ssec);
 
 	return 0;
 }
@@ -2945,7 +2945,6 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
 static int selinux_revalidate_file_permission(struct file *file, int mask)
 {
 	const struct cred *cred = current_cred();
-	int rc;
 	struct inode *inode = file->f_path.dentry->d_inode;
 
 	if (!mask) {
@@ -2957,29 +2956,15 @@ static int selinux_revalidate_file_permission(struct file *file, int mask)
 	if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
 		mask |= MAY_APPEND;
 
-	rc = file_has_perm(cred, file,
-			   file_mask_to_av(inode->i_mode, mask));
-	if (rc)
-		return rc;
-
-	return selinux_netlbl_inode_permission(inode, mask);
+	return file_has_perm(cred, file,
+			     file_mask_to_av(inode->i_mode, mask));
 }
 
 static int selinux_file_permission(struct file *file, int mask)
 {
-	struct inode *inode = file->f_path.dentry->d_inode;
-	struct file_security_struct *fsec = file->f_security;
-	struct inode_security_struct *isec = inode->i_security;
-	u32 sid = current_sid();
-
-	if (!mask) {
+	if (!mask)
 		/* No permission to check.  Existence test. */
 		return 0;
-	}
-
-	if (sid == fsec->sid && fsec->isid == isec->sid
-	    && fsec->pseqno == avc_policy_seqno())
-		return selinux_netlbl_inode_permission(inode, mask);
 
 	return selinux_revalidate_file_permission(file, mask);
 }
@@ -3723,7 +3708,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
 		sksec = sock->sk->sk_security;
 		sksec->sid = isec->sid;
 		sksec->sclass = isec->sclass;
-		err = selinux_netlbl_socket_post_create(sock);
+		err = selinux_netlbl_socket_post_create(sock->sk, family);
 	}
 
 	return err;
@@ -3914,13 +3899,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
 static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
 				  int size)
 {
-	int rc;
-
-	rc = socket_has_perm(current, sock, SOCKET__WRITE);
-	if (rc)
-		return rc;
-
-	return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE);
+	return socket_has_perm(current, sock, SOCKET__WRITE);
 }
 
 static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
@@ -4304,7 +4283,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
 	newssec->peer_sid = ssec->peer_sid;
 	newssec->sclass = ssec->sclass;
 
-	selinux_netlbl_sk_security_reset(newssec, newsk->sk_family);
+	selinux_netlbl_sk_security_reset(newssec);
 }
 
 static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -4348,16 +4327,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 	if (peersid == SECSID_NULL) {
 		req->secid = sksec->sid;
 		req->peer_secid = SECSID_NULL;
-		return 0;
+	} else {
+		err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
+		if (err)
+			return err;
+		req->secid = newsid;
+		req->peer_secid = peersid;
 	}
 
-	err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
-	if (err)
-		return err;
-
-	req->secid = newsid;
-	req->peer_secid = peersid;
-	return 0;
+	return selinux_netlbl_inet_conn_request(req, family);
 }
 
 static void selinux_inet_csk_clone(struct sock *newsk,
@@ -4374,7 +4352,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
 
 	/* We don't need to take any sort of lock here as we are the only
 	 * thread with access to newsksec */
-	selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family);
+	selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
 }
 
 static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
@@ -4387,8 +4365,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
 		family = PF_INET;
 
 	selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
-
-	selinux_netlbl_inet_conn_established(sk, family);
 }
 
 static void selinux_req_classify_flow(const struct request_sock *req,
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index b913c8d..b4b5b9b 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -32,6 +32,7 @@
 #include <linux/net.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <net/request_sock.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -42,8 +43,7 @@ void selinux_netlbl_cache_invalidate(void);
 void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
 
 void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
-void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
-				      int family);
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec);
 
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 				 u16 family,
@@ -53,9 +53,9 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 				 u16 family,
 				 u32 sid);
 
-void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family);
-int selinux_netlbl_socket_post_create(struct socket *sock);
-int selinux_netlbl_inode_permission(struct inode *inode, int mask);
+int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
+void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
+int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
 int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
 				struct sk_buff *skb,
 				u16 family,
@@ -85,8 +85,7 @@ static inline void selinux_netlbl_sk_security_free(
 }
 
 static inline void selinux_netlbl_sk_security_reset(
-					       struct sk_security_struct *ssec,
-					       int family)
+					       struct sk_security_struct *ssec)
 {
 	return;
 }
@@ -113,17 +112,17 @@ static inline int selinux_netlbl_conn_setsid(struct sock *sk,
 	return 0;
 }
 
-static inline void selinux_netlbl_inet_conn_established(struct sock *sk,
-							u16 family)
+static inline int selinux_netlbl_inet_conn_request(struct request_sock *req,
+						   u16 family)
 {
-	return;
+	return 0;
 }
-static inline int selinux_netlbl_socket_post_create(struct socket *sock)
+static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
 {
-	return 0;
+	return;
 }
-static inline int selinux_netlbl_inode_permission(struct inode *inode,
-						  int mask)
+static inline int selinux_netlbl_socket_post_create(struct sock *sk,
+						    u16 family)
 {
 	return 0;
 }
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 350794a..2e98441 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -100,41 +100,6 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
 }
 
 /**
- * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
- * @sk: the socket to label
- *
- * Description:
- * Attempt to label a socket using the NetLabel mechanism.  Returns zero values
- * on success, negative values on failure.
- *
- */
-static int selinux_netlbl_sock_setsid(struct sock *sk)
-{
-	int rc;
-	struct sk_security_struct *sksec = sk->sk_security;
-	struct netlbl_lsm_secattr *secattr;
-
-	if (sksec->nlbl_state != NLBL_REQUIRE)
-		return 0;
-
-	secattr = selinux_netlbl_sock_genattr(sk);
-	if (secattr == NULL)
-		return -ENOMEM;
-	rc = netlbl_sock_setattr(sk, secattr);
-	switch (rc) {
-	case 0:
-		sksec->nlbl_state = NLBL_LABELED;
-		break;
-	case -EDESTADDRREQ:
-		sksec->nlbl_state = NLBL_REQSKB;
-		rc = 0;
-		break;
-	}
-
-	return rc;
-}
-
-/**
  * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
  *
  * Description:
@@ -188,13 +153,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
  * The caller is responsibile for all the NetLabel sk_security_struct locking.
  *
  */
-void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
-				      int family)
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec)
 {
-	if (family == PF_INET)
-		ssec->nlbl_state = NLBL_REQUIRE;
-	else
-		ssec->nlbl_state = NLBL_UNSET;
+	ssec->nlbl_state = NLBL_UNSET;
 }
 
 /**
@@ -281,127 +242,86 @@ skbuff_setsid_return:
 }
 
 /**
- * selinux_netlbl_inet_conn_established - Netlabel the newly accepted connection
- * @sk: the new connection
+ * selinux_netlbl_inet_conn_request - Label an incoming stream connection
+ * @req: incoming connection request socket
  *
  * Description:
- * A new connection has been established on @sk so make sure it is labeled
- * correctly with the NetLabel susbsystem.
+ * A new incoming connection request is represented by @req, we need to label
+ * the new request_sock here and the stack will ensure the on-the-wire label
+ * will get preserved when a full sock is created once the connection handshake
+ * is complete.  Returns zero on success, negative values on failure.
  *
  */
-void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family)
+int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
 {
 	int rc;
-	struct sk_security_struct *sksec = sk->sk_security;
-	struct netlbl_lsm_secattr *secattr;
-	struct inet_sock *sk_inet = inet_sk(sk);
-	struct sockaddr_in addr;
-
-	if (sksec->nlbl_state != NLBL_REQUIRE)
-		return;
+	struct netlbl_lsm_secattr secattr;
 
-	secattr = selinux_netlbl_sock_genattr(sk);
-	if (secattr == NULL)
-		return;
+	if (family != PF_INET)
+		return 0;
 
-	rc = netlbl_sock_setattr(sk, secattr);
-	switch (rc) {
-	case 0:
-		sksec->nlbl_state = NLBL_LABELED;
-		break;
-	case -EDESTADDRREQ:
-		/* no PF_INET6 support yet because we don't support any IPv6
-		 * labeling protocols */
-		if (family != PF_INET) {
-			sksec->nlbl_state = NLBL_UNSET;
-			return;
-		}
-
-		addr.sin_family = family;
-		addr.sin_addr.s_addr = sk_inet->daddr;
-		if (netlbl_conn_setattr(sk, (struct sockaddr *)&addr,
-					secattr) != 0) {
-			/* we failed to label the connected socket (could be
-			 * for a variety of reasons, the actual "why" isn't
-			 * important here) so we have to go to our backup plan,
-			 * labeling the packets individually in the netfilter
-			 * local output hook.  this is okay but we need to
-			 * adjust the MSS of the connection to take into
-			 * account any labeling overhead, since we don't know
-			 * the exact overhead at this point we'll use the worst
-			 * case value which is 40 bytes for IPv4 */
-			struct inet_connection_sock *sk_conn = inet_csk(sk);
-			sk_conn->icsk_ext_hdr_len += 40 -
-				      (sk_inet->opt ? sk_inet->opt->optlen : 0);
-			sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
-
-			sksec->nlbl_state = NLBL_REQSKB;
-		} else
-			sksec->nlbl_state = NLBL_CONNLABELED;
-		break;
-	default:
-		/* note that we are failing to label the socket which could be
-		 * a bad thing since it means traffic could leave the system
-		 * without the desired labeling, however, all is not lost as
-		 * we have a check in selinux_netlbl_inode_permission() to
-		 * pick up the pieces that we might drop here because we can't
-		 * return an error code */
-		break;
-	}
+	netlbl_secattr_init(&secattr);
+	rc = security_netlbl_sid_to_secattr(req->secid, &secattr);
+	if (rc != 0)
+		goto inet_conn_request_return;
+	rc = netlbl_req_setattr(req, &secattr);
+inet_conn_request_return:
+	netlbl_secattr_destroy(&secattr);
+	return rc;
 }
 
 /**
- * selinux_netlbl_socket_post_create - Label a socket using NetLabel
- * @sock: the socket to label
+ * selinux_netlbl_inet_csk_clone - Initialize the newly created sock
+ * @sk: the new sock
  *
  * Description:
- * Attempt to label a socket using the NetLabel mechanism using the given
- * SID.  Returns zero values on success, negative values on failure.
+ * A new connection has been established using @sk, we've already labeled the
+ * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but
+ * we need to set the NetLabel state here since we now have a sock structure.
  *
  */
-int selinux_netlbl_socket_post_create(struct socket *sock)
+void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
 {
-	return selinux_netlbl_sock_setsid(sock->sk);
+	struct sk_security_struct *sksec = sk->sk_security;
+
+	if (family == PF_INET)
+		sksec->nlbl_state = NLBL_LABELED;
+	else
+		sksec->nlbl_state = NLBL_UNSET;
 }
 
 /**
- * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled
- * @inode: the file descriptor's inode
- * @mask: the permission mask
+ * selinux_netlbl_socket_post_create - Label a socket using NetLabel
+ * @sock: the socket to label
+ * @family: protocol family
  *
  * Description:
- * Looks at a file's inode and if it is marked as a socket protected by
- * NetLabel then verify that the socket has been labeled, if not try to label
- * the socket now with the inode's SID.  Returns zero on success, negative
- * values on failure.
+ * Attempt to label a socket using the NetLabel mechanism using the given
+ * SID.  Returns zero values on success, negative values on failure.
  *
  */
-int selinux_netlbl_inode_permission(struct inode *inode, int mask)
+int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
 {
 	int rc;
-	struct sock *sk;
-	struct socket *sock;
-	struct sk_security_struct *sksec;
+	struct sk_security_struct *sksec = sk->sk_security;
+	struct netlbl_lsm_secattr *secattr;
 
-	if (!S_ISSOCK(inode->i_mode) ||
-	    ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
-		return 0;
-	sock = SOCKET_I(inode);
-	sk = sock->sk;
-	if (sk == NULL)
-		return 0;
-	sksec = sk->sk_security;
-	if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE)
+	if (family != PF_INET)
 		return 0;
 
-	local_bh_disable();
-	bh_lock_sock_nested(sk);
-	if (likely(sksec->nlbl_state == NLBL_REQUIRE))
-		rc = selinux_netlbl_sock_setsid(sk);
-	else
+	secattr = selinux_netlbl_sock_genattr(sk);
+	if (secattr == NULL)
+		return -ENOMEM;
+	rc = netlbl_sock_setattr(sk, family, secattr);
+	switch (rc) {
+	case 0:
+		sksec->nlbl_state = NLBL_LABELED;
+		break;
+	case -EDESTADDRREQ:
+		sksec->nlbl_state = NLBL_REQSKB;
 		rc = 0;
-	bh_unlock_sock(sk);
-	local_bh_enable();
+		break;
+	}
 
 	return rc;
 }
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index fd20d15..23ad420 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1387,7 +1387,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
 	else {
 		netlbl_secattr_init(&secattr);
 		smack_to_secattr(ssp->smk_out, &secattr);
-		rc = netlbl_sock_setattr(sk, &secattr);
+		rc = netlbl_sock_setattr(sk, sk->sk_family, &secattr);
 		netlbl_secattr_destroy(&secattr);
 	}
 


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/6] selinux: Remove the "compat_net" compatibility code
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
  2009-03-27 21:10 ` [PATCH 1/6] lsm: Relocate the IPv4 security_inet_conn_request() hooks Paul Moore
  2009-03-27 21:10 ` [PATCH 2/6] netlabel: Label incoming TCP connections correctly in SELinux Paul Moore
@ 2009-03-27 21:10 ` Paul Moore
  2009-03-27 21:10 ` [PATCH 4/6] lsm: Remove the socket_post_accept() hook Paul Moore
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:10 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

The SELinux "compat_net" is marked as deprecated, the time has come to
finally remove it from the kernel.  Further code simplifications are
likely in the future, but this patch was intended to be a simple,
straight-up removal of the compat_net code.

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 Documentation/feature-removal-schedule.txt |   11 --
 Documentation/kernel-parameters.txt        |    9 --
 security/selinux/hooks.c                   |  153 +---------------------------
 security/selinux/selinuxfs.c               |   68 ------------
 4 files changed, 7 insertions(+), 234 deletions(-)

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index e47c0ff..9b2cd68 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -328,17 +328,6 @@ Who:	Hans de Goede <hdegoede@redhat.com>
 
 ---------------------------
 
-What:	SELinux "compat_net" functionality
-When:	2.6.30 at the earliest
-Why:	In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
-	network access control functionality of SELinux.  Secmark offers both
-	better performance and greater flexibility than the "compat_net"
-	mechanism.  Now that the major Linux distributions have moved to
-	Secmark, it is time to deprecate the older mechanism and start the
-	process of removing the old code.
-Who:	Paul Moore <paul.moore@hp.com>
----------------------------
-
 What:	sysfs ui for changing p4-clockmod parameters
 When:	September 2009
 Why:	See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index fa4e123..d1b0827 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2019,15 +2019,6 @@ and is between 256 and 4096 characters. It is defined in the file
 			If enabled at boot time, /selinux/disable can be used
 			later to disable prior to initial policy load.
 
-	selinux_compat_net =
-			[SELINUX] Set initial selinux_compat_net flag value.
-                        Format: { "0" | "1" }
-                        0 -- use new secmark-based packet controls
-                        1 -- use legacy packet controls
-                        Default value is 0 (preferred).
-                        Value can be changed at runtime via
-                        /selinux/compat_net.
-
 	serialnumber	[BUGS=X86-32]
 
 	shapers=	[NET]
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ee2e781..ba808ef 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -93,7 +93,6 @@
 
 extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
-extern int selinux_compat_net;
 extern struct security_operations *security_ops;
 
 /* SECMARK reference count */
@@ -4019,72 +4018,6 @@ static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
 			    SECCLASS_NODE, NODE__RECVFROM, ad);
 }
 
-static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
-						struct sk_buff *skb,
-						struct avc_audit_data *ad,
-						u16 family,
-						char *addrp)
-{
-	int err;
-	struct sk_security_struct *sksec = sk->sk_security;
-	u16 sk_class;
-	u32 netif_perm, node_perm, recv_perm;
-	u32 port_sid, node_sid, if_sid, sk_sid;
-
-	sk_sid = sksec->sid;
-	sk_class = sksec->sclass;
-
-	switch (sk_class) {
-	case SECCLASS_UDP_SOCKET:
-		netif_perm = NETIF__UDP_RECV;
-		node_perm = NODE__UDP_RECV;
-		recv_perm = UDP_SOCKET__RECV_MSG;
-		break;
-	case SECCLASS_TCP_SOCKET:
-		netif_perm = NETIF__TCP_RECV;
-		node_perm = NODE__TCP_RECV;
-		recv_perm = TCP_SOCKET__RECV_MSG;
-		break;
-	case SECCLASS_DCCP_SOCKET:
-		netif_perm = NETIF__DCCP_RECV;
-		node_perm = NODE__DCCP_RECV;
-		recv_perm = DCCP_SOCKET__RECV_MSG;
-		break;
-	default:
-		netif_perm = NETIF__RAWIP_RECV;
-		node_perm = NODE__RAWIP_RECV;
-		recv_perm = 0;
-		break;
-	}
-
-	err = sel_netif_sid(skb->iif, &if_sid);
-	if (err)
-		return err;
-	err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
-	if (err)
-		return err;
-
-	err = sel_netnode_sid(addrp, family, &node_sid);
-	if (err)
-		return err;
-	err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad);
-	if (err)
-		return err;
-
-	if (!recv_perm)
-		return 0;
-	err = sel_netport_sid(sk->sk_protocol,
-			      ntohs(ad->u.net.sport), &port_sid);
-	if (unlikely(err)) {
-		printk(KERN_WARNING
-		       "SELinux: failure in"
-		       " selinux_sock_rcv_skb_iptables_compat(),"
-		       " network port label not found\n");
-		return err;
-	}
-	return avc_has_perm(sk_sid, port_sid, sk_class, recv_perm, ad);
-}
-
 static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
 				       u16 family)
 {
@@ -4102,14 +4035,12 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
 	if (err)
 		return err;
 
-	if (selinux_compat_net)
-		err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad,
-							   family, addrp);
-	else if (selinux_secmark_enabled())
+	if (selinux_secmark_enabled()) {
 		err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
 				   PACKET__RECV, &ad);
-	if (err)
-		return err;
+		if (err)
+			return err;
+	}
 
 	if (selinux_policycap_netpeer) {
 		err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
@@ -4151,7 +4082,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	 * to the selinux_sock_rcv_skb_compat() function to deal with the
 	 * special handling.  We do this in an attempt to keep this function
 	 * as fast and as clean as possible. */
-	if (selinux_compat_net || !selinux_policycap_netpeer)
+	if (!selinux_policycap_netpeer)
 		return selinux_sock_rcv_skb_compat(sk, skb, family);
 
 	secmark_active = selinux_secmark_enabled();
@@ -4516,71 +4447,6 @@ static unsigned int selinux_ipv4_output(unsigned int hooknum,
 	return selinux_ip_output(skb, PF_INET);
 }
 
-static int selinux_ip_postroute_iptables_compat(struct sock *sk,
-						int ifindex,
-						struct avc_audit_data *ad,
-						u16 family, char *addrp)
-{
-	int err;
-	struct sk_security_struct *sksec = sk->sk_security;
-	u16 sk_class;
-	u32 netif_perm, node_perm, send_perm;
-	u32 port_sid, node_sid, if_sid, sk_sid;
-
-	sk_sid = sksec->sid;
-	sk_class = sksec->sclass;
-
-	switch (sk_class) {
-	case SECCLASS_UDP_SOCKET:
-		netif_perm = NETIF__UDP_SEND;
-		node_perm = NODE__UDP_SEND;
-		send_perm = UDP_SOCKET__SEND_MSG;
-		break;
-	case SECCLASS_TCP_SOCKET:
-		netif_perm = NETIF__TCP_SEND;
-		node_perm = NODE__TCP_SEND;
-		send_perm = TCP_SOCKET__SEND_MSG;
-		break;
-	case SECCLASS_DCCP_SOCKET:
-		netif_perm = NETIF__DCCP_SEND;
-		node_perm = NODE__DCCP_SEND;
-		send_perm = DCCP_SOCKET__SEND_MSG;
-		break;
-	default:
-		netif_perm = NETIF__RAWIP_SEND;
-		node_perm = NODE__RAWIP_SEND;
-		send_perm = 0;
-		break;
-	}
-
-	err = sel_netif_sid(ifindex, &if_sid);
-	if (err)
-		return err;
-	err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
-		return err;
-
-	err = sel_netnode_sid(addrp, family, &node_sid);
-	if (err)
-		return err;
-	err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad);
-	if (err)
-		return err;
-
-	if (send_perm != 0)
-		return 0;
-
-	err = sel_netport_sid(sk->sk_protocol,
-			      ntohs(ad->u.net.dport), &port_sid);
-	if (unlikely(err)) {
-		printk(KERN_WARNING
-		       "SELinux: failure in"
-		       " selinux_ip_postroute_iptables_compat(),"
-		       " network port label not found\n");
-		return err;
-	}
-	return avc_has_perm(sk_sid, port_sid, sk_class, send_perm, ad);
-}
-
 static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 						int ifindex,
 						u16 family)
@@ -4601,15 +4467,10 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 	if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
 		return NF_DROP;
 
-	if (selinux_compat_net) {
-		if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex,
-							 &ad, family, addrp))
-			return NF_DROP;
-	} else if (selinux_secmark_enabled()) {
+	if (selinux_secmark_enabled())
 		if (avc_has_perm(sksec->sid, skb->secmark,
 				 SECCLASS_PACKET, PACKET__SEND, &ad))
 			return NF_DROP;
-	}
 
 	if (selinux_policycap_netpeer)
 		if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
@@ -4633,7 +4494,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 	 * to the selinux_ip_postroute_compat() function to deal with the
 	 * special handling.  We do this in an attempt to keep this function
 	 * as fast and as clean as possible. */
-	if (selinux_compat_net || !selinux_policycap_netpeer)
+	if (!selinux_policycap_netpeer)
 		return selinux_ip_postroute_compat(skb, ifindex, family);
 #ifdef CONFIG_XFRM
 	/* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index d3c8b98..2d5136e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -47,8 +47,6 @@ static char *policycap_names[] = {
 
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 
-int selinux_compat_net = 0;
-
 static int __init checkreqprot_setup(char *str)
 {
 	unsigned long checkreqprot;
@@ -58,16 +56,6 @@ static int __init checkreqprot_setup(char *str)
 }
 __setup("checkreqprot=", checkreqprot_setup);
 
-static int __init selinux_compat_net_setup(char *str)
-{
-	unsigned long compat_net;
-	if (!strict_strtoul(str, 0, &compat_net))
-		selinux_compat_net = compat_net ? 1 : 0;
-	return 1;
-}
-__setup("selinux_compat_net=", selinux_compat_net_setup);
-
-
 static DEFINE_MUTEX(sel_mutex);
 
 /* global data for booleans */
@@ -450,61 +438,6 @@ static const struct file_operations sel_checkreqprot_ops = {
 	.write		= sel_write_checkreqprot,
 };
 
-static ssize_t sel_read_compat_net(struct file *filp, char __user *buf,
-				   size_t count, loff_t *ppos)
-{
-	char tmpbuf[TMPBUFLEN];
-	ssize_t length;
-
-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net);
-	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
-}
-
-static ssize_t sel_write_compat_net(struct file *file, const char __user *buf,
-				    size_t count, loff_t *ppos)
-{
-	char *page;
-	ssize_t length;
-	int new_value;
-
-	length = task_has_security(current, SECURITY__LOAD_POLICY);
-	if (length)
-		return length;
-
-	if (count >= PAGE_SIZE)
-		return -ENOMEM;
-	if (*ppos != 0) {
-		/* No partial writes. */
-		return -EINVAL;
-	}
-	page = (char *)get_zeroed_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-	length = -EFAULT;
-	if (copy_from_user(page, buf, count))
-		goto out;
-
-	length = -EINVAL;
-	if (sscanf(page, "%d", &new_value) != 1)
-		goto out;
-
-	if (new_value) {
-		printk(KERN_NOTICE
-		       "SELinux: compat_net is deprecated, please use secmark"
-		       " instead\n");
-		selinux_compat_net = 1;
-	} else
-		selinux_compat_net = 0;
-	length = count;
-out:
-	free_page((unsigned long) page);
-	return length;
-}
-static const struct file_operations sel_compat_net_ops = {
-	.read		= sel_read_compat_net,
-	.write		= sel_write_compat_net,
-};
-
 /*
  * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
  */
@@ -1665,7 +1598,6 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
 		[SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
 		[SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
 		[SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
-		[SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
 		[SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
 		[SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
 		/* last one */ {""}


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/6] lsm: Remove the socket_post_accept() hook
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
                   ` (2 preceding siblings ...)
  2009-03-27 21:10 ` [PATCH 3/6] selinux: Remove the "compat_net" compatibility code Paul Moore
@ 2009-03-27 21:10 ` Paul Moore
  2009-03-27 21:10 ` [PATCH 5/6] netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections Paul Moore
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:10 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

The socket_post_accept() hook is not currently used by any in-tree modules
and its existence continues to cause problems by confusing people about
what can be safely accomplished using this hook.  If a legitimate need for
this hook arises in the future it can always be reintroduced.

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 include/linux/security.h |   13 -------------
 net/socket.c             |    2 --
 security/capability.c    |    5 -----
 security/security.c      |    5 -----
 4 files changed, 0 insertions(+), 25 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 1f2ab63..54ed157 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -880,11 +880,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *	@sock contains the listening socket structure.
  *	@newsock contains the newly created server socket for connection.
  *	Return 0 if permission is granted.
- * @socket_post_accept:
- *	This hook allows a security module to copy security
- *	information into the newly created socket's inode.
- *	@sock contains the listening socket structure.
- *	@newsock contains the newly created server socket for connection.
  * @socket_sendmsg:
  *	Check permission before transmitting a message to another socket.
  *	@sock contains the socket structure.
@@ -1554,8 +1549,6 @@ struct security_operations {
 			       struct sockaddr *address, int addrlen);
 	int (*socket_listen) (struct socket *sock, int backlog);
 	int (*socket_accept) (struct socket *sock, struct socket *newsock);
-	void (*socket_post_accept) (struct socket *sock,
-				    struct socket *newsock);
 	int (*socket_sendmsg) (struct socket *sock,
 			       struct msghdr *msg, int size);
 	int (*socket_recvmsg) (struct socket *sock,
@@ -2537,7 +2530,6 @@ int security_socket_bind(struct socket *sock, struct sockaddr *address, int addr
 int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen);
 int security_socket_listen(struct socket *sock, int backlog);
 int security_socket_accept(struct socket *sock, struct socket *newsock);
-void security_socket_post_accept(struct socket *sock, struct socket *newsock);
 int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size);
 int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,
 			    int size, int flags);
@@ -2616,11 +2608,6 @@ static inline int security_socket_accept(struct socket *sock,
 	return 0;
 }
 
-static inline void security_socket_post_accept(struct socket *sock,
-					       struct socket *newsock)
-{
-}
-
 static inline int security_socket_sendmsg(struct socket *sock,
 					  struct msghdr *msg, int size)
 {
diff --git a/net/socket.c b/net/socket.c
index af0205f..5d288d1 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1536,8 +1536,6 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
 	fd_install(newfd, newfile);
 	err = newfd;
 
-	security_socket_post_accept(sock, newsock);
-
 out_put:
 	fput_light(sock->file, fput_needed);
 out:
diff --git a/security/capability.c b/security/capability.c
index c545bd1..21b6cea 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -620,10 +620,6 @@ static int cap_socket_accept(struct socket *sock, struct socket *newsock)
 	return 0;
 }
 
-static void cap_socket_post_accept(struct socket *sock, struct socket *newsock)
-{
-}
-
 static int cap_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
 {
 	return 0;
@@ -1014,7 +1010,6 @@ void security_fixup_ops(struct security_operations *ops)
 	set_to_cap_if_null(ops, socket_connect);
 	set_to_cap_if_null(ops, socket_listen);
 	set_to_cap_if_null(ops, socket_accept);
-	set_to_cap_if_null(ops, socket_post_accept);
 	set_to_cap_if_null(ops, socket_sendmsg);
 	set_to_cap_if_null(ops, socket_recvmsg);
 	set_to_cap_if_null(ops, socket_getsockname);
diff --git a/security/security.c b/security/security.c
index c3586c0..206e538 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1007,11 +1007,6 @@ int security_socket_accept(struct socket *sock, struct socket *newsock)
 	return security_ops->socket_accept(sock, newsock);
 }
 
-void security_socket_post_accept(struct socket *sock, struct socket *newsock)
-{
-	security_ops->socket_post_accept(sock, newsock);
-}
-
 int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
 {
 	return security_ops->socket_sendmsg(sock, msg, size);


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/6] netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
                   ` (3 preceding siblings ...)
  2009-03-27 21:10 ` [PATCH 4/6] lsm: Remove the socket_post_accept() hook Paul Moore
@ 2009-03-27 21:10 ` Paul Moore
  2009-03-28  3:04   ` Casey Schaufler
  2009-03-27 21:11 ` [PATCH 6/6] smack: Add a new '-CIPSO' option to the network address label configuration Paul Moore
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:10 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

This patch cleans up a lot of the Smack network access control code.  The
largest changes are to fix the labeling of incoming TCP connections in a
manner similar to the recent SELinux changes which use the
security_inet_conn_request() hook to label the request_sock and let the label
move to the child socket via the normal network stack mechanisms.  In addition
to the incoming TCP connection fixes this patch also removes the smk_labled
field from the socket_smack struct as the minor optimization advantage was
outweighed by the difficulty in maintaining it's proper state.

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 include/net/netlabel.h       |    5 +
 net/netlabel/netlabel_kapi.c |   13 ++
 security/smack/smack.h       |    1 
 security/smack/smack_lsm.c   |  260 +++++++++++++++++++++++-------------------
 4 files changed, 161 insertions(+), 118 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index bdb10e5..60ebbc1 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -417,6 +417,7 @@ int netlbl_conn_setattr(struct sock *sk,
 			const struct netlbl_lsm_secattr *secattr);
 int netlbl_req_setattr(struct request_sock *req,
 		       const struct netlbl_lsm_secattr *secattr);
+void netlbl_req_delattr(struct request_sock *req);
 int netlbl_skbuff_setattr(struct sk_buff *skb,
 			  u16 family,
 			  const struct netlbl_lsm_secattr *secattr);
@@ -547,6 +548,10 @@ static inline int netlbl_req_setattr(struct request_sock *req,
 {
 	return -ENOSYS;
 }
+static inline void netlbl_req_delattr(struct request_sock *req)
+{
+	return;
+}
 static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
 				      u16 family,
 				      const struct netlbl_lsm_secattr *secattr)
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index cae2f5f..b0e582f 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -861,6 +861,19 @@ req_setattr_return:
 }
 
 /**
+* netlbl_req_delattr - Delete all the NetLabel labels on a socket
+* @req: the socket
+*
+* Description:
+* Remove all the NetLabel labeling from @req.
+*
+*/
+void netlbl_req_delattr(struct request_sock *req)
+{
+	cipso_v4_req_delattr(req);
+}
+
+/**
  * netlbl_skbuff_setattr - Label a packet using the correct protocol
  * @skb: the packet
  * @family: protocol family
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 64164f8..5e5a3bc 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -42,7 +42,6 @@ struct superblock_smack {
 struct socket_smack {
 	char		*smk_out;			/* outbound label */
 	char		*smk_in;			/* inbound label */
-	int		smk_labeled;			/* label scheme */
 	char		smk_packet[SMK_LABELLEN];	/* TCP peer label */
 };
 
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 23ad420..8ed502c 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -7,6 +7,8 @@
  *	Casey Schaufler <casey@schaufler-ca.com>
  *
  *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
+ *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *                Paul Moore <paul.moore@hp.com>
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License version 2,
@@ -20,6 +22,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/kd.h>
 #include <asm/ioctls.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/mutex.h>
@@ -1275,7 +1278,6 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
 
 	ssp->smk_in = csp;
 	ssp->smk_out = csp;
-	ssp->smk_labeled = SMACK_CIPSO_SOCKET;
 	ssp->smk_packet[0] = '\0';
 
 	sk->sk_security = ssp;
@@ -1295,6 +1297,39 @@ static void smack_sk_free_security(struct sock *sk)
 }
 
 /**
+* smack_host_label - check host based restrictions
+* @sip: the object end
+*
+* looks for host based access restrictions
+*
+* This version will only be appropriate for really small sets of single label
+* hosts.  The caller is responsible for ensuring that the RCU read lock is
+* taken before calling this function.
+*
+* Returns the label of the far end or NULL if it's not special.
+*/
+static char *smack_host_label(struct sockaddr_in *sip)
+{
+	struct smk_netlbladdr *snp;
+	struct in_addr *siap = &sip->sin_addr;
+
+	if (siap->s_addr == 0)
+		return NULL;
+
+	list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list)
+		/*
+		* we break after finding the first match because
+		* the list is sorted from longest to shortest mask
+		* so we have found the most specific match
+		*/
+		if ((&snp->smk_host.sin_addr)->s_addr ==
+		    (siap->s_addr & (&snp->smk_mask)->s_addr))
+			return snp->smk_label;
+
+	return NULL;
+}
+
+/**
  * smack_set_catset - convert a capset to netlabel mls categories
  * @catset: the Smack categories
  * @sap: where to put the netlabel categories
@@ -1365,11 +1400,10 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
  */
 static int smack_netlabel(struct sock *sk, int labeled)
 {
-	struct socket_smack *ssp;
+	struct socket_smack *ssp = sk->sk_security;
 	struct netlbl_lsm_secattr secattr;
 	int rc = 0;
 
-	ssp = sk->sk_security;
 	/*
 	 * Usually the netlabel code will handle changing the
 	 * packet labeling based on the label.
@@ -1393,21 +1427,45 @@ static int smack_netlabel(struct sock *sk, int labeled)
 
 	bh_unlock_sock(sk);
 	local_bh_enable();
-	/*
-	 * Remember the label scheme used so that it is not
-	 * necessary to do the netlabel setting if it has not
-	 * changed the next time through.
-	 *
-	 * The -EDESTADDRREQ case is an indication that there's
-	 * a single level host involved.
-	 */
-	if (rc == 0)
-		ssp->smk_labeled = labeled;
 
 	return rc;
 }
 
 /**
+ * smack_netlbel_send - Set the secattr on a socket and perform access checks
+ * @sk: the socket
+ * @sap: the destination address
+ *
+ * Set the correct secattr for the given socket based on the destination
+ * address and perform any outbound access checks needed.
+ *
+ * Returns 0 on success or an error code.
+ *
+ */
+static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
+{
+	int rc;
+	int sk_lbl;
+	char *hostsp;
+	struct socket_smack *ssp = sk->sk_security;
+
+	rcu_read_lock();
+	hostsp = smack_host_label(sap);
+	if (hostsp != NULL) {
+		sk_lbl = SMACK_UNLABELED_SOCKET;
+		rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
+	} else {
+		sk_lbl = SMACK_CIPSO_SOCKET;
+		rc = 0;
+	}
+	rcu_read_unlock();
+	if (rc != 0)
+		return rc;
+
+	return smack_netlabel(sk, sk_lbl);
+}
+
+/**
  * smack_inode_setsecurity - set smack xattrs
  * @inode: the object
  * @name: attribute name
@@ -1488,43 +1546,6 @@ static int smack_socket_post_create(struct socket *sock, int family,
 	return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
 }
 
-
-/**
- * smack_host_label - check host based restrictions
- * @sip: the object end
- *
- * looks for host based access restrictions
- *
- * This version will only be appropriate for really small
- * sets of single label hosts.
- *
- * Returns the label of the far end or NULL if it's not special.
- */
-static char *smack_host_label(struct sockaddr_in *sip)
-{
-	struct smk_netlbladdr *snp;
-	struct in_addr *siap = &sip->sin_addr;
-
-	if (siap->s_addr == 0)
-		return NULL;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) {
-		/*
-		 * we break after finding the first match because
-		 * the list is sorted from longest to shortest mask
-		 * so we have found the most specific match
-		 */
-		if ((&snp->smk_host.sin_addr)->s_addr  ==
-			(siap->s_addr & (&snp->smk_mask)->s_addr)) {
-			rcu_read_unlock();
-			return snp->smk_label;
-		}
-	}
-	rcu_read_unlock();
-	return NULL;
-}
-
 /**
  * smack_socket_connect - connect access check
  * @sock: the socket
@@ -1538,30 +1559,12 @@ static char *smack_host_label(struct sockaddr_in *sip)
 static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
 				int addrlen)
 {
-	struct socket_smack *ssp = sock->sk->sk_security;
-	char *hostsp;
-	int rc;
-
 	if (sock->sk == NULL || sock->sk->sk_family != PF_INET)
 		return 0;
-
 	if (addrlen < sizeof(struct sockaddr_in))
 		return -EINVAL;
 
-	hostsp = smack_host_label((struct sockaddr_in *)sap);
-	if (hostsp == NULL) {
-		if (ssp->smk_labeled != SMACK_CIPSO_SOCKET)
-			return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
-		return 0;
-	}
-
-	rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
-	if (rc != 0)
-		return rc;
-
-	if (ssp->smk_labeled != SMACK_UNLABELED_SOCKET)
-		return smack_netlabel(sock->sk, SMACK_UNLABELED_SOCKET);
-	return 0;
+	return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
 }
 
 /**
@@ -2262,9 +2265,6 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
 				int size)
 {
 	struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
-	struct socket_smack *ssp = sock->sk->sk_security;
-	char *hostsp;
-	int rc;
 
 	/*
 	 * Perfectly reasonable for this to be NULL
@@ -2272,22 +2272,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (sip == NULL || sip->sin_family != PF_INET)
 		return 0;
 
-	hostsp = smack_host_label(sip);
-	if (hostsp == NULL) {
-		if (ssp->smk_labeled != SMACK_CIPSO_SOCKET)
-			return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
-		return 0;
-	}
-
-	rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
-	if (rc != 0)
-		return rc;
-
-	if (ssp->smk_labeled != SMACK_UNLABELED_SOCKET)
-		return smack_netlabel(sock->sk, SMACK_UNLABELED_SOCKET);
-
-	return 0;
-
+	return smack_netlabel_send(sock->sk, sip);
 }
 
 
@@ -2492,31 +2477,24 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
 }
 
 /**
- * smack_sock_graft - graft access state between two sockets
- * @sk: fresh sock
- * @parent: donor socket
+ * smack_sock_graft - Initialize a newly created socket with an existing sock
+ * @sk: child sock
+ * @parent: parent socket
  *
- * Sets the netlabel socket state on sk from parent
+ * Set the smk_{in,out} state of an existing sock based on the process that
+ * is creating the new socket.
  */
 static void smack_sock_graft(struct sock *sk, struct socket *parent)
 {
 	struct socket_smack *ssp;
-	int rc;
-
-	if (sk == NULL)
-		return;
 
-	if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
+	if (sk == NULL ||
+	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
 		return;
 
 	ssp = sk->sk_security;
 	ssp->smk_in = ssp->smk_out = current_security();
-	ssp->smk_packet[0] = '\0';
-
-	rc = smack_netlabel(sk, SMACK_CIPSO_SOCKET);
-	if (rc != 0)
-		printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
-		       __func__, -rc);
+	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
 }
 
 /**
@@ -2531,35 +2509,82 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
 static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 				   struct request_sock *req)
 {
-	struct netlbl_lsm_secattr skb_secattr;
+	u16 family = sk->sk_family;
 	struct socket_smack *ssp = sk->sk_security;
+	struct netlbl_lsm_secattr secattr;
+	struct sockaddr_in addr;
+	struct iphdr *hdr;
 	char smack[SMK_LABELLEN];
 	int rc;
 
-	if (skb == NULL)
-		return -EACCES;
+	/* handle mapped IPv4 packets arriving via IPv6 sockets */
+	if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
+		family = PF_INET;
 
-	netlbl_secattr_init(&skb_secattr);
-	rc = netlbl_skbuff_getattr(skb, sk->sk_family, &skb_secattr);
+	netlbl_secattr_init(&secattr);
+	rc = netlbl_skbuff_getattr(skb, family, &secattr);
 	if (rc == 0)
-		smack_from_secattr(&skb_secattr, smack);
+		smack_from_secattr(&secattr, smack);
 	else
 		strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN);
-	netlbl_secattr_destroy(&skb_secattr);
+	netlbl_secattr_destroy(&secattr);
+
 	/*
-	 * Receiving a packet requires that the other end
-	 * be able to write here. Read access is not required.
-	 *
-	 * If the request is successful save the peer's label
-	 * so that SO_PEERCRED can report it.
+	 * Receiving a packet requires that the other end be able to write
+	 * here. Read access is not required.
 	 */
 	rc = smk_access(smack, ssp->smk_in, MAY_WRITE);
-	if (rc == 0)
-		strncpy(ssp->smk_packet, smack, SMK_MAXLEN);
+	if (rc != 0)
+		return rc;
+
+	/*
+	 * Save the peer's label in the request_sock so we can later setup
+	 * smk_packet in the child socket so that SO_PEERCRED can report it.
+	 */
+	req->peer_secid = smack_to_secid(smack);
+
+	/*
+	 * We need to decide if we want to label the incoming connection here
+	 * if we do we only need to label the request_sock and the stack will
+	 * propogate the wire-label to the sock when it is created.
+	 */
+	hdr = ip_hdr(skb);
+	addr.sin_addr.s_addr = hdr->saddr;
+	rcu_read_lock();
+	if (smack_host_label(&addr) == NULL) {
+		rcu_read_unlock();
+		netlbl_secattr_init(&secattr);
+		smack_to_secattr(smack, &secattr);
+		rc = netlbl_req_setattr(req, &secattr);
+		netlbl_secattr_destroy(&secattr);
+	} else {
+		rcu_read_unlock();
+		netlbl_req_delattr(req);
+	}
 
 	return rc;
 }
 
+/**
+ * smack_inet_csk_clone - Copy the connection information to the new socket
+ * @sk: the new socket
+ * @req: the connection's request_sock
+ *
+ * Transfer the connection's peer label to the newly created socket.
+ */
+static void smack_inet_csk_clone(struct sock *sk,
+				 const struct request_sock *req)
+{
+	struct socket_smack *ssp = sk->sk_security;
+	char *smack;
+
+	if (req->peer_secid != 0) {
+		smack = smack_from_secid(req->peer_secid);
+		strncpy(ssp->smk_packet, smack, SMK_MAXLEN);
+	} else
+		ssp->smk_packet[0] = '\0';
+}
+
 /*
  * Key management security hooks
  *
@@ -2911,6 +2936,7 @@ struct security_operations smack_ops = {
 	.sk_free_security = 		smack_sk_free_security,
 	.sock_graft = 			smack_sock_graft,
 	.inet_conn_request = 		smack_inet_conn_request,
+	.inet_csk_clone =		smack_inet_csk_clone,
 
  /* key management security hooks */
 #ifdef CONFIG_KEYS


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 6/6] smack: Add a new '-CIPSO' option to the network address label configuration
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
                   ` (4 preceding siblings ...)
  2009-03-27 21:10 ` [PATCH 5/6] netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections Paul Moore
@ 2009-03-27 21:11 ` Paul Moore
  2009-03-28  3:05   ` Casey Schaufler
  2009-03-27 21:58 ` [PATCH 0/6] Labeled networking patches for 2.6.30 David Miller
  2009-03-28  5:16 ` James Morris
  7 siblings, 1 reply; 15+ messages in thread
From: Paul Moore @ 2009-03-27 21:11 UTC (permalink / raw)
  To: linux-security-module, selinux; +Cc: netdev, casey, etienne.basset

From: Etienne Basset <etienne.basset@numericable.fr>

This patch adds a new special option '-CIPSO' to the Smack subsystem. When used
in the netlabel list, it means "use CIPSO networking". A use case is when your
local network speaks CIPSO and you want also to connect to the unlabeled
Internet. This patch also add some documentation describing that. The patch
also corrects an oops when setting a '' SMACK64 xattr to a file.

Signed-off-by: Etienne Basset <etienne.basset@numericable.fr>
Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 Documentation/Smack.txt       |   42 ++++++++++++++++++++++++++++++++++++-----
 security/smack/smack.h        |    3 +++
 security/smack/smack_access.c |    3 +++
 security/smack/smack_lsm.c    |   11 +++++++++--
 security/smack/smackfs.c      |   38 +++++++++++++++++++++++++++++--------
 5 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt
index 989c2fc..629c92e 100644
--- a/Documentation/Smack.txt
+++ b/Documentation/Smack.txt
@@ -184,14 +184,16 @@ length. Single character labels using special characters, that being anything
 other than a letter or digit, are reserved for use by the Smack development
 team. Smack labels are unstructured, case sensitive, and the only operation
 ever performed on them is comparison for equality. Smack labels cannot
-contain unprintable characters or the "/" (slash) character.
+contain unprintable characters or the "/" (slash) character. Smack labels
+cannot begin with a '-', which is reserved for special options.
 
 There are some predefined labels:
 
-	_ Pronounced "floor", a single underscore character.
-	^ Pronounced "hat", a single circumflex character.
-	* Pronounced "star", a single asterisk character.
-	? Pronounced "huh", a single question mark character.
+	_ 	Pronounced "floor", a single underscore character.
+	^ 	Pronounced "hat", a single circumflex character.
+	* 	Pronounced "star", a single asterisk character.
+	? 	Pronounced "huh", a single question mark character.
+	@ 	Pronounced "Internet", a single at sign character.
 
 Every task on a Smack system is assigned a label. System tasks, such as
 init(8) and systems daemons, are run with the floor ("_") label. User tasks
@@ -412,6 +414,36 @@ sockets.
 	A privileged program may set this to match the label of another
 	task with which it hopes to communicate.
 
+Smack Netlabel Exceptions
+
+You will often find that your labeled application has to talk to the outside,
+unlabeled world. To do this there's a special file /smack/netlabel where you can
+add some exceptions in the form of :
+@IP1	   LABEL1 or
+@IP2/MASK  LABEL2
+
+It means that your application will have unlabeled access to @IP1 if it has
+write access on LABEL1, and access to the subnet @IP2/MASK if it has write
+access on LABEL2.
+
+Entries in the /smack/netlabel file are matched by longest mask first, like in
+classless IPv4 routing.
+
+A special label '@' and an option '-CIPSO' can be used there :
+@      means Internet, any application with any label has access to it
+-CIPSO means standard CIPSO networking
+
+If you don't know what CIPSO is and don't plan to use it, you can just do :
+echo 127.0.0.1 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0 @      > /smack/netlabel
+
+If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
+Internet access, you can have :
+echo 127.0.0.1      -CIPSO > /smack/netlabel
+echo 192.168.0.0/16 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0      @      > /smack/netlabel
+
+
 Writing Applications for Smack
 
 There are three sorts of applications that will run on a Smack system. How an
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 5e5a3bc..42ef313 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -132,6 +132,8 @@ struct smack_known {
 #define XATTR_NAME_SMACKIPIN	XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
 #define XATTR_NAME_SMACKIPOUT	XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
 
+#define SMACK_CIPSO_OPTION 	"-CIPSO"
+
 /*
  * How communications on this socket are treated.
  * Usually it's determined by the underlying netlabel code
@@ -199,6 +201,7 @@ u32 smack_to_secid(const char *);
 extern int smack_cipso_direct;
 extern char *smack_net_ambient;
 extern char *smack_onlycap;
+extern const char *smack_cipso_option;
 
 extern struct smack_known smack_known_floor;
 extern struct smack_known smack_known_hat;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 5856419..ac0a270 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -261,6 +261,9 @@ char *smk_import(const char *string, int len)
 {
 	struct smack_known *skp;
 
+	/* labels cannot begin with a '-' */
+	if (string[0] == '-')
+		return NULL;
 	skp = smk_import_entry(string, len);
 	if (skp == NULL)
 		return NULL;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 8ed502c..9215149 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -609,6 +609,9 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
 	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
 		if (!capable(CAP_MAC_ADMIN))
 			rc = -EPERM;
+		/* a label cannot be void and cannot begin with '-' */
+		if (size == 0 || (size > 0 && ((char *)value)[0] == '-'))
+			rc = -EINVAL;
 	} else
 		rc = cap_inode_setxattr(dentry, name, value, size, flags);
 
@@ -1323,8 +1326,12 @@ static char *smack_host_label(struct sockaddr_in *sip)
 		* so we have found the most specific match
 		*/
 		if ((&snp->smk_host.sin_addr)->s_addr ==
-		    (siap->s_addr & (&snp->smk_mask)->s_addr))
+		    (siap->s_addr & (&snp->smk_mask)->s_addr)) {
+			/* we have found the special CIPSO option */
+			if (snp->smk_label == smack_cipso_option)
+				return NULL;
 			return snp->smk_label;
+		}
 
 	return NULL;
 }
@@ -1486,7 +1493,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
 	struct socket *sock;
 	int rc = 0;
 
-	if (value == NULL || size > SMK_LABELLEN)
+	if (value == NULL || size > SMK_LABELLEN || size == 0)
 		return -EACCES;
 
 	sp = smk_import(value, size);
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 856c8a2..e03a7e1 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -86,6 +86,9 @@ LIST_HEAD(smack_rule_list);
 
 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 
+const char *smack_cipso_option = SMACK_CIPSO_OPTION;
+
+
 #define	SEQ_READ_FINISHED	1
 
 /*
@@ -565,6 +568,11 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
 		goto unlockedout;
 	}
 
+	/* labels cannot begin with a '-' */
+	if (data[0] == '-') {
+		rc = -EINVAL;
+		goto unlockedout;
+	}
 	data[count] = '\0';
 	rule = data;
 	/*
@@ -808,9 +816,18 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
 	if (m > BEBITS)
 		return -EINVAL;
 
-	sp = smk_import(smack, 0);
-	if (sp == NULL)
-		return -EINVAL;
+	/* if smack begins with '-', its an option, don't import it */
+	if (smack[0] != '-') {
+		sp = smk_import(smack, 0);
+		if (sp == NULL)
+			return -EINVAL;
+	} else {
+		/* check known options */
+		if (strcmp(smack, smack_cipso_option) == 0)
+			sp = (char *)smack_cipso_option;
+		else
+			return -EINVAL;
+	}
 
 	for (temp_mask = 0; m > 0; m--) {
 		temp_mask |= mask_bits;
@@ -849,18 +866,23 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
 			smk_netlbladdr_insert(skp);
 		}
 	} else {
-		rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
-			&skp->smk_host.sin_addr, &skp->smk_mask,
-			PF_INET, &audit_info);
+		/* we delete the unlabeled entry, only if the previous label
+		 * wasnt the special CIPSO option */
+		if (skp->smk_label != smack_cipso_option)
+			rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
+					&skp->smk_host.sin_addr, &skp->smk_mask,
+					PF_INET, &audit_info);
+		else
+			rc = 0;
 		skp->smk_label = sp;
 	}
 
 	/*
 	 * Now tell netlabel about the single label nature of
 	 * this host so that incoming packets get labeled.
+	 * but only if we didn't get the special CIPSO option
 	 */
-
-	if (rc == 0)
+	if (rc == 0 && sp != smack_cipso_option)
 		rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
 			&skp->smk_host.sin_addr, &skp->smk_mask, PF_INET,
 			smack_to_secid(skp->smk_label), &audit_info);


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] Labeled networking patches for 2.6.30
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
                   ` (5 preceding siblings ...)
  2009-03-27 21:11 ` [PATCH 6/6] smack: Add a new '-CIPSO' option to the network address label configuration Paul Moore
@ 2009-03-27 21:58 ` David Miller
  2009-03-28  0:58   ` James Morris
  2009-03-28  5:16 ` James Morris
  7 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2009-03-27 21:58 UTC (permalink / raw)
  To: paul.moore; +Cc: linux-security-module, selinux, netdev, casey, etienne.basset

From: Paul Moore <paul.moore@hp.com>
Date: Fri, 27 Mar 2009 17:10:20 -0400

> This patchset wraps up all the new labeled networking bits for 2.6.30.  This
> is mostly a fixup/cleanup release with the main focus being to correct the
> TCP labeling of both SELinux and Smack; expect some of this to get backported
> to the -stable trees but there will need to be a bit of rework first so it
> may take a few weeks for that to happen.  Other than the TCP issue there is a
> new Smack feature to configure CIPSO aware hosts in "/smack/netlabel" which
> should make the host/network label configuration much more flexible.  The last
> change is to get rid of the security_socket_post_accept() hook which isn't
> currently being used by anything in-tree and seems to act as a magnet for
> bad ideas; if things change we can always add it back later.

Is James Morris going to take this stuff?  Just curious...

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] Labeled networking patches for 2.6.30
  2009-03-27 21:58 ` [PATCH 0/6] Labeled networking patches for 2.6.30 David Miller
@ 2009-03-28  0:58   ` James Morris
  2009-03-28  1:08     ` David Miller
  2009-03-28 12:01     ` Paul Moore
  0 siblings, 2 replies; 15+ messages in thread
From: James Morris @ 2009-03-28  0:58 UTC (permalink / raw)
  To: David Miller
  Cc: paul.moore, linux-security-module, selinux, netdev, casey,
	etienne.basset

On Fri, 27 Mar 2009, David Miller wrote:

> From: Paul Moore <paul.moore@hp.com>
> Date: Fri, 27 Mar 2009 17:10:20 -0400
> 
> > This patchset wraps up all the new labeled networking bits for 2.6.30.  This
> > is mostly a fixup/cleanup release with the main focus being to correct the
> > TCP labeling of both SELinux and Smack; expect some of this to get backported
> > to the -stable trees but there will need to be a bit of rework first so it
> > may take a few weeks for that to happen.  Other than the TCP issue there is a
> > new Smack feature to configure CIPSO aware hosts in "/smack/netlabel" which
> > should make the host/network label configuration much more flexible.  The last
> > change is to get rid of the security_socket_post_accept() hook which isn't
> > currently being used by anything in-tree and seems to act as a magnet for
> > bad ideas; if things change we can always add it back later.
> 
> Is James Morris going to take this stuff?  Just curious...

I will unless you specifically want it.

Paul: it's probably a good idea to have this in my tree before the merge 
window opens.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] Labeled networking patches for 2.6.30
  2009-03-28  0:58   ` James Morris
@ 2009-03-28  1:08     ` David Miller
  2009-03-28 12:01     ` Paul Moore
  1 sibling, 0 replies; 15+ messages in thread
From: David Miller @ 2009-03-28  1:08 UTC (permalink / raw)
  To: jmorris
  Cc: paul.moore, linux-security-module, selinux, netdev, casey,
	etienne.basset

From: James Morris <jmorris@namei.org>
Date: Sat, 28 Mar 2009 11:58:52 +1100 (EST)

> On Fri, 27 Mar 2009, David Miller wrote:
> 
> > From: Paul Moore <paul.moore@hp.com>
> > Date: Fri, 27 Mar 2009 17:10:20 -0400
> > 
> > > This patchset wraps up all the new labeled networking bits for 2.6.30.  This
> > > is mostly a fixup/cleanup release with the main focus being to correct the
> > > TCP labeling of both SELinux and Smack; expect some of this to get backported
> > > to the -stable trees but there will need to be a bit of rework first so it
> > > may take a few weeks for that to happen.  Other than the TCP issue there is a
> > > new Smack feature to configure CIPSO aware hosts in "/smack/netlabel" which
> > > should make the host/network label configuration much more flexible.  The last
> > > change is to get rid of the security_socket_post_accept() hook which isn't
> > > currently being used by anything in-tree and seems to act as a magnet for
> > > bad ideas; if things change we can always add it back later.
> > 
> > Is James Morris going to take this stuff?  Just curious...
> 
> I will unless you specifically want it.

Nope, it's all your's :-)

Thanks!

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] netlabel: Label incoming TCP connections correctly in SELinux
  2009-03-27 21:10 ` [PATCH 2/6] netlabel: Label incoming TCP connections correctly in SELinux Paul Moore
@ 2009-03-28  3:03   ` Casey Schaufler
  0 siblings, 0 replies; 15+ messages in thread
From: Casey Schaufler @ 2009-03-28  3:03 UTC (permalink / raw)
  To: Paul Moore
  Cc: linux-security-module, selinux, netdev, etienne.basset,
	Casey Schaufler

Paul Moore wrote:
> The current NetLabel/SELinux behavior for incoming TCP connections works but
> only through a series of happy coincidences that rely on the limited nature of
> standard CIPSO (only able to convey MLS attributes) and the write equality
> imposed by the SELinux MLS constraints.  The problem is that network sockets
> created as the result of an incoming TCP connection were not on-the-wire
> labeled based on the security attributes of the parent socket but rather based
> on the wire label of the remote peer.  The issue had to do with how IP options
> were managed as part of the network stack and where the LSM hooks were in
> relation to the code which set the IP options on these newly created child
> sockets.  While NetLabel/SELinux did correctly set the socket's on-the-wire
> label it was promptly cleared by the network stack and reset based on the IP
> options of the remote peer.
>
> This patch, in conjunction with a prior patch that adjusted the LSM hook
> locations, works to set the correct on-the-wire label format for new incoming
> connections through the security_inet_conn_request() hook.  Besides the
> correct behavior there are many advantages to this change, the most significant
> is that all of the NetLabel socket labeling code in SELinux now lives in hooks
> which can return error codes to the core stack which allows us to finally get
> ride of the selinux_netlbl_inode_permission() logic which greatly simplfies
> the NetLabel/SELinux glue code.  In the process of developing this patch I
> also ran into a small handful of AF_INET6 cleanliness issues that have been
> fixed which should make the code safer and easier to extend in the future.
>
> Signed-off-by: Paul Moore <paul.moore@hp.com>
>   

Acked-by: Casey Schaufler <casey@schaufler-ca.com>


> ---
>
>  include/net/cipso_ipv4.h            |   17 +++
>  include/net/netlabel.h              |   12 ++
>  net/ipv4/cipso_ipv4.c               |  130 ++++++++++++++++++++++--
>  net/netlabel/netlabel_kapi.c        |  152 +++++++++++++++++++++++++----
>  security/selinux/hooks.c            |   54 +++-------
>  security/selinux/include/netlabel.h |   27 ++---
>  security/selinux/netlabel.c         |  186 ++++++++++-------------------------
>  security/smack/smack_lsm.c          |    2 
>  8 files changed, 360 insertions(+), 220 deletions(-)
>
> diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h
> index bedc7f6..abd4436 100644
> --- a/include/net/cipso_ipv4.h
> +++ b/include/net/cipso_ipv4.h
> @@ -40,6 +40,7 @@
>  #include <linux/net.h>
>  #include <linux/skbuff.h>
>  #include <net/netlabel.h>
> +#include <net/request_sock.h>
>  #include <asm/atomic.h>
>  
>  /* known doi values */
> @@ -215,6 +216,10 @@ int cipso_v4_sock_setattr(struct sock *sk,
>  			  const struct netlbl_lsm_secattr *secattr);
>  void cipso_v4_sock_delattr(struct sock *sk);
>  int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
> +int cipso_v4_req_setattr(struct request_sock *req,
> +			 const struct cipso_v4_doi *doi_def,
> +			 const struct netlbl_lsm_secattr *secattr);
> +void cipso_v4_req_delattr(struct request_sock *req);
>  int cipso_v4_skbuff_setattr(struct sk_buff *skb,
>  			    const struct cipso_v4_doi *doi_def,
>  			    const struct netlbl_lsm_secattr *secattr);
> @@ -247,6 +252,18 @@ static inline int cipso_v4_sock_getattr(struct sock *sk,
>  	return -ENOSYS;
>  }
>  
> +static inline int cipso_v4_req_setattr(struct request_sock *req,
> +				       const struct cipso_v4_doi *doi_def,
> +				       const struct netlbl_lsm_secattr *secattr)
> +{
> +	return -ENOSYS;
> +}
> +
> +static inline void cipso_v4_req_delattr(struct request_sock *req)
> +{
> +	return;
> +}
> +
>  static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
>  				      const struct cipso_v4_doi *doi_def,
>  				      const struct netlbl_lsm_secattr *secattr)
> diff --git a/include/net/netlabel.h b/include/net/netlabel.h
> index 749011e..bdb10e5 100644
> --- a/include/net/netlabel.h
> +++ b/include/net/netlabel.h
> @@ -36,6 +36,7 @@
>  #include <linux/in.h>
>  #include <linux/in6.h>
>  #include <net/netlink.h>
> +#include <net/request_sock.h>
>  #include <asm/atomic.h>
>  
>  struct cipso_v4_doi;
> @@ -406,6 +407,7 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
>   */
>  int netlbl_enabled(void);
>  int netlbl_sock_setattr(struct sock *sk,
> +			u16 family,
>  			const struct netlbl_lsm_secattr *secattr);
>  void netlbl_sock_delattr(struct sock *sk);
>  int netlbl_sock_getattr(struct sock *sk,
> @@ -413,6 +415,8 @@ int netlbl_sock_getattr(struct sock *sk,
>  int netlbl_conn_setattr(struct sock *sk,
>  			struct sockaddr *addr,
>  			const struct netlbl_lsm_secattr *secattr);
> +int netlbl_req_setattr(struct request_sock *req,
> +		       const struct netlbl_lsm_secattr *secattr);
>  int netlbl_skbuff_setattr(struct sk_buff *skb,
>  			  u16 family,
>  			  const struct netlbl_lsm_secattr *secattr);
> @@ -519,7 +523,8 @@ static inline int netlbl_enabled(void)
>  	return 0;
>  }
>  static inline int netlbl_sock_setattr(struct sock *sk,
> -				     const struct netlbl_lsm_secattr *secattr)
> +				      u16 family,
> +				      const struct netlbl_lsm_secattr *secattr)
>  {
>  	return -ENOSYS;
>  }
> @@ -537,6 +542,11 @@ static inline int netlbl_conn_setattr(struct sock *sk,
>  {
>  	return -ENOSYS;
>  }
> +static inline int netlbl_req_setattr(struct request_sock *req,
> +				     const struct netlbl_lsm_secattr *secattr)
> +{
> +	return -ENOSYS;
> +}
>  static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
>  				      u16 family,
>  				      const struct netlbl_lsm_secattr *secattr)
> diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
> index 7bc9929..039cc1f 100644
> --- a/net/ipv4/cipso_ipv4.c
> +++ b/net/ipv4/cipso_ipv4.c
> @@ -1942,23 +1942,85 @@ socket_setattr_failure:
>  }
>  
>  /**
> - * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
> - * @sk: the socket
> + * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket
> + * @req: the connection request socket
> + * @doi_def: the CIPSO DOI to use
> + * @secattr: the specific security attributes of the socket
>   *
>   * Description:
> - * Removes the CIPSO option from a socket, if present.
> + * Set the CIPSO option on the given socket using the DOI definition and
> + * security attributes passed to the function.  Returns zero on success and
> + * negative values on failure.
>   *
>   */
> -void cipso_v4_sock_delattr(struct sock *sk)
> +int cipso_v4_req_setattr(struct request_sock *req,
> +			 const struct cipso_v4_doi *doi_def,
> +			 const struct netlbl_lsm_secattr *secattr)
>  {
> -	u8 hdr_delta;
> -	struct ip_options *opt;
> -	struct inet_sock *sk_inet;
> +	int ret_val = -EPERM;
> +	unsigned char *buf = NULL;
> +	u32 buf_len;
> +	u32 opt_len;
> +	struct ip_options *opt = NULL;
> +	struct inet_request_sock *req_inet;
>  
> -	sk_inet = inet_sk(sk);
> -	opt = sk_inet->opt;
> -	if (opt == NULL || opt->cipso == 0)
> -		return;
> +	/* We allocate the maximum CIPSO option size here so we are probably
> +	 * being a little wasteful, but it makes our life _much_ easier later
> +	 * on and after all we are only talking about 40 bytes. */
> +	buf_len = CIPSO_V4_OPT_LEN_MAX;
> +	buf = kmalloc(buf_len, GFP_ATOMIC);
> +	if (buf == NULL) {
> +		ret_val = -ENOMEM;
> +		goto req_setattr_failure;
> +	}
> +
> +	ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
> +	if (ret_val < 0)
> +		goto req_setattr_failure;
> +	buf_len = ret_val;
> +
> +	/* We can't use ip_options_get() directly because it makes a call to
> +	 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
> +	 * we won't always have CAP_NET_RAW even though we _always_ want to
> +	 * set the IPOPT_CIPSO option. */
> +	opt_len = (buf_len + 3) & ~3;
> +	opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
> +	if (opt == NULL) {
> +		ret_val = -ENOMEM;
> +		goto req_setattr_failure;
> +	}
> +	memcpy(opt->__data, buf, buf_len);
> +	opt->optlen = opt_len;
> +	opt->cipso = sizeof(struct iphdr);
> +	kfree(buf);
> +	buf = NULL;
> +
> +	req_inet = inet_rsk(req);
> +	opt = xchg(&req_inet->opt, opt);
> +	kfree(opt);
> +
> +	return 0;
> +
> +req_setattr_failure:
> +	kfree(buf);
> +	kfree(opt);
> +	return ret_val;
> +}
> +
> +/**
> + * cipso_v4_delopt - Delete the CIPSO option from a set of IP options
> + * @opt_ptr: IP option pointer
> + *
> + * Description:
> + * Deletes the CIPSO IP option from a set of IP options and makes the necessary
> + * adjustments to the IP option structure.  Returns zero on success, negative
> + * values on failure.
> + *
> + */
> +int cipso_v4_delopt(struct ip_options **opt_ptr)
> +{
> +	int hdr_delta = 0;
> +	struct ip_options *opt = *opt_ptr;
>  
>  	if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
>  		u8 cipso_len;
> @@ -2003,11 +2065,34 @@ void cipso_v4_sock_delattr(struct sock *sk)
>  	} else {
>  		/* only the cipso option was present on the socket so we can
>  		 * remove the entire option struct */
> -		sk_inet->opt = NULL;
> +		*opt_ptr = NULL;
>  		hdr_delta = opt->optlen;
>  		kfree(opt);
>  	}
>  
> +	return hdr_delta;
> +}
> +
> +/**
> + * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
> + * @sk: the socket
> + *
> + * Description:
> + * Removes the CIPSO option from a socket, if present.
> + *
> + */
> +void cipso_v4_sock_delattr(struct sock *sk)
> +{
> +	int hdr_delta;
> +	struct ip_options *opt;
> +	struct inet_sock *sk_inet;
> +
> +	sk_inet = inet_sk(sk);
> +	opt = sk_inet->opt;
> +	if (opt == NULL || opt->cipso == 0)
> +		return;
> +
> +	hdr_delta = cipso_v4_delopt(&sk_inet->opt);
>  	if (sk_inet->is_icsk && hdr_delta > 0) {
>  		struct inet_connection_sock *sk_conn = inet_csk(sk);
>  		sk_conn->icsk_ext_hdr_len -= hdr_delta;
> @@ -2016,6 +2101,27 @@ void cipso_v4_sock_delattr(struct sock *sk)
>  }
>  
>  /**
> + * cipso_v4_req_delattr - Delete the CIPSO option from a request socket
> + * @reg: the request socket
> + *
> + * Description:
> + * Removes the CIPSO option from a request socket, if present.
> + *
> + */
> +void cipso_v4_req_delattr(struct request_sock *req)
> +{
> +	struct ip_options *opt;
> +	struct inet_request_sock *req_inet;
> +
> +	req_inet = inet_rsk(req);
> +	opt = req_inet->opt;
> +	if (opt == NULL || opt->cipso == 0)
> +		return;
> +
> +	cipso_v4_delopt(&req_inet->opt);
> +}
> +
> +/**
>   * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
>   * @cipso: the CIPSO v4 option
>   * @secattr: the security attributes
> diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
> index fd9229d..cae2f5f 100644
> --- a/net/netlabel/netlabel_kapi.c
> +++ b/net/netlabel/netlabel_kapi.c
> @@ -619,8 +619,9 @@ int netlbl_enabled(void)
>  }
>  
>  /**
> - * netlbl_socket_setattr - Label a socket using the correct protocol
> + * netlbl_sock_setattr - Label a socket using the correct protocol
>   * @sk: the socket to label
> + * @family: protocol family
>   * @secattr: the security attributes
>   *
>   * Description:
> @@ -633,29 +634,45 @@ int netlbl_enabled(void)
>   *
>   */
>  int netlbl_sock_setattr(struct sock *sk,
> +			u16 family,
>  			const struct netlbl_lsm_secattr *secattr)
>  {
> -	int ret_val = -ENOENT;
> +	int ret_val;
>  	struct netlbl_dom_map *dom_entry;
>  
>  	rcu_read_lock();
>  	dom_entry = netlbl_domhsh_getentry(secattr->domain);
> -	if (dom_entry == NULL)
> +	if (dom_entry == NULL) {
> +		ret_val = -ENOENT;
>  		goto socket_setattr_return;
> -	switch (dom_entry->type) {
> -	case NETLBL_NLTYPE_ADDRSELECT:
> -		ret_val = -EDESTADDRREQ;
> -		break;
> -	case NETLBL_NLTYPE_CIPSOV4:
> -		ret_val = cipso_v4_sock_setattr(sk,
> -						dom_entry->type_def.cipsov4,
> -						secattr);
> +	}
> +	switch (family) {
> +	case AF_INET:
> +		switch (dom_entry->type) {
> +		case NETLBL_NLTYPE_ADDRSELECT:
> +			ret_val = -EDESTADDRREQ;
> +			break;
> +		case NETLBL_NLTYPE_CIPSOV4:
> +			ret_val = cipso_v4_sock_setattr(sk,
> +						    dom_entry->type_def.cipsov4,
> +						    secattr);
> +			break;
> +		case NETLBL_NLTYPE_UNLABELED:
> +			ret_val = 0;
> +			break;
> +		default:
> +			ret_val = -ENOENT;
> +		}
>  		break;
> -	case NETLBL_NLTYPE_UNLABELED:
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	case AF_INET6:
> +		/* since we don't support any IPv6 labeling protocols right
> +		 * now we can optimize everything away until we do */
>  		ret_val = 0;
>  		break;
> +#endif /* IPv6 */
>  	default:
> -		ret_val = -ENOENT;
> +		ret_val = -EPROTONOSUPPORT;
>  	}
>  
>  socket_setattr_return:
> @@ -689,9 +706,25 @@ void netlbl_sock_delattr(struct sock *sk)
>   * on failure.
>   *
>   */
> -int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
> +int netlbl_sock_getattr(struct sock *sk,
> +			struct netlbl_lsm_secattr *secattr)
>  {
> -	return cipso_v4_sock_getattr(sk, secattr);
> +	int ret_val;
> +
> +	switch (sk->sk_family) {
> +	case AF_INET:
> +		ret_val = cipso_v4_sock_getattr(sk, secattr);
> +		break;
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	case AF_INET6:
> +		ret_val = -ENOMSG;
> +		break;
> +#endif /* IPv6 */
> +	default:
> +		ret_val = -EPROTONOSUPPORT;
> +	}
> +
> +	return ret_val;
>  }
>  
>  /**
> @@ -748,7 +781,7 @@ int netlbl_conn_setattr(struct sock *sk,
>  		break;
>  #endif /* IPv6 */
>  	default:
> -		ret_val = 0;
> +		ret_val = -EPROTONOSUPPORT;
>  	}
>  
>  conn_setattr_return:
> @@ -757,6 +790,77 @@ conn_setattr_return:
>  }
>  
>  /**
> + * netlbl_req_setattr - Label a request socket using the correct protocol
> + * @req: the request socket to label
> + * @secattr: the security attributes
> + *
> + * Description:
> + * Attach the correct label to the given socket using the security attributes
> + * specified in @secattr.  Returns zero on success, negative values on failure.
> + *
> + */
> +int netlbl_req_setattr(struct request_sock *req,
> +		       const struct netlbl_lsm_secattr *secattr)
> +{
> +	int ret_val;
> +	struct netlbl_dom_map *dom_entry;
> +	struct netlbl_domaddr4_map *af4_entry;
> +	u32 proto_type;
> +	struct cipso_v4_doi *proto_cv4;
> +
> +	rcu_read_lock();
> +	dom_entry = netlbl_domhsh_getentry(secattr->domain);
> +	if (dom_entry == NULL) {
> +		ret_val = -ENOENT;
> +		goto req_setattr_return;
> +	}
> +	switch (req->rsk_ops->family) {
> +	case AF_INET:
> +		if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) {
> +			struct inet_request_sock *req_inet = inet_rsk(req);
> +			af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
> +							    req_inet->rmt_addr);
> +			if (af4_entry == NULL) {
> +				ret_val = -ENOENT;
> +				goto req_setattr_return;
> +			}
> +			proto_type = af4_entry->type;
> +			proto_cv4 = af4_entry->type_def.cipsov4;
> +		} else {
> +			proto_type = dom_entry->type;
> +			proto_cv4 = dom_entry->type_def.cipsov4;
> +		}
> +		switch (proto_type) {
> +		case NETLBL_NLTYPE_CIPSOV4:
> +			ret_val = cipso_v4_req_setattr(req, proto_cv4, secattr);
> +			break;
> +		case NETLBL_NLTYPE_UNLABELED:
> +			/* just delete the protocols we support for right now
> +			 * but we could remove other protocols if needed */
> +			cipso_v4_req_delattr(req);
> +			ret_val = 0;
> +			break;
> +		default:
> +			ret_val = -ENOENT;
> +		}
> +		break;
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	case AF_INET6:
> +		/* since we don't support any IPv6 labeling protocols right
> +		 * now we can optimize everything away until we do */
> +		ret_val = 0;
> +		break;
> +#endif /* IPv6 */
> +	default:
> +		ret_val = -EPROTONOSUPPORT;
> +	}
> +
> +req_setattr_return:
> +	rcu_read_unlock();
> +	return ret_val;
> +}
> +
> +/**
>   * netlbl_skbuff_setattr - Label a packet using the correct protocol
>   * @skb: the packet
>   * @family: protocol family
> @@ -808,7 +912,7 @@ int netlbl_skbuff_setattr(struct sk_buff *skb,
>  		break;
>  #endif /* IPv6 */
>  	default:
> -		ret_val = 0;
> +		ret_val = -EPROTONOSUPPORT;
>  	}
>  
>  skbuff_setattr_return:
> @@ -833,9 +937,17 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
>  			  u16 family,
>  			  struct netlbl_lsm_secattr *secattr)
>  {
> -	if (CIPSO_V4_OPTEXIST(skb) &&
> -	    cipso_v4_skbuff_getattr(skb, secattr) == 0)
> -		return 0;
> +	switch (family) {
> +	case AF_INET:
> +		if (CIPSO_V4_OPTEXIST(skb) &&
> +		    cipso_v4_skbuff_getattr(skb, secattr) == 0)
> +			return 0;
> +		break;
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	case AF_INET6:
> +		break;
> +#endif /* IPv6 */
> +	}
>  
>  	return netlbl_unlabel_getattr(skb, family, secattr);
>  }
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 7c52ba2..ee2e781 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -311,7 +311,7 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
>  	ssec->sid = SECINITSID_UNLABELED;
>  	sk->sk_security = ssec;
>  
> -	selinux_netlbl_sk_security_reset(ssec, family);
> +	selinux_netlbl_sk_security_reset(ssec);
>  
>  	return 0;
>  }
> @@ -2945,7 +2945,6 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
>  static int selinux_revalidate_file_permission(struct file *file, int mask)
>  {
>  	const struct cred *cred = current_cred();
> -	int rc;
>  	struct inode *inode = file->f_path.dentry->d_inode;
>  
>  	if (!mask) {
> @@ -2957,29 +2956,15 @@ static int selinux_revalidate_file_permission(struct file *file, int mask)
>  	if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
>  		mask |= MAY_APPEND;
>  
> -	rc = file_has_perm(cred, file,
> -			   file_mask_to_av(inode->i_mode, mask));
> -	if (rc)
> -		return rc;
> -
> -	return selinux_netlbl_inode_permission(inode, mask);
> +	return file_has_perm(cred, file,
> +			     file_mask_to_av(inode->i_mode, mask));
>  }
>  
>  static int selinux_file_permission(struct file *file, int mask)
>  {
> -	struct inode *inode = file->f_path.dentry->d_inode;
> -	struct file_security_struct *fsec = file->f_security;
> -	struct inode_security_struct *isec = inode->i_security;
> -	u32 sid = current_sid();
> -
> -	if (!mask) {
> +	if (!mask)
>  		/* No permission to check.  Existence test. */
>  		return 0;
> -	}
> -
> -	if (sid == fsec->sid && fsec->isid == isec->sid
> -	    && fsec->pseqno == avc_policy_seqno())
> -		return selinux_netlbl_inode_permission(inode, mask);
>  
>  	return selinux_revalidate_file_permission(file, mask);
>  }
> @@ -3723,7 +3708,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
>  		sksec = sock->sk->sk_security;
>  		sksec->sid = isec->sid;
>  		sksec->sclass = isec->sclass;
> -		err = selinux_netlbl_socket_post_create(sock);
> +		err = selinux_netlbl_socket_post_create(sock->sk, family);
>  	}
>  
>  	return err;
> @@ -3914,13 +3899,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
>  static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
>  				  int size)
>  {
> -	int rc;
> -
> -	rc = socket_has_perm(current, sock, SOCKET__WRITE);
> -	if (rc)
> -		return rc;
> -
> -	return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE);
> +	return socket_has_perm(current, sock, SOCKET__WRITE);
>  }
>  
>  static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
> @@ -4304,7 +4283,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
>  	newssec->peer_sid = ssec->peer_sid;
>  	newssec->sclass = ssec->sclass;
>  
> -	selinux_netlbl_sk_security_reset(newssec, newsk->sk_family);
> +	selinux_netlbl_sk_security_reset(newssec);
>  }
>  
>  static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
> @@ -4348,16 +4327,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
>  	if (peersid == SECSID_NULL) {
>  		req->secid = sksec->sid;
>  		req->peer_secid = SECSID_NULL;
> -		return 0;
> +	} else {
> +		err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
> +		if (err)
> +			return err;
> +		req->secid = newsid;
> +		req->peer_secid = peersid;
>  	}
>  
> -	err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
> -	if (err)
> -		return err;
> -
> -	req->secid = newsid;
> -	req->peer_secid = peersid;
> -	return 0;
> +	return selinux_netlbl_inet_conn_request(req, family);
>  }
>  
>  static void selinux_inet_csk_clone(struct sock *newsk,
> @@ -4374,7 +4352,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
>  
>  	/* We don't need to take any sort of lock here as we are the only
>  	 * thread with access to newsksec */
> -	selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family);
> +	selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
>  }
>  
>  static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
> @@ -4387,8 +4365,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
>  		family = PF_INET;
>  
>  	selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
> -
> -	selinux_netlbl_inet_conn_established(sk, family);
>  }
>  
>  static void selinux_req_classify_flow(const struct request_sock *req,
> diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
> index b913c8d..b4b5b9b 100644
> --- a/security/selinux/include/netlabel.h
> +++ b/security/selinux/include/netlabel.h
> @@ -32,6 +32,7 @@
>  #include <linux/net.h>
>  #include <linux/skbuff.h>
>  #include <net/sock.h>
> +#include <net/request_sock.h>
>  
>  #include "avc.h"
>  #include "objsec.h"
> @@ -42,8 +43,7 @@ void selinux_netlbl_cache_invalidate(void);
>  void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
>  
>  void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
> -void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
> -				      int family);
> +void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec);
>  
>  int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
>  				 u16 family,
> @@ -53,9 +53,9 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
>  				 u16 family,
>  				 u32 sid);
>  
> -void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family);
> -int selinux_netlbl_socket_post_create(struct socket *sock);
> -int selinux_netlbl_inode_permission(struct inode *inode, int mask);
> +int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
> +void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
> +int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
>  int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
>  				struct sk_buff *skb,
>  				u16 family,
> @@ -85,8 +85,7 @@ static inline void selinux_netlbl_sk_security_free(
>  }
>  
>  static inline void selinux_netlbl_sk_security_reset(
> -					       struct sk_security_struct *ssec,
> -					       int family)
> +					       struct sk_security_struct *ssec)
>  {
>  	return;
>  }
> @@ -113,17 +112,17 @@ static inline int selinux_netlbl_conn_setsid(struct sock *sk,
>  	return 0;
>  }
>  
> -static inline void selinux_netlbl_inet_conn_established(struct sock *sk,
> -							u16 family)
> +static inline int selinux_netlbl_inet_conn_request(struct request_sock *req,
> +						   u16 family)
>  {
> -	return;
> +	return 0;
>  }
> -static inline int selinux_netlbl_socket_post_create(struct socket *sock)
> +static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
>  {
> -	return 0;
> +	return;
>  }
> -static inline int selinux_netlbl_inode_permission(struct inode *inode,
> -						  int mask)
> +static inline int selinux_netlbl_socket_post_create(struct sock *sk,
> +						    u16 family)
>  {
>  	return 0;
>  }
> diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
> index 350794a..2e98441 100644
> --- a/security/selinux/netlabel.c
> +++ b/security/selinux/netlabel.c
> @@ -100,41 +100,6 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
>  }
>  
>  /**
> - * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
> - * @sk: the socket to label
> - *
> - * Description:
> - * Attempt to label a socket using the NetLabel mechanism.  Returns zero values
> - * on success, negative values on failure.
> - *
> - */
> -static int selinux_netlbl_sock_setsid(struct sock *sk)
> -{
> -	int rc;
> -	struct sk_security_struct *sksec = sk->sk_security;
> -	struct netlbl_lsm_secattr *secattr;
> -
> -	if (sksec->nlbl_state != NLBL_REQUIRE)
> -		return 0;
> -
> -	secattr = selinux_netlbl_sock_genattr(sk);
> -	if (secattr == NULL)
> -		return -ENOMEM;
> -	rc = netlbl_sock_setattr(sk, secattr);
> -	switch (rc) {
> -	case 0:
> -		sksec->nlbl_state = NLBL_LABELED;
> -		break;
> -	case -EDESTADDRREQ:
> -		sksec->nlbl_state = NLBL_REQSKB;
> -		rc = 0;
> -		break;
> -	}
> -
> -	return rc;
> -}
> -
> -/**
>   * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
>   *
>   * Description:
> @@ -188,13 +153,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
>   * The caller is responsibile for all the NetLabel sk_security_struct locking.
>   *
>   */
> -void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
> -				      int family)
> +void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec)
>  {
> -	if (family == PF_INET)
> -		ssec->nlbl_state = NLBL_REQUIRE;
> -	else
> -		ssec->nlbl_state = NLBL_UNSET;
> +	ssec->nlbl_state = NLBL_UNSET;
>  }
>  
>  /**
> @@ -281,127 +242,86 @@ skbuff_setsid_return:
>  }
>  
>  /**
> - * selinux_netlbl_inet_conn_established - Netlabel the newly accepted connection
> - * @sk: the new connection
> + * selinux_netlbl_inet_conn_request - Label an incoming stream connection
> + * @req: incoming connection request socket
>   *
>   * Description:
> - * A new connection has been established on @sk so make sure it is labeled
> - * correctly with the NetLabel susbsystem.
> + * A new incoming connection request is represented by @req, we need to label
> + * the new request_sock here and the stack will ensure the on-the-wire label
> + * will get preserved when a full sock is created once the connection handshake
> + * is complete.  Returns zero on success, negative values on failure.
>   *
>   */
> -void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family)
> +int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
>  {
>  	int rc;
> -	struct sk_security_struct *sksec = sk->sk_security;
> -	struct netlbl_lsm_secattr *secattr;
> -	struct inet_sock *sk_inet = inet_sk(sk);
> -	struct sockaddr_in addr;
> -
> -	if (sksec->nlbl_state != NLBL_REQUIRE)
> -		return;
> +	struct netlbl_lsm_secattr secattr;
>  
> -	secattr = selinux_netlbl_sock_genattr(sk);
> -	if (secattr == NULL)
> -		return;
> +	if (family != PF_INET)
> +		return 0;
>  
> -	rc = netlbl_sock_setattr(sk, secattr);
> -	switch (rc) {
> -	case 0:
> -		sksec->nlbl_state = NLBL_LABELED;
> -		break;
> -	case -EDESTADDRREQ:
> -		/* no PF_INET6 support yet because we don't support any IPv6
> -		 * labeling protocols */
> -		if (family != PF_INET) {
> -			sksec->nlbl_state = NLBL_UNSET;
> -			return;
> -		}
> -
> -		addr.sin_family = family;
> -		addr.sin_addr.s_addr = sk_inet->daddr;
> -		if (netlbl_conn_setattr(sk, (struct sockaddr *)&addr,
> -					secattr) != 0) {
> -			/* we failed to label the connected socket (could be
> -			 * for a variety of reasons, the actual "why" isn't
> -			 * important here) so we have to go to our backup plan,
> -			 * labeling the packets individually in the netfilter
> -			 * local output hook.  this is okay but we need to
> -			 * adjust the MSS of the connection to take into
> -			 * account any labeling overhead, since we don't know
> -			 * the exact overhead at this point we'll use the worst
> -			 * case value which is 40 bytes for IPv4 */
> -			struct inet_connection_sock *sk_conn = inet_csk(sk);
> -			sk_conn->icsk_ext_hdr_len += 40 -
> -				      (sk_inet->opt ? sk_inet->opt->optlen : 0);
> -			sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
> -
> -			sksec->nlbl_state = NLBL_REQSKB;
> -		} else
> -			sksec->nlbl_state = NLBL_CONNLABELED;
> -		break;
> -	default:
> -		/* note that we are failing to label the socket which could be
> -		 * a bad thing since it means traffic could leave the system
> -		 * without the desired labeling, however, all is not lost as
> -		 * we have a check in selinux_netlbl_inode_permission() to
> -		 * pick up the pieces that we might drop here because we can't
> -		 * return an error code */
> -		break;
> -	}
> +	netlbl_secattr_init(&secattr);
> +	rc = security_netlbl_sid_to_secattr(req->secid, &secattr);
> +	if (rc != 0)
> +		goto inet_conn_request_return;
> +	rc = netlbl_req_setattr(req, &secattr);
> +inet_conn_request_return:
> +	netlbl_secattr_destroy(&secattr);
> +	return rc;
>  }
>  
>  /**
> - * selinux_netlbl_socket_post_create - Label a socket using NetLabel
> - * @sock: the socket to label
> + * selinux_netlbl_inet_csk_clone - Initialize the newly created sock
> + * @sk: the new sock
>   *
>   * Description:
> - * Attempt to label a socket using the NetLabel mechanism using the given
> - * SID.  Returns zero values on success, negative values on failure.
> + * A new connection has been established using @sk, we've already labeled the
> + * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but
> + * we need to set the NetLabel state here since we now have a sock structure.
>   *
>   */
> -int selinux_netlbl_socket_post_create(struct socket *sock)
> +void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
>  {
> -	return selinux_netlbl_sock_setsid(sock->sk);
> +	struct sk_security_struct *sksec = sk->sk_security;
> +
> +	if (family == PF_INET)
> +		sksec->nlbl_state = NLBL_LABELED;
> +	else
> +		sksec->nlbl_state = NLBL_UNSET;
>  }
>  
>  /**
> - * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled
> - * @inode: the file descriptor's inode
> - * @mask: the permission mask
> + * selinux_netlbl_socket_post_create - Label a socket using NetLabel
> + * @sock: the socket to label
> + * @family: protocol family
>   *
>   * Description:
> - * Looks at a file's inode and if it is marked as a socket protected by
> - * NetLabel then verify that the socket has been labeled, if not try to label
> - * the socket now with the inode's SID.  Returns zero on success, negative
> - * values on failure.
> + * Attempt to label a socket using the NetLabel mechanism using the given
> + * SID.  Returns zero values on success, negative values on failure.
>   *
>   */
> -int selinux_netlbl_inode_permission(struct inode *inode, int mask)
> +int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
>  {
>  	int rc;
> -	struct sock *sk;
> -	struct socket *sock;
> -	struct sk_security_struct *sksec;
> +	struct sk_security_struct *sksec = sk->sk_security;
> +	struct netlbl_lsm_secattr *secattr;
>  
> -	if (!S_ISSOCK(inode->i_mode) ||
> -	    ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
> -		return 0;
> -	sock = SOCKET_I(inode);
> -	sk = sock->sk;
> -	if (sk == NULL)
> -		return 0;
> -	sksec = sk->sk_security;
> -	if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE)
> +	if (family != PF_INET)
>  		return 0;
>  
> -	local_bh_disable();
> -	bh_lock_sock_nested(sk);
> -	if (likely(sksec->nlbl_state == NLBL_REQUIRE))
> -		rc = selinux_netlbl_sock_setsid(sk);
> -	else
> +	secattr = selinux_netlbl_sock_genattr(sk);
> +	if (secattr == NULL)
> +		return -ENOMEM;
> +	rc = netlbl_sock_setattr(sk, family, secattr);
> +	switch (rc) {
> +	case 0:
> +		sksec->nlbl_state = NLBL_LABELED;
> +		break;
> +	case -EDESTADDRREQ:
> +		sksec->nlbl_state = NLBL_REQSKB;
>  		rc = 0;
> -	bh_unlock_sock(sk);
> -	local_bh_enable();
> +		break;
> +	}
>  
>  	return rc;
>  }
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index fd20d15..23ad420 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -1387,7 +1387,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
>  	else {
>  		netlbl_secattr_init(&secattr);
>  		smack_to_secattr(ssp->smk_out, &secattr);
> -		rc = netlbl_sock_setattr(sk, &secattr);
> +		rc = netlbl_sock_setattr(sk, sk->sk_family, &secattr);
>  		netlbl_secattr_destroy(&secattr);
>  	}
>  
>
>
>   


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/6] netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections
  2009-03-27 21:10 ` [PATCH 5/6] netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections Paul Moore
@ 2009-03-28  3:04   ` Casey Schaufler
  0 siblings, 0 replies; 15+ messages in thread
From: Casey Schaufler @ 2009-03-28  3:04 UTC (permalink / raw)
  To: Paul Moore; +Cc: linux-security-module, selinux, netdev, etienne.basset

Paul Moore wrote:
> This patch cleans up a lot of the Smack network access control code.  The
> largest changes are to fix the labeling of incoming TCP connections in a
> manner similar to the recent SELinux changes which use the
> security_inet_conn_request() hook to label the request_sock and let the label
> move to the child socket via the normal network stack mechanisms.  In addition
> to the incoming TCP connection fixes this patch also removes the smk_labled
> field from the socket_smack struct as the minor optimization advantage was
> outweighed by the difficulty in maintaining it's proper state.
>
> Signed-off-by: Paul Moore <paul.moore@hp.com>
>   

Acked-by: Casey Schaufler <casey@schaufler-ca.com>


> ---
>
>  include/net/netlabel.h       |    5 +
>  net/netlabel/netlabel_kapi.c |   13 ++
>  security/smack/smack.h       |    1 
>  security/smack/smack_lsm.c   |  260 +++++++++++++++++++++++-------------------
>  4 files changed, 161 insertions(+), 118 deletions(-)
>
> diff --git a/include/net/netlabel.h b/include/net/netlabel.h
> index bdb10e5..60ebbc1 100644
> --- a/include/net/netlabel.h
> +++ b/include/net/netlabel.h
> @@ -417,6 +417,7 @@ int netlbl_conn_setattr(struct sock *sk,
>  			const struct netlbl_lsm_secattr *secattr);
>  int netlbl_req_setattr(struct request_sock *req,
>  		       const struct netlbl_lsm_secattr *secattr);
> +void netlbl_req_delattr(struct request_sock *req);
>  int netlbl_skbuff_setattr(struct sk_buff *skb,
>  			  u16 family,
>  			  const struct netlbl_lsm_secattr *secattr);
> @@ -547,6 +548,10 @@ static inline int netlbl_req_setattr(struct request_sock *req,
>  {
>  	return -ENOSYS;
>  }
> +static inline void netlbl_req_delattr(struct request_sock *req)
> +{
> +	return;
> +}
>  static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
>  				      u16 family,
>  				      const struct netlbl_lsm_secattr *secattr)
> diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
> index cae2f5f..b0e582f 100644
> --- a/net/netlabel/netlabel_kapi.c
> +++ b/net/netlabel/netlabel_kapi.c
> @@ -861,6 +861,19 @@ req_setattr_return:
>  }
>  
>  /**
> +* netlbl_req_delattr - Delete all the NetLabel labels on a socket
> +* @req: the socket
> +*
> +* Description:
> +* Remove all the NetLabel labeling from @req.
> +*
> +*/
> +void netlbl_req_delattr(struct request_sock *req)
> +{
> +	cipso_v4_req_delattr(req);
> +}
> +
> +/**
>   * netlbl_skbuff_setattr - Label a packet using the correct protocol
>   * @skb: the packet
>   * @family: protocol family
> diff --git a/security/smack/smack.h b/security/smack/smack.h
> index 64164f8..5e5a3bc 100644
> --- a/security/smack/smack.h
> +++ b/security/smack/smack.h
> @@ -42,7 +42,6 @@ struct superblock_smack {
>  struct socket_smack {
>  	char		*smk_out;			/* outbound label */
>  	char		*smk_in;			/* inbound label */
> -	int		smk_labeled;			/* label scheme */
>  	char		smk_packet[SMK_LABELLEN];	/* TCP peer label */
>  };
>  
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 23ad420..8ed502c 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -7,6 +7,8 @@
>   *	Casey Schaufler <casey@schaufler-ca.com>
>   *
>   *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
> + *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
> + *                Paul Moore <paul.moore@hp.com>
>   *
>   *	This program is free software; you can redistribute it and/or modify
>   *	it under the terms of the GNU General Public License version 2,
> @@ -20,6 +22,7 @@
>  #include <linux/ext2_fs.h>
>  #include <linux/kd.h>
>  #include <asm/ioctls.h>
> +#include <linux/ip.h>
>  #include <linux/tcp.h>
>  #include <linux/udp.h>
>  #include <linux/mutex.h>
> @@ -1275,7 +1278,6 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
>  
>  	ssp->smk_in = csp;
>  	ssp->smk_out = csp;
> -	ssp->smk_labeled = SMACK_CIPSO_SOCKET;
>  	ssp->smk_packet[0] = '\0';
>  
>  	sk->sk_security = ssp;
> @@ -1295,6 +1297,39 @@ static void smack_sk_free_security(struct sock *sk)
>  }
>  
>  /**
> +* smack_host_label - check host based restrictions
> +* @sip: the object end
> +*
> +* looks for host based access restrictions
> +*
> +* This version will only be appropriate for really small sets of single label
> +* hosts.  The caller is responsible for ensuring that the RCU read lock is
> +* taken before calling this function.
> +*
> +* Returns the label of the far end or NULL if it's not special.
> +*/
> +static char *smack_host_label(struct sockaddr_in *sip)
> +{
> +	struct smk_netlbladdr *snp;
> +	struct in_addr *siap = &sip->sin_addr;
> +
> +	if (siap->s_addr == 0)
> +		return NULL;
> +
> +	list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list)
> +		/*
> +		* we break after finding the first match because
> +		* the list is sorted from longest to shortest mask
> +		* so we have found the most specific match
> +		*/
> +		if ((&snp->smk_host.sin_addr)->s_addr ==
> +		    (siap->s_addr & (&snp->smk_mask)->s_addr))
> +			return snp->smk_label;
> +
> +	return NULL;
> +}
> +
> +/**
>   * smack_set_catset - convert a capset to netlabel mls categories
>   * @catset: the Smack categories
>   * @sap: where to put the netlabel categories
> @@ -1365,11 +1400,10 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
>   */
>  static int smack_netlabel(struct sock *sk, int labeled)
>  {
> -	struct socket_smack *ssp;
> +	struct socket_smack *ssp = sk->sk_security;
>  	struct netlbl_lsm_secattr secattr;
>  	int rc = 0;
>  
> -	ssp = sk->sk_security;
>  	/*
>  	 * Usually the netlabel code will handle changing the
>  	 * packet labeling based on the label.
> @@ -1393,21 +1427,45 @@ static int smack_netlabel(struct sock *sk, int labeled)
>  
>  	bh_unlock_sock(sk);
>  	local_bh_enable();
> -	/*
> -	 * Remember the label scheme used so that it is not
> -	 * necessary to do the netlabel setting if it has not
> -	 * changed the next time through.
> -	 *
> -	 * The -EDESTADDRREQ case is an indication that there's
> -	 * a single level host involved.
> -	 */
> -	if (rc == 0)
> -		ssp->smk_labeled = labeled;
>  
>  	return rc;
>  }
>  
>  /**
> + * smack_netlbel_send - Set the secattr on a socket and perform access checks
> + * @sk: the socket
> + * @sap: the destination address
> + *
> + * Set the correct secattr for the given socket based on the destination
> + * address and perform any outbound access checks needed.
> + *
> + * Returns 0 on success or an error code.
> + *
> + */
> +static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
> +{
> +	int rc;
> +	int sk_lbl;
> +	char *hostsp;
> +	struct socket_smack *ssp = sk->sk_security;
> +
> +	rcu_read_lock();
> +	hostsp = smack_host_label(sap);
> +	if (hostsp != NULL) {
> +		sk_lbl = SMACK_UNLABELED_SOCKET;
> +		rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
> +	} else {
> +		sk_lbl = SMACK_CIPSO_SOCKET;
> +		rc = 0;
> +	}
> +	rcu_read_unlock();
> +	if (rc != 0)
> +		return rc;
> +
> +	return smack_netlabel(sk, sk_lbl);
> +}
> +
> +/**
>   * smack_inode_setsecurity - set smack xattrs
>   * @inode: the object
>   * @name: attribute name
> @@ -1488,43 +1546,6 @@ static int smack_socket_post_create(struct socket *sock, int family,
>  	return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
>  }
>  
> -
> -/**
> - * smack_host_label - check host based restrictions
> - * @sip: the object end
> - *
> - * looks for host based access restrictions
> - *
> - * This version will only be appropriate for really small
> - * sets of single label hosts.
> - *
> - * Returns the label of the far end or NULL if it's not special.
> - */
> -static char *smack_host_label(struct sockaddr_in *sip)
> -{
> -	struct smk_netlbladdr *snp;
> -	struct in_addr *siap = &sip->sin_addr;
> -
> -	if (siap->s_addr == 0)
> -		return NULL;
> -
> -	rcu_read_lock();
> -	list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) {
> -		/*
> -		 * we break after finding the first match because
> -		 * the list is sorted from longest to shortest mask
> -		 * so we have found the most specific match
> -		 */
> -		if ((&snp->smk_host.sin_addr)->s_addr  ==
> -			(siap->s_addr & (&snp->smk_mask)->s_addr)) {
> -			rcu_read_unlock();
> -			return snp->smk_label;
> -		}
> -	}
> -	rcu_read_unlock();
> -	return NULL;
> -}
> -
>  /**
>   * smack_socket_connect - connect access check
>   * @sock: the socket
> @@ -1538,30 +1559,12 @@ static char *smack_host_label(struct sockaddr_in *sip)
>  static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
>  				int addrlen)
>  {
> -	struct socket_smack *ssp = sock->sk->sk_security;
> -	char *hostsp;
> -	int rc;
> -
>  	if (sock->sk == NULL || sock->sk->sk_family != PF_INET)
>  		return 0;
> -
>  	if (addrlen < sizeof(struct sockaddr_in))
>  		return -EINVAL;
>  
> -	hostsp = smack_host_label((struct sockaddr_in *)sap);
> -	if (hostsp == NULL) {
> -		if (ssp->smk_labeled != SMACK_CIPSO_SOCKET)
> -			return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
> -		return 0;
> -	}
> -
> -	rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
> -	if (rc != 0)
> -		return rc;
> -
> -	if (ssp->smk_labeled != SMACK_UNLABELED_SOCKET)
> -		return smack_netlabel(sock->sk, SMACK_UNLABELED_SOCKET);
> -	return 0;
> +	return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
>  }
>  
>  /**
> @@ -2262,9 +2265,6 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
>  				int size)
>  {
>  	struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
> -	struct socket_smack *ssp = sock->sk->sk_security;
> -	char *hostsp;
> -	int rc;
>  
>  	/*
>  	 * Perfectly reasonable for this to be NULL
> @@ -2272,22 +2272,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
>  	if (sip == NULL || sip->sin_family != PF_INET)
>  		return 0;
>  
> -	hostsp = smack_host_label(sip);
> -	if (hostsp == NULL) {
> -		if (ssp->smk_labeled != SMACK_CIPSO_SOCKET)
> -			return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
> -		return 0;
> -	}
> -
> -	rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
> -	if (rc != 0)
> -		return rc;
> -
> -	if (ssp->smk_labeled != SMACK_UNLABELED_SOCKET)
> -		return smack_netlabel(sock->sk, SMACK_UNLABELED_SOCKET);
> -
> -	return 0;
> -
> +	return smack_netlabel_send(sock->sk, sip);
>  }
>  
>  
> @@ -2492,31 +2477,24 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
>  }
>  
>  /**
> - * smack_sock_graft - graft access state between two sockets
> - * @sk: fresh sock
> - * @parent: donor socket
> + * smack_sock_graft - Initialize a newly created socket with an existing sock
> + * @sk: child sock
> + * @parent: parent socket
>   *
> - * Sets the netlabel socket state on sk from parent
> + * Set the smk_{in,out} state of an existing sock based on the process that
> + * is creating the new socket.
>   */
>  static void smack_sock_graft(struct sock *sk, struct socket *parent)
>  {
>  	struct socket_smack *ssp;
> -	int rc;
> -
> -	if (sk == NULL)
> -		return;
>  
> -	if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
> +	if (sk == NULL ||
> +	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
>  		return;
>  
>  	ssp = sk->sk_security;
>  	ssp->smk_in = ssp->smk_out = current_security();
> -	ssp->smk_packet[0] = '\0';
> -
> -	rc = smack_netlabel(sk, SMACK_CIPSO_SOCKET);
> -	if (rc != 0)
> -		printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
> -		       __func__, -rc);
> +	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
>  }
>  
>  /**
> @@ -2531,35 +2509,82 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
>  static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
>  				   struct request_sock *req)
>  {
> -	struct netlbl_lsm_secattr skb_secattr;
> +	u16 family = sk->sk_family;
>  	struct socket_smack *ssp = sk->sk_security;
> +	struct netlbl_lsm_secattr secattr;
> +	struct sockaddr_in addr;
> +	struct iphdr *hdr;
>  	char smack[SMK_LABELLEN];
>  	int rc;
>  
> -	if (skb == NULL)
> -		return -EACCES;
> +	/* handle mapped IPv4 packets arriving via IPv6 sockets */
> +	if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
> +		family = PF_INET;
>  
> -	netlbl_secattr_init(&skb_secattr);
> -	rc = netlbl_skbuff_getattr(skb, sk->sk_family, &skb_secattr);
> +	netlbl_secattr_init(&secattr);
> +	rc = netlbl_skbuff_getattr(skb, family, &secattr);
>  	if (rc == 0)
> -		smack_from_secattr(&skb_secattr, smack);
> +		smack_from_secattr(&secattr, smack);
>  	else
>  		strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN);
> -	netlbl_secattr_destroy(&skb_secattr);
> +	netlbl_secattr_destroy(&secattr);
> +
>  	/*
> -	 * Receiving a packet requires that the other end
> -	 * be able to write here. Read access is not required.
> -	 *
> -	 * If the request is successful save the peer's label
> -	 * so that SO_PEERCRED can report it.
> +	 * Receiving a packet requires that the other end be able to write
> +	 * here. Read access is not required.
>  	 */
>  	rc = smk_access(smack, ssp->smk_in, MAY_WRITE);
> -	if (rc == 0)
> -		strncpy(ssp->smk_packet, smack, SMK_MAXLEN);
> +	if (rc != 0)
> +		return rc;
> +
> +	/*
> +	 * Save the peer's label in the request_sock so we can later setup
> +	 * smk_packet in the child socket so that SO_PEERCRED can report it.
> +	 */
> +	req->peer_secid = smack_to_secid(smack);
> +
> +	/*
> +	 * We need to decide if we want to label the incoming connection here
> +	 * if we do we only need to label the request_sock and the stack will
> +	 * propogate the wire-label to the sock when it is created.
> +	 */
> +	hdr = ip_hdr(skb);
> +	addr.sin_addr.s_addr = hdr->saddr;
> +	rcu_read_lock();
> +	if (smack_host_label(&addr) == NULL) {
> +		rcu_read_unlock();
> +		netlbl_secattr_init(&secattr);
> +		smack_to_secattr(smack, &secattr);
> +		rc = netlbl_req_setattr(req, &secattr);
> +		netlbl_secattr_destroy(&secattr);
> +	} else {
> +		rcu_read_unlock();
> +		netlbl_req_delattr(req);
> +	}
>  
>  	return rc;
>  }
>  
> +/**
> + * smack_inet_csk_clone - Copy the connection information to the new socket
> + * @sk: the new socket
> + * @req: the connection's request_sock
> + *
> + * Transfer the connection's peer label to the newly created socket.
> + */
> +static void smack_inet_csk_clone(struct sock *sk,
> +				 const struct request_sock *req)
> +{
> +	struct socket_smack *ssp = sk->sk_security;
> +	char *smack;
> +
> +	if (req->peer_secid != 0) {
> +		smack = smack_from_secid(req->peer_secid);
> +		strncpy(ssp->smk_packet, smack, SMK_MAXLEN);
> +	} else
> +		ssp->smk_packet[0] = '\0';
> +}
> +
>  /*
>   * Key management security hooks
>   *
> @@ -2911,6 +2936,7 @@ struct security_operations smack_ops = {
>  	.sk_free_security = 		smack_sk_free_security,
>  	.sock_graft = 			smack_sock_graft,
>  	.inet_conn_request = 		smack_inet_conn_request,
> +	.inet_csk_clone =		smack_inet_csk_clone,
>  
>   /* key management security hooks */
>  #ifdef CONFIG_KEYS
>
>
>   


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/6] smack: Add a new '-CIPSO' option to the network address label configuration
  2009-03-27 21:11 ` [PATCH 6/6] smack: Add a new '-CIPSO' option to the network address label configuration Paul Moore
@ 2009-03-28  3:05   ` Casey Schaufler
  0 siblings, 0 replies; 15+ messages in thread
From: Casey Schaufler @ 2009-03-28  3:05 UTC (permalink / raw)
  To: Paul Moore
  Cc: linux-security-module, selinux, netdev, etienne.basset,
	Casey Schaufler

Paul Moore wrote:
> From: Etienne Basset <etienne.basset@numericable.fr>
>
> This patch adds a new special option '-CIPSO' to the Smack subsystem. When used
> in the netlabel list, it means "use CIPSO networking". A use case is when your
> local network speaks CIPSO and you want also to connect to the unlabeled
> Internet. This patch also add some documentation describing that. The patch
> also corrects an oops when setting a '' SMACK64 xattr to a file.
>
> Signed-off-by: Etienne Basset <etienne.basset@numericable.fr>
> Signed-off-by: Paul Moore <paul.moore@hp.com>
>   

Acked-by: Casey Schaufler <casey@schaufler-ca.com>


> ---
>
>  Documentation/Smack.txt       |   42 ++++++++++++++++++++++++++++++++++++-----
>  security/smack/smack.h        |    3 +++
>  security/smack/smack_access.c |    3 +++
>  security/smack/smack_lsm.c    |   11 +++++++++--
>  security/smack/smackfs.c      |   38 +++++++++++++++++++++++++++++--------
>  5 files changed, 82 insertions(+), 15 deletions(-)
>
> diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt
> index 989c2fc..629c92e 100644
> --- a/Documentation/Smack.txt
> +++ b/Documentation/Smack.txt
> @@ -184,14 +184,16 @@ length. Single character labels using special characters, that being anything
>  other than a letter or digit, are reserved for use by the Smack development
>  team. Smack labels are unstructured, case sensitive, and the only operation
>  ever performed on them is comparison for equality. Smack labels cannot
> -contain unprintable characters or the "/" (slash) character.
> +contain unprintable characters or the "/" (slash) character. Smack labels
> +cannot begin with a '-', which is reserved for special options.
>  
>  There are some predefined labels:
>  
> -	_ Pronounced "floor", a single underscore character.
> -	^ Pronounced "hat", a single circumflex character.
> -	* Pronounced "star", a single asterisk character.
> -	? Pronounced "huh", a single question mark character.
> +	_ 	Pronounced "floor", a single underscore character.
> +	^ 	Pronounced "hat", a single circumflex character.
> +	* 	Pronounced "star", a single asterisk character.
> +	? 	Pronounced "huh", a single question mark character.
> +	@ 	Pronounced "Internet", a single at sign character.
>  
>  Every task on a Smack system is assigned a label. System tasks, such as
>  init(8) and systems daemons, are run with the floor ("_") label. User tasks
> @@ -412,6 +414,36 @@ sockets.
>  	A privileged program may set this to match the label of another
>  	task with which it hopes to communicate.
>  
> +Smack Netlabel Exceptions
> +
> +You will often find that your labeled application has to talk to the outside,
> +unlabeled world. To do this there's a special file /smack/netlabel where you can
> +add some exceptions in the form of :
> +@IP1	   LABEL1 or
> +@IP2/MASK  LABEL2
> +
> +It means that your application will have unlabeled access to @IP1 if it has
> +write access on LABEL1, and access to the subnet @IP2/MASK if it has write
> +access on LABEL2.
> +
> +Entries in the /smack/netlabel file are matched by longest mask first, like in
> +classless IPv4 routing.
> +
> +A special label '@' and an option '-CIPSO' can be used there :
> +@      means Internet, any application with any label has access to it
> +-CIPSO means standard CIPSO networking
> +
> +If you don't know what CIPSO is and don't plan to use it, you can just do :
> +echo 127.0.0.1 -CIPSO > /smack/netlabel
> +echo 0.0.0.0/0 @      > /smack/netlabel
> +
> +If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
> +Internet access, you can have :
> +echo 127.0.0.1      -CIPSO > /smack/netlabel
> +echo 192.168.0.0/16 -CIPSO > /smack/netlabel
> +echo 0.0.0.0/0      @      > /smack/netlabel
> +
> +
>  Writing Applications for Smack
>  
>  There are three sorts of applications that will run on a Smack system. How an
> diff --git a/security/smack/smack.h b/security/smack/smack.h
> index 5e5a3bc..42ef313 100644
> --- a/security/smack/smack.h
> +++ b/security/smack/smack.h
> @@ -132,6 +132,8 @@ struct smack_known {
>  #define XATTR_NAME_SMACKIPIN	XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
>  #define XATTR_NAME_SMACKIPOUT	XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
>  
> +#define SMACK_CIPSO_OPTION 	"-CIPSO"
> +
>  /*
>   * How communications on this socket are treated.
>   * Usually it's determined by the underlying netlabel code
> @@ -199,6 +201,7 @@ u32 smack_to_secid(const char *);
>  extern int smack_cipso_direct;
>  extern char *smack_net_ambient;
>  extern char *smack_onlycap;
> +extern const char *smack_cipso_option;
>  
>  extern struct smack_known smack_known_floor;
>  extern struct smack_known smack_known_hat;
> diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
> index 5856419..ac0a270 100644
> --- a/security/smack/smack_access.c
> +++ b/security/smack/smack_access.c
> @@ -261,6 +261,9 @@ char *smk_import(const char *string, int len)
>  {
>  	struct smack_known *skp;
>  
> +	/* labels cannot begin with a '-' */
> +	if (string[0] == '-')
> +		return NULL;
>  	skp = smk_import_entry(string, len);
>  	if (skp == NULL)
>  		return NULL;
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 8ed502c..9215149 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -609,6 +609,9 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
>  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
>  		if (!capable(CAP_MAC_ADMIN))
>  			rc = -EPERM;
> +		/* a label cannot be void and cannot begin with '-' */
> +		if (size == 0 || (size > 0 && ((char *)value)[0] == '-'))
> +			rc = -EINVAL;
>  	} else
>  		rc = cap_inode_setxattr(dentry, name, value, size, flags);
>  
> @@ -1323,8 +1326,12 @@ static char *smack_host_label(struct sockaddr_in *sip)
>  		* so we have found the most specific match
>  		*/
>  		if ((&snp->smk_host.sin_addr)->s_addr ==
> -		    (siap->s_addr & (&snp->smk_mask)->s_addr))
> +		    (siap->s_addr & (&snp->smk_mask)->s_addr)) {
> +			/* we have found the special CIPSO option */
> +			if (snp->smk_label == smack_cipso_option)
> +				return NULL;
>  			return snp->smk_label;
> +		}
>  
>  	return NULL;
>  }
> @@ -1486,7 +1493,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
>  	struct socket *sock;
>  	int rc = 0;
>  
> -	if (value == NULL || size > SMK_LABELLEN)
> +	if (value == NULL || size > SMK_LABELLEN || size == 0)
>  		return -EACCES;
>  
>  	sp = smk_import(value, size);
> diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
> index 856c8a2..e03a7e1 100644
> --- a/security/smack/smackfs.c
> +++ b/security/smack/smackfs.c
> @@ -86,6 +86,9 @@ LIST_HEAD(smack_rule_list);
>  
>  static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
>  
> +const char *smack_cipso_option = SMACK_CIPSO_OPTION;
> +
> +
>  #define	SEQ_READ_FINISHED	1
>  
>  /*
> @@ -565,6 +568,11 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
>  		goto unlockedout;
>  	}
>  
> +	/* labels cannot begin with a '-' */
> +	if (data[0] == '-') {
> +		rc = -EINVAL;
> +		goto unlockedout;
> +	}
>  	data[count] = '\0';
>  	rule = data;
>  	/*
> @@ -808,9 +816,18 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
>  	if (m > BEBITS)
>  		return -EINVAL;
>  
> -	sp = smk_import(smack, 0);
> -	if (sp == NULL)
> -		return -EINVAL;
> +	/* if smack begins with '-', its an option, don't import it */
> +	if (smack[0] != '-') {
> +		sp = smk_import(smack, 0);
> +		if (sp == NULL)
> +			return -EINVAL;
> +	} else {
> +		/* check known options */
> +		if (strcmp(smack, smack_cipso_option) == 0)
> +			sp = (char *)smack_cipso_option;
> +		else
> +			return -EINVAL;
> +	}
>  
>  	for (temp_mask = 0; m > 0; m--) {
>  		temp_mask |= mask_bits;
> @@ -849,18 +866,23 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
>  			smk_netlbladdr_insert(skp);
>  		}
>  	} else {
> -		rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
> -			&skp->smk_host.sin_addr, &skp->smk_mask,
> -			PF_INET, &audit_info);
> +		/* we delete the unlabeled entry, only if the previous label
> +		 * wasnt the special CIPSO option */
> +		if (skp->smk_label != smack_cipso_option)
> +			rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
> +					&skp->smk_host.sin_addr, &skp->smk_mask,
> +					PF_INET, &audit_info);
> +		else
> +			rc = 0;
>  		skp->smk_label = sp;
>  	}
>  
>  	/*
>  	 * Now tell netlabel about the single label nature of
>  	 * this host so that incoming packets get labeled.
> +	 * but only if we didn't get the special CIPSO option
>  	 */
> -
> -	if (rc == 0)
> +	if (rc == 0 && sp != smack_cipso_option)
>  		rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
>  			&skp->smk_host.sin_addr, &skp->smk_mask, PF_INET,
>  			smack_to_secid(skp->smk_label), &audit_info);
>
>
>   


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] Labeled networking patches for 2.6.30
  2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
                   ` (6 preceding siblings ...)
  2009-03-27 21:58 ` [PATCH 0/6] Labeled networking patches for 2.6.30 David Miller
@ 2009-03-28  5:16 ` James Morris
  7 siblings, 0 replies; 15+ messages in thread
From: James Morris @ 2009-03-28  5:16 UTC (permalink / raw)
  To: Paul Moore; +Cc: linux-security-module, selinux, netdev, casey, etienne.basset

All applied and pushed to Linus.


-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] Labeled networking patches for 2.6.30
  2009-03-28  0:58   ` James Morris
  2009-03-28  1:08     ` David Miller
@ 2009-03-28 12:01     ` Paul Moore
  1 sibling, 0 replies; 15+ messages in thread
From: Paul Moore @ 2009-03-28 12:01 UTC (permalink / raw)
  To: James Morris
  Cc: David Miller, linux-security-module, selinux, netdev, casey,
	etienne.basset

On Friday 27 March 2009 08:58:52 pm James Morris wrote:
> On Fri, 27 Mar 2009, David Miller wrote:
> > From: Paul Moore <paul.moore@hp.com>
> > Date: Fri, 27 Mar 2009 17:10:20 -0400
> >
> > > This patchset wraps up all the new labeled networking bits for 2.6.30. 
> > > This is mostly a fixup/cleanup release with the main focus being to
> > > correct the TCP labeling of both SELinux and Smack; expect some of this
> > > to get backported to the -stable trees but there will need to be a bit
> > > of rework first so it may take a few weeks for that to happen.  Other
> > > than the TCP issue there is a new Smack feature to configure CIPSO
> > > aware hosts in "/smack/netlabel" which should make the host/network
> > > label configuration much more flexible.  The last change is to get rid
> > > of the security_socket_post_accept() hook which isn't currently being
> > > used by anything in-tree and seems to act as a magnet for bad ideas; if
> > > things change we can always add it back later.
> >
> > Is James Morris going to take this stuff?  Just curious...
>
> I will unless you specifically want it.

Since James had pulled the labeled networking patches the past few times I 
figured he would do the same this time around.  I was posting these to netdev 
more as an FYI since there were some core networking changes, although they 
were pretty minor and previously ACKd.

> Paul: it's probably a good idea to have this in my tree before the merge
> window opens.

Okay, I'll make sure you have the lblnet-2.6_next stuff before the merge 
window opens in the future.  Regardless, thanks for pulling in the patches.

-- 
paul moore
linux @ hp


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2009-03-28 12:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-27 21:10 [PATCH 0/6] Labeled networking patches for 2.6.30 Paul Moore
2009-03-27 21:10 ` [PATCH 1/6] lsm: Relocate the IPv4 security_inet_conn_request() hooks Paul Moore
2009-03-27 21:10 ` [PATCH 2/6] netlabel: Label incoming TCP connections correctly in SELinux Paul Moore
2009-03-28  3:03   ` Casey Schaufler
2009-03-27 21:10 ` [PATCH 3/6] selinux: Remove the "compat_net" compatibility code Paul Moore
2009-03-27 21:10 ` [PATCH 4/6] lsm: Remove the socket_post_accept() hook Paul Moore
2009-03-27 21:10 ` [PATCH 5/6] netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections Paul Moore
2009-03-28  3:04   ` Casey Schaufler
2009-03-27 21:11 ` [PATCH 6/6] smack: Add a new '-CIPSO' option to the network address label configuration Paul Moore
2009-03-28  3:05   ` Casey Schaufler
2009-03-27 21:58 ` [PATCH 0/6] Labeled networking patches for 2.6.30 David Miller
2009-03-28  0:58   ` James Morris
2009-03-28  1:08     ` David Miller
2009-03-28 12:01     ` Paul Moore
2009-03-28  5:16 ` James Morris

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).