Skip to contentSkip to conversation

Fix for the unlabeled NetLabel access check patch

PATCH In review Paul Moore 2 participants 8 messages Jul 14, 2007

Subsystems (3)
lore
Share & tools
lore

Paul Moore

author
#0 lore raw

cover Fix for the unlabeled NetLabel access check patch

This patchset consists of two patches, both based against Linus' tree of about an hour ago. the first is largely a resend of a previous patch which was accepted into 2.6.23, the second is a fix for the first patch because it broke
stuff :/ More information about the breakage can be found in the link in the
patch description.

The first patch is the patch which converted NetLabel to make use of the netmsg initial SID for MLS labeled packets so that the unlabeled initial SID could be used for truly unlabeled packets. Unfortunately, this turned out to cause problems on systems with older policy. The second patch in this series addresses this problem by providing a runtime enable/disable status flag for NetLabel which SELinux (and other LSMs for that matter) can use to decide if they should perform NetLabel label enforcement.

I've given this patchset a quick test and everything behaves as I would expect, that is to say the following happens:

1. When the system is booted NetLabel is disabled (no NetLabel config present)
- no NetLabel access checks for labeled or unlabeled packets
2. Once NetLabel is configured (netlabelctl cipsov4 add ...) NetLabel is enabled
- NetLabel access checks are performed for both labeled and unlabeled packets
3. If all of the NetLabel labeled protocol configurations are removed (netlabelctl cipsov4 del ...) then NetLabel is disabled again
- no NetLabel access checks for labeled or unlabeled packets

This should solve the problems seen in the early 2.6.23 git kernels.

Michal, if you're not sick of verifying things yet - could you test this patchset on your configuration and verify that you do not see any regressions?

Thank you all for your patience, and sorry for all the confusion.

Signature · 7 lines
paul moore
linux security @ hp

--
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
#1 lore raw

PATCH 1/2 SELinux: use SECINITSID_NETMSG instead of SECINITSID_UNLABELED for NetLabel

These changes will make NetLabel behave like labeled IPsec where there is an access check for both labeled and unlabeled packets as well as providing the ability to restrict domains to receiving only labeled packets when NetLabel is in use. The changes to the policy are straight forward with the following necessary to receive labeled traffic (with SECINITSID_NETMSG defined as "netlabel_peer_t"):

allow mydom_t netlabel_peer_t:{ tcp_socket udp_socket rawip_socket } recvfrom;

The policy for unlabeled traffic would be:

allow mydom_t unlabeled_t:{ tcp_socket udp_socket rawip_socket } recvfrom;

These policy changes, as well as more general NetLabel support, are included in the latest SELinux Reference Policy release 20070629 or later. Users who make use of NetLabel are strongly encouraged to upgrade their policy to avoid network problems.

---
 security/selinux/hooks.c    |   21 +++++++++++----------
 security/selinux/netlabel.c |   34 +++++++++++++---------------------
 2 files changed, 24 insertions(+), 31 deletions(-)
