Skip to contentSkip to conversation

Labeled networking patches for 2.6.28

RFC PATCH Superseded Paul Moore 1 participant 9 messages Aug 11, 2008

Subsystems (6)

v2 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Paul Moore

author
#0 lore raw

v2 cover Labeled networking patches for 2.6.28

An updated patchset that includes some RCU/locking fixes from Paul McKenney, a tweak to the SELinux socket security structure to cache the NetLabel security attribute structure (last patch, not present in previous version), as well as some small other fixes I found over the weekend. The patches are still pretty rough around the edges but they are getting there, once again, any comments or feedback you have are greatly appreciated.

I've updated the git tree, no changes have been made to the userspace tools since last posting.

* git://git.infradead.org/users/pcmoore/lblnet-2.6_testing
* http://netlabel.svn.sf.net/viewvc/netlabel/netlabel_tools/branches/addrsel

As promised, I'm also including some instructions on how to configure the new functionality as well. The first step is to download and build the "addrsel" branch of the netlabel_tools package, you can do that with the following commands:

 # svn co https://netlabel.svn.sourceforge.net/svnroot/netlabel netlabel
 # cd netlabel/netlabel_tools/branches/addrsel
 # make

Then you need to use the netlabelctl tool you just built to configure the NetLabel subsystem. The following commands create a CIPSO DOI and use it to label traffic sent to 127.0.0.1 by ping, aka the ping_t domain, all other ping traffic is unlabeled. Remember you _must_ have a catch-all address, i.e. 0.0.0.0/0, configured for each domain that you configure to use the new address selectors; failure to do so will cause unmatched traffic to be dropped, similar to what would happen if you didn't have a domain mapping configured under the original configuration scheme. In general, think of the catch-all addresses, 0.0.0.0/0 and ::/0, as the "DEFAULT" domain mapping.

[NOTE: in the process of writing the examples below I found a bug in the
'netlabelctl cipsov4 del ...' operation, I'm looking into it right now but in the meantime only add :) ]

 # ./netlabelctl cipsov4 add pass doi:1 tags:1,2,5
 # ./netlabelctl -p cipsov4 list doi:1
 Configured CIPSOv4 mapping (DOI = 1)
  tags (3):
    RESTRICTED BITMAP
    ENUMERATED
    RANGED
 # ./netlabelctl -p map list
 Configured NetLabel domain mappings (1)
  domain: DEFAULT
    protocol: UNLABELED
 # ./netlabelctl map add domain:ping_t protocol:unlbl address:0.0.0.0/0
 # ./netlabelctl map add domain:ping_t protocol:cipsov4,1 address:127.0.0.1
 # ./netlabelctl -p map list
 Configured NetLabel domain mappings (2)
  domain: "ping_t"
    address: 127.0.0.1/32
     protocol: CIPSOv4, DOI = 1
    address: 0.0.0.0/0
     protocol: UNLABELED
  domain: DEFAULT
    protocol: UNLABELED

We can test this by pinging the host's address where we don't see any additional IP options, in other words an unlabeled packet ...

 # ping -c 1 bob.lan
 PING bob.lan (192.168.0.169) 56(84) bytes of data.
 64 bytes from bob.lan (192.168.0.169): icmp_seq=1 ttl=64 time=0.061 ms

--- bob.lan ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.061/0.061/0.061/0.000 ms

... however, if we ping localhost we can see the telltale "unknown option 86" that tells us a CIPSO option is present on the packet.

 # ping -c 1 localhost
 PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.056 ms
 unknown option 86

--- localhost.localdomain ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.056/0.056/0.056/0.000 ms

Tada!

Signature · 2 lines
paul moore
linux @ hp
author
#1 lore raw

RFC PATCH v2 1/7 selinux: Fix a problem in security_netlbl_sid_to_secattr()

Currently when SELinux fails to allocate memory in security_netlbl_sid_to_secattr() the NetLabel LSM domain field is set to NULL which triggers the default NetLabel LSM domain mapping which may not always be the desired mapping. This patch fixes this by returning an error when the kernel is unable to allocate memory. This could result in more failures on a system with heavy memory pressure but it is the "correct" thing to do.

Signed-off-by XXX

---

 security/selinux/ss/services.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
security/selinux/ss/services.c +8 -2
index b52f923..5b7ecc1 100644
@@ -2788,7 +2788,7 @@ netlbl_secattr_to_sid_return_cleanup:
  */
 int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
 {
-	int rc = -ENOENT;
+	int rc;
 	struct context *ctx;
 
 	if (!ss_initialized)
@@ -2796,10 +2796,16 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
 
 	read_lock(&policy_rwlock);
 	ctx = sidtab_search(&sidtab, sid);
-	if (ctx == NULL)
+	if (ctx == NULL) {
+		rc = -ENOENT;
 		goto netlbl_sid_to_secattr_failure;
+	}
 	secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
 				  GFP_ATOMIC);
+	if (secattr->domain == NULL) {
+		rc = -ENOMEM;
+		goto netlbl_sid_to_secattr_failure;
+	}
 	secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY;
 	mls_export_netlbl_lvl(ctx, secattr);
 	rc = mls_export_netlbl_cat(ctx, secattr);
author
#2 lore raw

RFC PATCH v2 2/7 netlabel: Replace protocol/NetLabel linking with refrerence counts

In reply to Paul Moore

NetLabel has always had a list of backpointers in the CIPSO DOI definition structure which pointed to the NetLabel LSM domain mapping structures which referenced the CIPSO DOI struct. The rationale for this was that when an administrator removed a CIPSO DOI from the system all of the associated NetLabel LSM domain mappings should be removed as well; a list of backpointers made this a simple operation.

Unfortunately, while the backpointers did make the removal easier they were a bit of a mess from an implementation point of view which was making further development difficult. Since the removal of a CIPSO DOI is a realtively rare event it seems to make sense to remove this backpointer list as the optimization was hurting us more then it was helping. However, we still need to be able to track when a CIPSO DOI definition is being used so replace the backpointer list with a reference count. In order to preserve the current functionality of removing the associated LSM domain mappings when a CIPSO DOI is removed we walk the LSM domain mapping table, removing the relevant entries.

Signed-off-by XXX

---

 include/net/cipso_ipv4.h           |   21 ++-
 include/net/netlabel.h             |    2 
 net/ipv4/cipso_ipv4.c              |  235 +++++++++++++++---------------------
 net/netlabel/netlabel_cipso_v4.c   |   74 ++++++-----
 net/netlabel/netlabel_domainhash.c |   95 +++++++--------
 net/netlabel/netlabel_domainhash.h |    2 
 net/netlabel/netlabel_kapi.c       |   32 ++---
 net/netlabel/netlabel_mgmt.c       |   24 +---
 security/smack/smackfs.c           |   15 ++
 9 files changed, 232 insertions(+), 268 deletions(-)
include/net/cipso_ipv4.h +11 -10
index a6bb945..5fe6556 100644
@@ -40,6 +40,7 @@
 #include <linux/net.h>
 #include <linux/skbuff.h>
 #include <net/netlabel.h>
+#include <asm/atomic.h>
 
 /* known doi values */
 #define CIPSO_V4_DOI_UNKNOWN          0x00000000
@@ -79,10 +80,9 @@ struct cipso_v4_doi {
 	} map;
 	u8 tags[CIPSO_V4_TAG_MAXCNT];
 
-	u32 valid;
+	atomic_t refcount;
 	struct list_head list;
 	struct rcu_head rcu;
-	struct list_head dom_list;
 };
 
 /* Standard CIPSO mapping table */
@@ -128,25 +128,26 @@ extern int cipso_v4_rbm_strictvalid;
 
 #ifdef CONFIG_NETLABEL
 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
-int cipso_v4_doi_remove(u32 doi,
-			struct netlbl_audit *audit_info,
-			void (*callback) (struct rcu_head * head));
+void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
+int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
+void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def);
 int cipso_v4_doi_walk(u32 *skip_cnt,
 		     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
 	             void *cb_arg);
-int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);
-int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
-			       const char *domain);
 #else
 static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
 {
 	return -ENOSYS;
 }
 
+static inline void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
+{
+	return;
+}
+
 static inline int cipso_v4_doi_remove(u32 doi,
-				    struct netlbl_audit *audit_info,
-				    void (*callback) (struct rcu_head * head))
+				      struct netlbl_audit *audit_info)
 {
 	return 0;
 }
include/net/netlabel.h +1 -1
index e4d2d6b..6b93921 100644
@@ -354,7 +354,7 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
 			     struct netlbl_audit *audit_info);
 int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
 			   struct netlbl_audit *audit_info);
-int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
+int netlbl_cfg_cipsov4_add_map(u32 doi,
 			       const char *domain,
 			       struct netlbl_audit *audit_info);
 int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info);
net/ipv4/cipso_ipv4.c +98 -137

307 lines not on this page · raw message