security/selinux/hooks.c +11 -10
Index: linux-2.6_netmsg_part_deux/security/selinux/hooks.c
===================================================================
@@ -3129,17 +3129,19 @@ static int selinux_parse_skb(struct sk_b
 /**
  * selinux_skb_extlbl_sid - Determine the external label of a packet
  * @skb: the packet
- * @base_sid: the SELinux SID to use as a context for MLS only external labels
  * @sid: the packet's SID
  *
  * Description:
  * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.
+ * the external SID for the packet.  If only one form of external labeling is
+ * present then it is used, if both labeled IPsec and NetLabel labels are
+ * present then the SELinux type information is taken from the labeled IPsec
+ * SA and the MLS sensitivity label information is taken from the NetLabel
+ * security attributes.  This bit of "magic" is done in the call to
+ * selinux_netlbl_skbuff_getsid().
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb,
-				   u32 base_sid,
-				   u32 *sid)
+static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
 {
 	u32 xfrm_sid;
 	u32 nlbl_sid;
@@ -3147,10 +3149,9 @@ static void selinux_skb_extlbl_sid(struc
 	selinux_skb_xfrm_sid(skb, &xfrm_sid);
 	if (selinux_netlbl_skbuff_getsid(skb,
 					 (xfrm_sid == SECSID_NULL ?
-					  base_sid : xfrm_sid),
+					  SECINITSID_NETMSG : xfrm_sid),
 					 &nlbl_sid) != 0)
 		nlbl_sid = SECSID_NULL;
-
 	*sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
 }
 
@@ -3695,7 +3696,7 @@ static int selinux_socket_getpeersec_dgr
 	if (sock && sock->sk->sk_family == PF_UNIX)
 		selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
 	else if (skb)
-		selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peer_secid);
+		selinux_skb_extlbl_sid(skb, &peer_secid);
 
 	if (peer_secid == SECSID_NULL)
 		err = -EINVAL;
@@ -3756,7 +3757,7 @@ static int selinux_inet_conn_request(str
 	u32 newsid;
 	u32 peersid;
 
-	selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid);
+	selinux_skb_extlbl_sid(skb, &peersid);
 	if (peersid == SECSID_NULL) {
 		req->secid = sksec->sid;
 		req->peer_secid = SECSID_NULL;
@@ -3794,7 +3795,7 @@ static void selinux_inet_conn_establishe
 {
 	struct sk_security_struct *sksec = sk->sk_security;
 
-	selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid);
+	selinux_skb_extlbl_sid(skb, &sksec->peer_sid);
 }
 
 static void selinux_req_classify_flow(const struct request_sock *req,
security/selinux/netlabel.c +13 -21
Index: linux-2.6_netmsg_part_deux/security/selinux/netlabel.c
===================================================================
@@ -158,9 +158,7 @@ int selinux_netlbl_skbuff_getsid(struct 
 	netlbl_secattr_init(&secattr);
 	rc = netlbl_skbuff_getattr(skb, &secattr);
 	if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
-		rc = security_netlbl_secattr_to_sid(&secattr,
-						    base_sid,
-						    sid);
+		rc = security_netlbl_secattr_to_sid(&secattr, base_sid, sid);
 	else
 		*sid = SECSID_NULL;
 	netlbl_secattr_destroy(&secattr);
@@ -198,7 +196,7 @@ void selinux_netlbl_sock_graft(struct so
 	if (netlbl_sock_getattr(sk, &secattr) == 0 &&
 	    secattr.flags != NETLBL_SECATTR_NONE &&
 	    security_netlbl_secattr_to_sid(&secattr,
-					   SECINITSID_UNLABELED,
+					   SECINITSID_NETMSG,
 					   &nlbl_peer_sid) == 0)
 		sksec->peer_sid = nlbl_peer_sid;
 	netlbl_secattr_destroy(&secattr);
@@ -295,38 +293,32 @@ int selinux_netlbl_sock_rcv_skb(struct s
 				struct avc_audit_data *ad)
 {
 	int rc;
-	u32 netlbl_sid;
-	u32 recv_perm;
+	u32 nlbl_sid;
+	u32 perm;
 
-	rc = selinux_netlbl_skbuff_getsid(skb,
-					  SECINITSID_UNLABELED,
-					  &netlbl_sid);
+	rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &nlbl_sid);
 	if (rc != 0)
 		return rc;
-
-	if (netlbl_sid == SECSID_NULL)
-		return 0;
+	if (nlbl_sid == SECSID_NULL)
+		nlbl_sid = SECINITSID_UNLABELED;
 
 	switch (sksec->sclass) {
 	case SECCLASS_UDP_SOCKET:
-		recv_perm = UDP_SOCKET__RECVFROM;
+		perm = UDP_SOCKET__RECVFROM;
 		break;
 	case SECCLASS_TCP_SOCKET:
-		recv_perm = TCP_SOCKET__RECVFROM;
+		perm = TCP_SOCKET__RECVFROM;
 		break;
 	default:
-		recv_perm = RAWIP_SOCKET__RECVFROM;
+		perm = RAWIP_SOCKET__RECVFROM;
 	}
 
-	rc = avc_has_perm(sksec->sid,
-			  netlbl_sid,
-			  sksec->sclass,
-			  recv_perm,
-			  ad);
+	rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
 	if (rc == 0)
 		return 0;
 
-	netlbl_skbuff_err(skb, rc);
+	if (nlbl_sid != SECINITSID_UNLABELED)
+		netlbl_skbuff_err(skb, rc);
 	return rc;
 }
 
Signature · 7 lines
paul moore
linux security @ hp

--
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
#2 lore raw

PATCH 2/2 NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement

In reply to Paul Moore

Create a new NetLabel KAPI interface, netlbl_enabled(), which reports on the current runtime status of NetLabel based on the existing configuration. LSMs that make use of NetLabel, i.e. SELinux, can use this new function to determine if they should perform NetLabel access checks. This patch changes the NetLabel/SELinux glue code such that SELinux only enforces NetLabel related access checks when netlbl_enabled() returns true.

At present NetLabel is considered to be enabled when there is at least one labeled protocol configuration present. The result is that by default NetLabel is considered to be disabled, however, as soon as an administrator configured a CIPSO DOI definition NetLabel is enabled and SELinux starts enforcing NetLabel related access controls - including unlabeled packet controls.

This patch should resolve the issue reported by Michal Piotrowski here:

* http://lkml.org/lkml/2007/7/12/362

---
 include/net/netlabel.h           |    6 +++
 net/netlabel/netlabel_cipso_v4.c |    5 +++
 net/netlabel/netlabel_kapi.c     |   21 ++++++++++++
 net/netlabel/netlabel_mgmt.c     |   65 +++++++++++++++++++++++++++++++++++++++
 net/netlabel/netlabel_mgmt.h     |    5 +++
 security/selinux/netlabel.c      |   21 ++++++++++--
 6 files changed, 120 insertions(+), 3 deletions(-)
include/net/netlabel.h +6 -0
Index: linux-2.6_netmsg_part_deux/include/net/netlabel.h
===================================================================
@@ -332,6 +332,7 @@ static inline int netlbl_secattr_catmap_
  */
 
 #ifdef CONFIG_NETLABEL
+int netlbl_enabled(void);
 int netlbl_sock_setattr(struct sock *sk,
 			const struct netlbl_lsm_secattr *secattr);
 int netlbl_sock_getattr(struct sock *sk,
@@ -340,6 +341,11 @@ int netlbl_skbuff_getattr(const struct s
 			  struct netlbl_lsm_secattr *secattr);
 void netlbl_skbuff_err(struct sk_buff *skb, int error);
 #else
+int netlbl_enabled(void)
+{
+	return 0;
+}
+
 static inline int netlbl_sock_setattr(struct sock *sk,
 				     const struct netlbl_lsm_secattr *secattr)
 {
net/netlabel/netlabel_cipso_v4.c +5 -0
Index: linux-2.6_netmsg_part_deux/net/netlabel/netlabel_cipso_v4.c
===================================================================
@@ -41,6 +41,7 @@
 
 #include "netlabel_user.h"
 #include "netlabel_cipso_v4.h"
+#include "netlabel_mgmt.h"
 
 /* Argument struct for cipso_v4_doi_walk() */
 struct netlbl_cipsov4_doiwalk_arg {
@@ -419,6 +420,8 @@ static int netlbl_cipsov4_add(struct sk_
 		ret_val = netlbl_cipsov4_add_pass(info);
 		break;
 	}
+	if (ret_val == 0)
+		netlbl_mgmt_protocount_inc();
 
 	audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
 					      &audit_info);
@@ -694,6 +697,8 @@ static int netlbl_cipsov4_remove(struct 
 	ret_val = cipso_v4_doi_remove(doi,
 				      &audit_info,
 				      netlbl_cipsov4_doi_free);
+	if (ret_val == 0)
+		netlbl_mgmt_protocount_dec();
 
 	audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
 					      &audit_info);
net/netlabel/netlabel_kapi.c +21 -0
Index: linux-2.6_netmsg_part_deux/net/netlabel/netlabel_kapi.c
===================================================================
@@ -38,6 +38,7 @@
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
 #include "netlabel_user.h"
+#include "netlabel_mgmt.h"
 
 /*
  * Security Attribute Functions
@@ -245,6 +246,26 @@ int netlbl_secattr_catmap_setrng(struct 
  */
 
 /**
+ * netlbl_enabled - Determine if the NetLabel subsystem is enabled
+ *
+ * Description:
+ * The LSM can use this function to determine if it should use NetLabel
+ * security attributes in it's enforcement mechanism.  Currently, NetLabel is
+ * considered to be enabled when it's configuration contains a valid setup for
+ * at least one labeled protocol (i.e. NetLabel can understand incoming
+ * labeled packets of at least one type); otherwise NetLabel is considered to
+ * be disabled.
+ *
+ */
+int netlbl_enabled(void)
+{
+	/* XXX - at some point we probably want to expose this mechanism to
+	 * the user as well so that admins can toggle NetLabel regardless of
+	 * the configuration */
+	return (netlbl_mgmt_protocount_value() > 0 ? 1 : 0);
+}
+
+/**
  * netlbl_socket_setattr - Label a socket using the correct protocol
  * @sk: the socket to label
  * @secattr: the security attributes
net/netlabel/netlabel_mgmt.c +65 -0

77 lines not on this page · raw message

net/netlabel/netlabel_mgmt.h +5 -0
Index: linux-2.6_netmsg_part_deux/net/netlabel/netlabel_mgmt.h
===================================================================
@@ -168,4 +168,9 @@ enum {
 /* NetLabel protocol functions */
 int netlbl_mgmt_genl_init(void);
 
+/* NetLabel misc management functions */
+void netlbl_mgmt_protocount_inc(void);
+void netlbl_mgmt_protocount_dec(void);
+u32 netlbl_mgmt_protocount_value(void);
+
 #endif
security/selinux/netlabel.c +18 -3
Index: linux-2.6_netmsg_part_deux/security/selinux/netlabel.c
===================================================================
@@ -155,6 +155,11 @@ int selinux_netlbl_skbuff_getsid(struct 
 	int rc;
 	struct netlbl_lsm_secattr secattr;
 
+	if (!netlbl_enabled()) {
+		*sid = SECSID_NULL;
+		return 0;
+	}
+
 	netlbl_secattr_init(&secattr);
 	rc = netlbl_skbuff_getattr(skb, &secattr);
 	if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
@@ -295,12 +300,22 @@ int selinux_netlbl_sock_rcv_skb(struct s
 	int rc;
 	u32 nlbl_sid;
 	u32 perm;
+	struct netlbl_lsm_secattr secattr;
+
+	if (!netlbl_enabled())
+		return 0;
 
-	rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &nlbl_sid);
+	netlbl_secattr_init(&secattr);
+	rc = netlbl_skbuff_getattr(skb, &secattr);
+	if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
+		rc = security_netlbl_secattr_to_sid(&secattr,
+						    SECINITSID_NETMSG,
+						    &nlbl_sid);
+	else
+		nlbl_sid = SECINITSID_UNLABELED;
+	netlbl_secattr_destroy(&secattr);
 	if (rc != 0)
 		return rc;
-	if (nlbl_sid == SECSID_NULL)
-		nlbl_sid = SECINITSID_UNLABELED;
 
 	switch (sksec->sclass) {
 	case SECCLASS_UDP_SOCKET:
Signature · 7 lines
paul moore
linux security @ hp

--
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.
#3 lore raw

Re: [PATCH 2/2] NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement

Quoted 6 lines · Paul Moore

Create a new NetLabel KAPI interface, netlbl_enabled(), which reports on the current runtime status of NetLabel based on the existing configuration. LSMs that make use of NetLabel, i.e. SELinux, can use this new function to determine if they should perform NetLabel access checks. This patch changes the NetLabel/SELinux glue code such that SELinux only enforces NetLabel related access checks when netlbl_enabled() returns true.

This should be the first patch, so a git-bisect doesn't break userspace. (I can re-order them for merge, as long as they apply ok in that order).

Signature · 7 lines
James Morris
<[email protected]>

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

Re: [PATCH 2/2] NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement

Quoted 11 lines · James Morris
Quoted 7 lines · Paul Moore

Create a new NetLabel KAPI interface, netlbl_enabled(), which reports on the current runtime status of NetLabel based on the existing configuration. LSMs that make use of NetLabel, i.e. SELinux, can use this new function to determine if they should perform NetLabel access checks. This patch changes the NetLabel/SELinux glue code such that SELinux only enforces NetLabel related access checks when netlbl_enabled() returns true.

This should be the first patch, so a git-bisect doesn't break userspace. (I can re-order them for merge, as long as they apply ok in that order).

That is fine with me. I suspect you might run into problems merging the patches for security/selinux/netlabel.c in reverse order, if that is the case let me know and I can respin the patchset for you.

Signature · 7 lines
paul moore
linux security @ hp

--
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.
#5 lore raw

Re: [PATCH 2/2] NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement

Quoted 3 lines · Paul Moore

That is fine with me. I suspect you might run into problems merging the patches for security/selinux/netlabel.c in reverse order, if that is the case let me know and I can respin the patchset for you.

Yep, they don't apply in that order. Could you please respin and test each one ?

- James

Signature · 7 lines
James Morris
<[email protected]>

--
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
#6 lore raw

Re: [PATCH 2/2] NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement

Quoted 7 lines · James Morris
Quoted 3 lines · Paul Moore

That is fine with me. I suspect you might run into problems merging the patches for security/selinux/netlabel.c in reverse order, if that is the case let me know and I can respin the patchset for you.

Yep, they don't apply in that order. Could you please respin and test each one ?

Yep, as soon as I sent that last email I tried it, saw they failed, and started fixing the patches. They apply cleanly now but testing them over the weekend is going to be a bit tricky - is it okay to wait until Monday to repost the patches?

Signature · 7 lines
paul moore
linux security @ hp

--
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.
#7 lore raw

Re: [PATCH 2/2] NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement

Quoted 6 lines · Paul Moore
Quoted 5 lines · James Morris
Quoted 3 lines · Paul Moore

That is fine with me. I suspect you might run into problems merging the patches for security/selinux/netlabel.c in reverse order, if that is the case let me know and I can respin the patchset for you.

Quoted 7 lines
Quoted 2 lines

Yep, they don't apply in that order. Could you please respin and test each one ?

Yep, as soon as I sent that last email I tried it, saw they failed, and started fixing the patches. They apply cleanly now but testing them over the weekend is going to be a bit tricky - is it okay to wait until Monday to repost the patches?

Yep.

Signature · 7 lines
James Morris
<[email protected]>

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