net/netlabel/netlabel_cipso_v4.c +41 -33

122 lines not on this page · raw message

net/netlabel/netlabel_domainhash.c +47 -48

136 lines not on this page · raw message

net/netlabel/netlabel_domainhash.h +2 -0
index 8220990..afcc41a 100644
@@ -61,6 +61,8 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
 		      struct netlbl_audit *audit_info);
 int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
 			      struct netlbl_audit *audit_info);
+int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
+			       struct netlbl_audit *audit_info);
 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
net/netlabel/netlabel_kapi.c +13 -19
index 39793a1..ccf3d4c 100644
@@ -147,7 +147,7 @@ int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
 }
 
 /**
- * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping
+ * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI mapping
  * @doi_def: the DOI definition
  * @domain: the domain mapping to add
  * @audit_info: NetLabel audit information
@@ -159,7 +159,7 @@ int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
  * failure.
  *
  */
-int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
+int netlbl_cfg_cipsov4_add_map(u32 doi,
 			       const char *domain,
 			       struct netlbl_audit *audit_info)
 {
@@ -175,30 +175,24 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
 			goto cfg_cipsov4_add_map_failure;
 	}
 	entry->type = NETLBL_NLTYPE_CIPSOV4;
-	entry->type_def.cipsov4 = doi_def;
-
-	/* Grab a RCU read lock here so nothing happens to the doi_def variable
-	 * between adding it to the CIPSOv4 protocol engine and adding a
-	 * domain mapping for it. */
+	entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi);
+	if (entry->type_def.cipsov4 == NULL) {
+		ret_val = -ENOENT;
+		goto cfg_cipsov4_add_map_failure;
+	}
 
-	rcu_read_lock();
-	ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info);
-	if (ret_val != 0)
-		goto cfg_cipsov4_add_map_failure_unlock;
 	ret_val = netlbl_domhsh_add(entry, audit_info);
 	if (ret_val != 0)
-		goto cfg_cipsov4_add_map_failure_remove_doi;
-	rcu_read_unlock();
+		goto cfg_cipsov4_add_map_failure;
 
 	return 0;
 
-cfg_cipsov4_add_map_failure_remove_doi:
-	cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free);
-cfg_cipsov4_add_map_failure_unlock:
-	rcu_read_unlock();
 cfg_cipsov4_add_map_failure:
-	if (entry != NULL)
+	if (entry != NULL) {
+		if (entry->type_def.cipsov4 != NULL)
+			cipso_v4_doi_putdef(entry->type_def.cipsov4);
 		kfree(entry->domain);
+	}
 	kfree(entry);
 	return ret_val;
 }
@@ -215,7 +209,7 @@ cfg_cipsov4_add_map_failure:
  */
 int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
 {
-	return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free);
+	return cipso_v4_doi_remove(doi, audit_info);
 }
 
 /*
net/netlabel/netlabel_mgmt.c +6 -18
index 44be5d5..c4e18c7 100644
@@ -122,18 +122,12 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
 			goto add_failure;
 
 		tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
-		/* We should be holding a rcu_read_lock() here while we hold
-		 * the result but since the entry will always be deleted when
-		 * the CIPSO DOI is deleted we aren't going to keep the
-		 * lock. */
-		rcu_read_lock();
 		entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
-		if (entry->type_def.cipsov4 == NULL) {
-			rcu_read_unlock();
+		if (entry->type_def.cipsov4 == NULL)
 			goto add_failure;
-		}
 		ret_val = netlbl_domhsh_add(entry, &audit_info);
-		rcu_read_unlock();
+		if (ret_val != 0)
+			cipso_v4_doi_putdef(entry->type_def.cipsov4);
 		break;
 	default:
 		goto add_failure;
@@ -294,18 +288,12 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
 			goto adddef_failure;
 
 		tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
-		/* We should be holding a rcu_read_lock() here while we hold
-		 * the result but since the entry will always be deleted when
-		 * the CIPSO DOI is deleted we aren't going to keep the
-		 * lock. */
-		rcu_read_lock();
 		entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
-		if (entry->type_def.cipsov4 == NULL) {
-			rcu_read_unlock();
+		if (entry->type_def.cipsov4 == NULL)
 			goto adddef_failure;
-		}
 		ret_val = netlbl_domhsh_add_default(entry, &audit_info);
-		rcu_read_unlock();
+		if (ret_val != 0)
+			cipso_v4_doi_putdef(entry->type_def.cipsov4);
 		break;
 	default:
 		goto adddef_failure;
security/smack/smackfs.c +13 -2
index 271a835..8d031ca 100644
@@ -342,10 +342,21 @@ static void smk_cipso_doi(void)
 	for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
 		doip->tags[rc] = CIPSO_V4_TAG_INVALID;
 
-	rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info);
-	if (rc != 0)
+	rc = netlbl_cfg_cipsov4_add(doip, &audit_info);
+	if (rc != 0) {
 		printk(KERN_WARNING "%s:%d add rc = %d\n",
+		       __func__, __LINE__, rc);	
+		goto err;
+	}
+	rc = netlbl_cfg_cipsov4_add_map(doip->doi, NULL, &audit_info);
+	if (rc != 0) {
+		printk(KERN_WARNING "%s:%d add_map rc = %d\n",
 		       __func__, __LINE__, rc);
+		goto err;
+	}
+
+err:
+	kfree(doip);
 }
 
 /**
author
#3 lore raw

RFC PATCH v2 3/7 netlabel: Add a generic way to create ordered linked lists of network addrs

In reply to Paul Moore

Create an ordered IP address linked list mechanism similar to the core kernel's linked list construct. The idea behind this list functionality is to create an extensibile linked list ordered by IP address mask to ease the matching of network addresses. The linked list is ordered with larger address masks at the front of the list and shorter address masks at the end to facilitate overriding network entries with individual host or subnet entries.

Signed-off-by XXX

---

 net/netlabel/Makefile             |    3 
 net/netlabel/netlabel_addrlist.c  |  258 +++++++++++++++++++++++++++++
 net/netlabel/netlabel_addrlist.h  |  162 ++++++++++++++++++
 net/netlabel/netlabel_unlabeled.c |  329 +++++++++++++------------------------
 4 files changed, 538 insertions(+), 214 deletions(-)
net/netlabel/Makefile +2 -1
index 8af18c0..ea750e9 100644
@@ -5,7 +5,8 @@
 #
 
 # base objects
-obj-y	:= netlabel_user.o netlabel_kapi.o netlabel_domainhash.o
+obj-y	:= netlabel_user.o netlabel_kapi.o
+obj-y	+= netlabel_domainhash.o netlabel_addrlist.o
 
 # management objects
 obj-y	+= netlabel_mgmt.o
net/netlabel/netlabel_addrlist.c new file +258 -0

258 lines not on this page · raw message

net/netlabel/netlabel_addrlist.h new file +162 -0

162 lines not on this page · raw message

net/netlabel/netlabel_unlabeled.c +116 -213

529 lines not on this page · raw message

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

author
#4 lore raw

RFC PATCH v2 4/7 netlabel: Add network address selectors to the NetLabel/LSM domain mapping

In reply to Paul Moore

This patch extends the NetLabel traffic labeling capabilities to individual packets based not only on the LSM domain but the by the destination address as well. The changes here only affect the core NetLabel infrastructre, changes to the NetLabel KAPI and individial protocol engines are also required but are split out into a different patch to ease review.

Signed-off-by XXX

---

 include/net/netlabel.h             |    5 
 net/netlabel/netlabel_addrlist.c   |  130 ++++++++++++
 net/netlabel/netlabel_addrlist.h   |   15 +
 net/netlabel/netlabel_domainhash.c |  286 +++++++++++++++++++++++----
 net/netlabel/netlabel_domainhash.h |   38 +++-
 net/netlabel/netlabel_kapi.c       |    7 +
 net/netlabel/netlabel_mgmt.c       |  385 +++++++++++++++++++++++++++---------
 net/netlabel/netlabel_mgmt.h       |   59 +++++-
 net/netlabel/netlabel_unlabeled.c  |   96 +--------
 9 files changed, 799 insertions(+), 222 deletions(-)
include/net/netlabel.h +4 -1
index 6b93921..2ca4f48 100644
@@ -72,8 +72,9 @@ struct cipso_v4_doi;
 /* NetLabel NETLINK protocol version
  *  1: initial version
  *  2: added static labels for unlabeled connections
+ *  3: network selectors added to the NetLabel/LSM domain mapping
  */
-#define NETLBL_PROTO_VERSION            2
+#define NETLBL_PROTO_VERSION            3
 
 /* NetLabel NETLINK types/families */
 #define NETLBL_NLTYPE_NONE              0
@@ -87,6 +88,8 @@ struct cipso_v4_doi;
 #define NETLBL_NLTYPE_CIPSOV6_NAME      "NLBL_CIPSOv6"
 #define NETLBL_NLTYPE_UNLABELED         5
 #define NETLBL_NLTYPE_UNLABELED_NAME    "NLBL_UNLBL"
+#define NETLBL_NLTYPE_ADDRSELECT        6
+#define NETLBL_NLTYPE_ADDRSELECT_NAME   "NLBL_ADRSEL"
 
 /*
  * NetLabel - Kernel API for accessing the network packet label mappings.
net/netlabel/netlabel_addrlist.c +130 -0

151 lines not on this page · raw message

net/netlabel/netlabel_addrlist.h +15 -0
index d521762..7840f95 100644
@@ -36,6 +36,7 @@
 #include <linux/rcupdate.h>
 #include <linux/list.h>
 #include <linux/in6.h>
+#include <linux/audit.h>
 
 /* XXX - needs documentation */
 struct netlbl_af4list {
@@ -104,6 +105,12 @@ struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
 void netlbl_af4list_remove_entry(struct netlbl_af4list *entry);
 struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
 					     struct list_head *head);
+struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
+						   __be32 mask,
+						   struct list_head *head);
+void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
+			       int src, const char *dev,
+			       __be32 addr, __be32 mask);
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 
@@ -157,6 +164,14 @@ struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
 void netlbl_af6list_remove_entry(struct netlbl_af6list *entry);
 struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
 					     struct list_head *head);
+struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
+						   const struct in6_addr *mask,
+						   struct list_head *head);
+void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
+			       int src,
+			       const char *dev,
+			       const struct in6_addr *addr,
+			       const struct in6_addr *mask);
 #endif /* IPV6 */
 
 #endif
net/netlabel/netlabel_domainhash.c +249 -37

339 lines not on this page · raw message

net/netlabel/netlabel_domainhash.h +36 -2
index afcc41a..bfcb676 100644
@@ -11,7 +11,7 @@
  */
 
 /*
- * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
  *
  * This program is free software;  you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,16 +36,43 @@
 #include <linux/rcupdate.h>
 #include <linux/list.h>
 
+#include "netlabel_addrlist.h"
+
 /* Domain hash table size */
 /* XXX - currently this number is an uneducated guess */
 #define NETLBL_DOMHSH_BITSIZE       7
 
-/* Domain mapping definition struct */
+/* Domain mapping definition structures */
+#define netlbl_domhsh_addr4_entry(iter) \
+	container_of(iter, struct netlbl_domaddr4_map, list)
+struct netlbl_domaddr4_map {
+	u32 type;
+	union {
+		struct cipso_v4_doi *cipsov4;
+	} type_def;
+
+	struct netlbl_af4list list;
+};
+#define netlbl_domhsh_addr6_entry(iter) \
+	container_of(iter, struct netlbl_domaddr6_map, list)
+struct netlbl_domaddr6_map {
+	u32 type;
+
+	/* NOTE: no 'type_def' union needed at present since we don't currently
+	 *       support any IPv6 labeling protocols */
+
+	struct netlbl_af6list list;
+};
+struct netlbl_domaddr_map {
+	struct list_head list4;
+	struct list_head list6;
+};
 struct netlbl_dom_map {
 	char *domain;
 	u32 type;
 	union {
 		struct cipso_v4_doi *cipsov4;
+		struct netlbl_domaddr_map *addrsel;
 	} type_def;
 
 	u32 valid;
@@ -66,9 +93,16 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
+struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
+						       __be32 addr);
 int netlbl_domhsh_walk(u32 *skip_bkt,
 		     u32 *skip_chain,
 		     int (*callback) (struct netlbl_dom_map *entry, void *arg),
 		     void *cb_arg);
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
+						  const struct in6_addr *addr);
+#endif /* IPv6 */
+
 #endif
net/netlabel/netlabel_kapi.c +6 -1
index ccf3d4c..c421f1a 100644
@@ -446,7 +446,9 @@ int netlbl_enabled(void)
  * Attach the correct label to the given socket using the security attributes
  * specified in @secattr.  This function requires exclusive access to @sk,
  * which means it either needs to be in the process of being created or locked.
- * Returns zero on success, negative values on failure.
+ * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
+ * network address selectors (can't blindly label the socket), and negative
+ * values on all other failures.
  *
  */
 int netlbl_sock_setattr(struct sock *sk,
@@ -460,6 +462,9 @@ int netlbl_sock_setattr(struct sock *sk,
 	if (dom_entry == NULL)
 		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,
net/netlabel/netlabel_mgmt.c +292 -93

473 lines not on this page · raw message

net/netlabel/netlabel_mgmt.h +54 -5

94 lines not on this page · raw message

net/netlabel/netlabel_unlabeled.c +13 -83

126 lines not on this page · raw message

author
#5 lore raw

RFC PATCH v2 5/7 netlabel: Add functionality to set the security attributes of a packet

In reply to Paul Moore

This patch builds upon the new NetLabel address selector functionality by providing the NetLabel KAPI and CIPSO engine support needed to enable the new packet-based labeling. The only new addition to the NetLabel KAPI at this point is shown below:

* int netlbl_skbuff_setattr(skb, family, secattr)

... and is designed to be called from a Netfilter hook after the packet's IP header has been populated such as in the FORWARD or LOCAL_OUT hooks.

This patch also provides the necessary SELinux hooks to support this new functionality. Smack support is not currently included due to uncertainty regarding the permissions needed to expand the Smack network access controls.

Signed-off-by XXX

---

 include/net/cipso_ipv4.h            |   16 +++
 include/net/netlabel.h              |    9 +
 net/ipv4/cipso_ipv4.c               |  220 +++++++++++++++++++++++++++++------
 net/netlabel/netlabel_kapi.c        |   57 +++++++++
 security/selinux/hooks.c            |   46 +++++++
 security/selinux/include/netlabel.h |   10 ++
 security/selinux/include/objsec.h   |    1 
 security/selinux/netlabel.c         |   48 +++++++-
 8 files changed, 367 insertions(+), 40 deletions(-)
include/net/cipso_ipv4.h +16 -0
index 5fe6556..2ce093b 100644
@@ -208,6 +208,10 @@ int cipso_v4_sock_setattr(struct sock *sk,
 			  const struct cipso_v4_doi *doi_def,
 			  const struct netlbl_lsm_secattr *secattr);
 int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
+int cipso_v4_skbuff_setattr(struct sk_buff *skb,
+			    const struct cipso_v4_doi *doi_def,
+			    const struct netlbl_lsm_secattr *secattr);
+int cipso_v4_skbuff_delattr(struct sk_buff *skb);
 int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
 			    struct netlbl_lsm_secattr *secattr);
 int cipso_v4_validate(unsigned char **option);
@@ -232,6 +236,18 @@ static inline int cipso_v4_sock_getattr(struct sock *sk,
 	return -ENOSYS;
 }
 
+static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
+				      const struct cipso_v4_doi *doi_def,
+				      const struct netlbl_lsm_secattr *secattr)
+{
+	return -ENOSYS;
+}
+
+static inline int cipso_v4_skbuff_delattr(struct sk_buff *skb)
+{
+	return -ENOSYS;
+}
+
 static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
 					  struct netlbl_lsm_secattr *secattr)
 {
include/net/netlabel.h +9 -0
index 2ca4f48..1d777f7 100644
@@ -385,6 +385,9 @@ int netlbl_sock_setattr(struct sock *sk,
 			const struct netlbl_lsm_secattr *secattr);
 int netlbl_sock_getattr(struct sock *sk,
 			struct netlbl_lsm_secattr *secattr);
+int netlbl_skbuff_setattr(struct sk_buff *skb,
+			  u16 family,
+			  const struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
 			  u16 family,
 			  struct netlbl_lsm_secattr *secattr);
@@ -464,6 +467,12 @@ static inline int netlbl_sock_getattr(struct sock *sk,
 {
 	return -ENOSYS;
 }
+static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
+				      u16 family,
+				      const struct netlbl_lsm_secattr *secattr)
+{
+	return -ENOSYS;
+}
 static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
 					u16 family,
 					struct netlbl_lsm_secattr *secattr)
net/ipv4/cipso_ipv4.c +182 -38

253 lines not on this page · raw message

net/netlabel/netlabel_kapi.c +57 -0

63 lines not on this page · raw message

security/selinux/hooks.c +45 -1

76 lines not on this page · raw message

security/selinux/include/netlabel.h +10 -0
index 487a7d8..7711885 100644
@@ -46,6 +46,9 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 				 u16 family,
 				 u32 *type,
 				 u32 *sid);
+int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
+				 u16 family,
+				 u32 sid);
 
 void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
 int selinux_netlbl_socket_post_create(struct socket *sock);
@@ -80,6 +83,13 @@ static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 	return 0;
 }
 
+static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
+					       u16 family
+					       u32 sid)
+{
+	return 0;
+}
+
 static inline void selinux_netlbl_sock_graft(struct sock *sk,
 					     struct socket *sock)
 {
security/selinux/include/objsec.h +1 -0
index 91070ab..b8e51de 100644
@@ -117,6 +117,7 @@ struct sk_security_struct {
 		NLBL_UNSET = 0,
 		NLBL_REQUIRE,
 		NLBL_LABELED,
+		NLBL_REQSKB
 	} nlbl_state;
 #endif
 };
security/selinux/netlabel.c +47 -1

61 lines not on this page · raw message

author
#6 lore raw

RFC PATCH v2 6/7 selinux: Set socket NetLabel based on connection endpoint

In reply to Paul Moore

Previous work enabled the use of address based NetLabel selectors, which while highly useful, brought the potential for additional per-packet overhead when used. This patch attempts to solve that by applying NetLabel socket labels when sockets are connect()'d. This should alleviate the per-packet NetLabel labeling for all connected sockets (yes, it even works for connected DGRAM sockets).

Signed-off-by XXX

---

 include/net/cipso_ipv4.h            |    5 ++
 include/net/netlabel.h              |   13 ++++++
 net/ipv4/cipso_ipv4.c               |   47 +++++++++++++++++++++++
 net/netlabel/netlabel_kapi.c        |   72 +++++++++++++++++++++++++++++++++++
 security/selinux/hooks.c            |    4 +-
 security/selinux/include/netlabel.h |    8 ++++
 security/selinux/include/objsec.h   |    3 +
 security/selinux/netlabel.c         |   48 +++++++++++++++++++++++
 8 files changed, 197 insertions(+), 3 deletions(-)
include/net/cipso_ipv4.h +5 -0
index 2ce093b..811febf 100644
@@ -207,6 +207,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
 int cipso_v4_sock_setattr(struct sock *sk,
 			  const struct cipso_v4_doi *doi_def,
 			  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_skbuff_setattr(struct sk_buff *skb,
 			    const struct cipso_v4_doi *doi_def,
@@ -230,6 +231,10 @@ static inline int cipso_v4_sock_setattr(struct sock *sk,
 	return -ENOSYS;
 }
 
+static inline void cipso_v4_sock_delattr(struct sock *sk)
+{
+}
+
 static inline int cipso_v4_sock_getattr(struct sock *sk,
 					struct netlbl_lsm_secattr *secattr)
 {
include/net/netlabel.h +13 -0
index 1d777f7..d4d3146 100644
@@ -383,8 +383,12 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
 int netlbl_enabled(void);
 int netlbl_sock_setattr(struct sock *sk,
 			const struct netlbl_lsm_secattr *secattr);
+void netlbl_sock_delattr(struct sock *sk);
 int netlbl_sock_getattr(struct sock *sk,
 			struct netlbl_lsm_secattr *secattr);
+int netlbl_conn_setattr(struct sock *sk,
+			struct sockaddr *addr,
+			const struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_setattr(struct sk_buff *skb,
 			  u16 family,
 			  const struct netlbl_lsm_secattr *secattr);
@@ -462,11 +466,20 @@ static inline int netlbl_sock_setattr(struct sock *sk,
 {
 	return -ENOSYS;
 }
+static inline void netlbl_sock_delattr(struct sock *sk)
+{
+}
 static inline int netlbl_sock_getattr(struct sock *sk,
 				      struct netlbl_lsm_secattr *secattr)
 {
 	return -ENOSYS;
 }
+static inline int netlbl_conn_setattr(struct sock *sk,
+				      struct sockaddr *addr,
+				      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)
net/ipv4/cipso_ipv4.c +47 -0

53 lines not on this page · raw message

net/netlabel/netlabel_kapi.c +72 -0

84 lines not on this page · raw message

security/selinux/hooks.c +3 -1
index bbd68bd..a6fd2e6 100644
@@ -3784,6 +3784,7 @@ out:
 
 static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
 {
+	struct sock *sk = sock->sk;
 	struct inode_security_struct *isec;
 	int err;
 
@@ -3797,7 +3798,6 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 	isec = SOCK_INODE(sock)->i_security;
 	if (isec->sclass == SECCLASS_TCP_SOCKET ||
 	    isec->sclass == SECCLASS_DCCP_SOCKET) {
-		struct sock *sk = sock->sk;
 		struct avc_audit_data ad;
 		struct sockaddr_in *addr4 = NULL;
 		struct sockaddr_in6 *addr6 = NULL;
@@ -3831,6 +3831,8 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 			goto out;
 	}
 
+	err = selinux_netlbl_conn_setsid(sk, address);
+
 out:
 	return err;
 }
security/selinux/include/netlabel.h +8 -0
index 7711885..f6ef540 100644
@@ -49,6 +49,8 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 				 u16 family,
 				 u32 sid);
+int selinux_netlbl_conn_setsid(struct sock *sk,
+			       struct sockaddr *addr);
 
 void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
 int selinux_netlbl_socket_post_create(struct socket *sock);
@@ -90,6 +92,12 @@ static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 	return 0;
 }
 
+static inline int selinux_netlbl_conn_setsid(struct sock *sk,
+					     struct sockaddr *addr)
+{
+	return 0;
+}
+
 static inline void selinux_netlbl_sock_graft(struct sock *sk,
 					     struct socket *sock)
 {
security/selinux/include/objsec.h +2 -1
index b8e51de..46fd1a4 100644
@@ -117,7 +117,8 @@ struct sk_security_struct {
 		NLBL_UNSET = 0,
 		NLBL_REQUIRE,
 		NLBL_LABELED,
-		NLBL_REQSKB
+		NLBL_REQSKB,
+		NLBL_CONNLABELED
 	} nlbl_state;
 #endif
 };
security/selinux/netlabel.c +47 -1

60 lines not on this page · raw message

author
#7 lore raw

RFC PATCH v2 7/7 selinux: Cache NetLabel secattrs in the socket's security struct

In reply to Paul Moore

Previous work enabled the use of address based NetLabel selectors, which while highly useful, brought the potential for additional per-packet overhead when used. This patch attempts to mitigate some of that overhead by caching the NetLabel security attribute struct within the SELinux socket security structure. This should help eliminate the need to recreate the NetLabel secattr structure for each packet resulting in less overhead.

Signed-off-by XXX

---

 security/selinux/hooks.c            |    1 
 security/selinux/include/netlabel.h |    7 ++
 security/selinux/include/objsec.h   |    7 +-
 security/selinux/netlabel.c         |  101 ++++++++++++++++++++++++++---------
 4 files changed, 86 insertions(+), 30 deletions(-)
security/selinux/hooks.c +1 -0
index a6fd2e6..a8b49d4 100644
@@ -291,6 +291,7 @@ static void sk_free_security(struct sock *sk)
 	struct sk_security_struct *ssec = sk->sk_security;
 
 	sk->sk_security = NULL;
+	selinux_netlbl_sk_security_free(ssec);
 	kfree(ssec);
 }
 
security/selinux/include/netlabel.h +7 -0
index f6ef540..1034350 100644
@@ -39,6 +39,7 @@
 #ifdef CONFIG_NETLABEL
 void selinux_netlbl_cache_invalidate(void);
 
+void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
 void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
 				      int family);
 
@@ -68,6 +69,12 @@ static inline void selinux_netlbl_cache_invalidate(void)
 	return;
 }
 
+static inline void selinux_netlbl_sk_security_free(
+					       struct sk_security_struct *ssec)
+{
+	return;
+}
+
 static inline void selinux_netlbl_sk_security_reset(
 					       struct sk_security_struct *ssec,
 					       int family)
security/selinux/include/objsec.h +4 -3
index 46fd1a4..5c9271a 100644
@@ -109,9 +109,6 @@ struct netport_security_struct {
 };
 
 struct sk_security_struct {
-	u32 sid;			/* SID of this object */
-	u32 peer_sid;			/* SID of peer */
-	u16 sclass;			/* sock security class */
 #ifdef CONFIG_NETLABEL
 	enum {				/* NetLabel state */
 		NLBL_UNSET = 0,
@@ -120,7 +117,11 @@ struct sk_security_struct {
 		NLBL_REQSKB,
 		NLBL_CONNLABELED
 	} nlbl_state;
+	struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */
 #endif
+	u32 sid;			/* SID of this object */
+	u32 peer_sid;			/* SID of peer */
+	u16 sclass;			/* sock security class */
 };
 
 struct key_security_struct {
security/selinux/netlabel.c +74 -27

156 lines not on this page · raw message

author
#8 lore raw
In reply to Paul Moore
Quoted 3 lines · Paul Moore

[NOTE: in the process of writing the examples below I found a bug in the 'netlabelctl cipsov4 del ...' operation, I'm looking into it right now but in the meantime only add :) ]

I made some stupid mistakes in netlbl_cipsov4_remove() which should now be fixed in the git tree.

Signature · 2 lines
paul moore
linux @ hp