Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1597

kernel-2.6.18-128.1.10.el5.src.rpm

From: Eric Paris <eparis@redhat.com>
Subject: [RHEL5 PATCH 1/3] BZ 218097  NetLabel: bring current with 	upstream: bugs
Date: Fri, 01 Dec 2006 15:15:14 -0500
Bugzilla: 218097
Message-Id: <1165004114.2079.177.camel@localhost.localdomain>
Changelog: NetLabel: bring current with upstream: bugs


BZ 218097 Part 1:

The bugs patch consists of patches 6,8,11, and 12 from the upstream
patch set.  11 would be better described as performance/cleanup, but
since patch 12 requires changes in 11 I decided to bring it in with the
bugs patch.

http://www.mail-archive.com/netdev@vger.kernel.org/msg26592.html

****
Patch 6:
Currently the CIPSOv4 engine does not do any sort of checking when a new
DOI definition is added.  The tags are still verified but only as a side
effect of normal NetLabel operation (packet processing, socket labeling,
etc.) which would cause application errors due to the faulty
configuration.  This patch adds tag checking when new DOI definition are
added allowing us to catch these configuration problems when they
happen.

Patch 8:
The CIPSOv4 translated tag #1 mapping does not always return the correct
error code if the desired mapping does not exist; instead of returning
-EPERM it returns -ENOSPC indicating that the buffer is not large enough
to hold the translated value.  This was caused by failing to check a
specific error condition.  This patch fixes this so that unknown
mappings return -EPERM which is consistent with the rest of the related
CIPSOv4 code.

Patch 11:
This patch does a lot of cleanup in the SELinux NetLabel support code.
A summary of the changes include:

* Use RCU locking for the NetLabel state variable in the
  skk_security_struct instead of using the inode_security_struct mutex.
* Remove unnecessary parameters in selinux_netlbl_socket_post_create().
* Rename selinux_netlbl_sk_clone_security() to
  selinux_netlbl_sk_security_clone() to better fit the other NetLabel
  sk_security functions.
* Improvements to selinux_netlbl_inode_permission() to help reduce the 
  cost of the common case.

Patch 12:
Now that labeled IPsec makes use of the peer_sid field in the
sk_security_struct we can remove a lot of the special cases between
labeled IPsec and NetLabel.  In addition, create a new function,
security_skb_extlbl_sid(), which we can use in several places to get the
security context of the packet's external label which allows us to
further simplify the code in a few places.

-Eric

--- linux-2.6.18.i686/security/selinux/hooks.c.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/hooks.c	2006-11-27 18:46:37.000000000 -0500
@@ -3096,9 +3096,7 @@ static int selinux_socket_post_create(st
 	if (sock->sk) {
 		sksec = sock->sk->sk_security;
 		sksec->sid = isec->sid;
-		err = selinux_netlbl_socket_post_create(sock,
-							family,
-							isec->sid);
+		err = selinux_netlbl_socket_post_create(sock);
 	}
 
 	return err;
@@ -3519,27 +3517,16 @@ static int selinux_socket_getpeersec_str
 	u32 scontext_len;
 	struct sk_security_struct *ssec;
 	struct inode_security_struct *isec;
-	u32 peer_sid = 0;
+	u32 peer_sid = SECSID_NULL;
 
 	isec = SOCK_INODE(sock)->i_security;
 
-	/* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
-	if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
+	if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
+	    isec->sclass == SECCLASS_TCP_SOCKET) {
 		ssec = sock->sk->sk_security;
 		peer_sid = ssec->peer_sid;
 	}
-	else if (isec->sclass == SECCLASS_TCP_SOCKET) {
-		peer_sid = selinux_netlbl_socket_getpeersec_stream(sock);
-		if (peer_sid == SECSID_NULL) {
-			ssec = sock->sk->sk_security;
-			peer_sid = ssec->peer_sid;
-		}
-		if (peer_sid == SECSID_NULL) {
-			err = -ENOPROTOOPT;
-			goto out;
-		}
-	}
-	else {
+	if (peer_sid == SECSID_NULL) {
 		err = -ENOPROTOOPT;
 		goto out;
 	}
@@ -3571,13 +3558,12 @@ static int selinux_socket_getpeersec_dgr
 	u32 peer_secid = SECSID_NULL;
 	int err = 0;
 
-	if (sock && (sock->sk->sk_family == PF_UNIX))
+	if (sock && sock->sk->sk_family == PF_UNIX)
 		selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
-	else if (skb) {
-		peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb);
-		if (peer_secid == SECSID_NULL)
-			peer_secid = selinux_socket_getpeer_dgram(skb);
-	}
+	else if (skb)
+		security_skb_extlbl_sid(skb,
+					SECINITSID_UNLABELED,
+					&peer_secid);
 	
 	if (peer_secid == SECSID_NULL)
 		err = -EINVAL;
@@ -3604,7 +3590,7 @@ static void selinux_sk_clone_security(co
 	newssec->sid = ssec->sid;
 	newssec->peer_sid = ssec->peer_sid;
 
-	selinux_netlbl_sk_clone_security(ssec, newssec);
+	selinux_netlbl_sk_security_clone(ssec, newssec);
 }
 
 static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -3638,17 +3624,10 @@ int selinux_inet_conn_request(struct soc
 	u32 newsid;
 	u32 peersid;
 
-	newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid);
-	if (newsid != SECSID_NULL) {
-		req->secid = newsid;
-		return 0;
-	}
-
-	selinux_skb_xfrm_sid(skb, &peersid);
-
+	security_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid);
 	if (peersid == SECSID_NULL) {
 		req->secid = sksec->sid;
-		req->peer_secid = 0;
+		req->peer_secid = SECSID_NULL;
 		return 0;
 	}
 
@@ -3672,7 +3651,9 @@ void selinux_inet_csk_clone(struct sock 
 	   So we will wait until sock_graft to do it, by which
 	   time it will have been created and available. */
 
-	selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family);
+	/* 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);
 }
 
 static void selinux_inet_conn_established(struct sock *sk,
@@ -3680,7 +3661,7 @@ static void selinux_inet_conn_establishe
 {
 	struct sk_security_struct *sksec = sk->sk_security;
 
-	selinux_skb_xfrm_sid(skb, &sksec->peer_sid);
+	security_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid);
 }
 
 void selinux_req_classify_flow(const struct request_sock *req, struct flowi *fl)
--- linux-2.6.18.i686/security/selinux/ss/services.c.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/ss/services.c	2006-11-27 18:46:37.000000000 -0500
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/spinlock.h>
+#include <linux/rcupdate.h>
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/sched.h>
@@ -49,6 +50,7 @@
 #include "mls.h"
 #include "objsec.h"
 #include "selinux_netlabel.h"
+#include "xfrm.h"
 
 extern void selnl_notify_policyload(u32 seqno);
 unsigned int policydb_loaded_version;
@@ -2145,6 +2147,32 @@ void selinux_audit_set_callback(int (*ca
 	aurule_callback = callback;
 }
 
+/**
+ * security_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.
+ *
+ */
+void security_skb_extlbl_sid(struct sk_buff *skb, u32 base_sid, u32 *sid)
+{
+	u32 xfrm_sid;
+	u32 nlbl_sid;
+
+	selinux_skb_xfrm_sid(skb, &xfrm_sid);
+	if (selinux_netlbl_skbuff_getsid(skb,
+					 (xfrm_sid == SECSID_NULL ?
+					  base_sid : xfrm_sid),
+					 &nlbl_sid) != 0)
+		nlbl_sid = SECSID_NULL;
+
+	*sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+}
+
 #ifdef CONFIG_NETLABEL
 /*
  * This is the structure we store inside the NetLabel cache block.
@@ -2360,9 +2388,7 @@ netlbl_secattr_to_sid_return_cleanup:
  * assign to the packet.  Returns zero on success, negative values on failure.
  *
  */
-static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
-					u32 base_sid,
-					u32 *sid)
+int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid)
 {
 	int rc;
 	struct netlbl_lsm_secattr secattr;
@@ -2386,7 +2412,9 @@ static int selinux_netlbl_skbuff_getsid(
  *
  * Description:
  * Attempt to label a socket using the NetLabel mechanism using the given
- * SID.  Returns zero values on success, negative values on failure.
+ * SID.  Returns zero values on success, negative values on failure.  The
+ * caller is responsibile for calling rcu_read_lock() before calling this
+ * this function and rcu_read_unlock() after this function returns.
  *
  */
 static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
@@ -2420,8 +2448,11 @@ static int selinux_netlbl_socket_setsid(
 		goto netlbl_socket_setsid_return;
 
 	rc = netlbl_socket_setattr(sock, &secattr);
-	if (rc == 0)
+	if (rc == 0) {
+		spin_lock(&sksec->nlbl_lock);
 		sksec->nlbl_state = NLBL_LABELED;
+		spin_unlock(&sksec->nlbl_lock);
+	}
 
 netlbl_socket_setsid_return:
 	POLICY_RDUNLOCK;
@@ -2430,6 +2461,25 @@ netlbl_socket_setsid_return:
 }
 
 /**
+ * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
+ * @ssec: the sk_security_struct
+ * @family: the socket family
+ *
+ * Description:
+ * Called when the NetLabel state of a sk_security_struct needs to be reset.
+ * 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)
+{
+        if (family == PF_INET)
+		ssec->nlbl_state = NLBL_REQUIRE;
+	else
+		ssec->nlbl_state = NLBL_UNSET;
+}
+
+/**
  * selinux_netlbl_sk_security_init - Setup the NetLabel fields
  * @ssec: the sk_security_struct
  * @family: the socket family
@@ -2442,14 +2492,13 @@ netlbl_socket_setsid_return:
 void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
 				     int family)
 {
-        if (family == PF_INET)
-		ssec->nlbl_state = NLBL_REQUIRE;
-	else
-		ssec->nlbl_state = NLBL_UNSET;
+	/* No locking needed, we are the only one who has access to ssec */
+	selinux_netlbl_sk_security_reset(ssec, family);
+	spin_lock_init(&ssec->nlbl_lock);
 }
 
 /**
- * selinux_netlbl_sk_clone_security - Copy the NetLabel fields
+ * selinux_netlbl_sk_security_clone - Copy the NetLabel fields
  * @ssec: the original sk_security_struct
  * @newssec: the cloned sk_security_struct
  *
@@ -2458,41 +2507,41 @@ void selinux_netlbl_sk_security_init(str
  * @newssec.
  *
  */
-void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
+void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
 				      struct sk_security_struct *newssec)
 {
+	/* We don't need to take newssec->nlbl_lock because we are the only
+	 * thread with access to newssec, but we do need to take the RCU read
+	 * lock as other threads could have access to ssec */
+	rcu_read_lock();
+	selinux_netlbl_sk_security_reset(newssec, ssec->sk->sk_family);
 	newssec->sclass = ssec->sclass;
-	if (ssec->nlbl_state != NLBL_UNSET)
-		newssec->nlbl_state = NLBL_REQUIRE;
-	else
-		newssec->nlbl_state = NLBL_UNSET;
+	rcu_read_unlock();
 }
 
 /**
  * selinux_netlbl_socket_post_create - Label a socket using NetLabel
  * @sock: the socket to label
- * @sock_family: the socket family
- * @sid: the SID to use
  *
  * Description:
  * 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_socket_post_create(struct socket *sock,
-				      int sock_family,
-				      u32 sid)
+int selinux_netlbl_socket_post_create(struct socket *sock)
 {
+	int rc = 0;
 	struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
 	struct sk_security_struct *sksec = sock->sk->sk_security;
 
 	sksec->sclass = isec->sclass;
 
-	if (sock_family != PF_INET)
-		return 0;
+	rcu_read_lock();
+	if (sksec->nlbl_state == NLBL_REQUIRE)
+		rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
+	rcu_read_unlock();
 
-	sksec->nlbl_state = NLBL_REQUIRE;
-	return selinux_netlbl_socket_setsid(sock, sid);
+	return rc;
 }
 
 /**
@@ -2514,8 +2563,12 @@ void selinux_netlbl_sock_graft(struct so
 
 	sksec->sclass = isec->sclass;
 
-	if (sk->sk_family != PF_INET)
+	rcu_read_lock();
+
+	if (sksec->nlbl_state != NLBL_REQUIRE) {
+		rcu_read_unlock();
 		return;
+	}
 
 	netlbl_secattr_init(&secattr);
 	if (netlbl_sock_getattr(sk, &secattr) == 0 &&
@@ -2526,35 +2579,12 @@ void selinux_netlbl_sock_graft(struct so
 		sksec->peer_sid = nlbl_peer_sid;
 	netlbl_secattr_destroy(&secattr);
 
-	sksec->nlbl_state = NLBL_REQUIRE;
-
 	/* Try to set the NetLabel on the socket to save time later, if we fail
 	 * here we will pick up the pieces in later calls to
 	 * selinux_netlbl_inode_permission(). */
 	selinux_netlbl_socket_setsid(sock, sksec->sid);
-}
-
-/**
- * selinux_netlbl_inet_conn_request - Handle a new connection request
- * @skb: the packet
- * @sock_sid: the SID of the parent socket
- *
- * Description:
- * If present, use the security attributes of the packet in @skb and the
- * parent sock's SID to arrive at a SID for the new child sock.  Returns the
- * SID of the connection or SECSID_NULL on failure.
- *
- */
-u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid)
-{
-	int rc;
-	u32 peer_sid;
 
-	rc = selinux_netlbl_skbuff_getsid(skb, sock_sid, &peer_sid);
-	if (rc != 0)
-		return SECSID_NULL;
-
-	return peer_sid;
+	rcu_read_unlock();
 }
 
 /**
@@ -2572,25 +2602,24 @@ u32 selinux_netlbl_inet_conn_request(str
 int selinux_netlbl_inode_permission(struct inode *inode, int mask)
 {
 	int rc;
-	struct inode_security_struct *isec;
 	struct sk_security_struct *sksec;
 	struct socket *sock;
 
-	if (!S_ISSOCK(inode->i_mode))
+	if (!S_ISSOCK(inode->i_mode) ||
+	    ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
 		return 0;
-
 	sock = SOCKET_I(inode);
-	isec = inode->i_security;
 	sksec = sock->sk->sk_security;
-	down(&isec->sem);
-	if (unlikely(sksec->nlbl_state == NLBL_REQUIRE &&
-		     (mask & (MAY_WRITE | MAY_APPEND)))) {
-		lock_sock(sock->sk);
-		rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
-		release_sock(sock->sk);
-	} else
-		rc = 0;
-	up(&isec->sem);
+
+	rcu_read_lock();
+	if (sksec->nlbl_state != NLBL_REQUIRE) {
+		rcu_read_unlock();
+		return 0;
+	}
+	lock_sock(sock->sk);
+	rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
+	release_sock(sock->sk);
+	rcu_read_unlock();
 
 	return rc;
 }
@@ -2648,42 +2677,6 @@ int selinux_netlbl_sock_rcv_skb(struct s
 }
 
 /**
- * selinux_netlbl_socket_getpeersec_stream - Return the connected peer's SID
- * @sock: the socket
- *
- * Description:
- * Examine @sock to find the connected peer's SID.  Returns the SID on success
- * or SECSID_NULL on error.
- *
- */
-u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
-{
-	struct sk_security_struct *sksec = sock->sk->sk_security;
-	return sksec->peer_sid;
-}
-
-/**
- * selinux_netlbl_socket_getpeersec_dgram - Return the SID of a NetLabel packet
- * @skb: the packet
- *
- * Description:
- * Examine @skb to find the SID assigned to it by NetLabel.  Returns the SID on
- * success, SECSID_NULL on error.
- *
- */
-u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
-{
-	int peer_sid;
-
-	if (selinux_netlbl_skbuff_getsid(skb,
-					 SECINITSID_UNLABELED,
-					 &peer_sid) != 0)
-		return SECSID_NULL;
-
-	return peer_sid;
-}
-
-/**
  * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
  * @sock: the socket
  * @level: the socket level or protocol
@@ -2701,12 +2694,10 @@ int selinux_netlbl_socket_setsockopt(str
 				     int optname)
 {
 	int rc = 0;
-	struct inode *inode = SOCK_INODE(sock);
 	struct sk_security_struct *sksec = sock->sk->sk_security;
-	struct inode_security_struct *isec = inode->i_security;
 	struct netlbl_lsm_secattr secattr;
 
-	down(&isec->sem);
+	rcu_read_lock();
 	if (level == IPPROTO_IP && optname == IP_OPTIONS &&
 	    sksec->nlbl_state == NLBL_LABELED) {
 		netlbl_secattr_init(&secattr);
@@ -2715,7 +2706,7 @@ int selinux_netlbl_socket_setsockopt(str
 			rc = -EACCES;
 		netlbl_secattr_destroy(&secattr);
 	}
-	up(&isec->sem);
+	rcu_read_unlock();
 
 	return rc;
 }
--- linux-2.6.18.i686/security/selinux/xfrm.c.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/xfrm.c	2006-11-27 18:46:37.000000000 -0500
@@ -372,39 +372,6 @@ void selinux_xfrm_state_free(struct xfrm
 		kfree(ctx);
 }
 
-/*
- * SELinux internal function to retrieve the context of a UDP packet
- * based on its security association.
- *
- * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message
- * type SCM_SECURITY.
- */
-u32 selinux_socket_getpeer_dgram(struct sk_buff *skb)
-{
-	struct sec_path *sp;
-
-	if (skb == NULL)
-		return SECSID_NULL;
-
-	if (skb->sk->sk_protocol != IPPROTO_UDP)
-		return SECSID_NULL;
-
-	sp = skb->sp;
-	if (sp) {
-		int i;
-
-		for (i = sp->len-1; i >= 0; i--) {
-			struct xfrm_state *x = sp->xvec[i];
-			if (selinux_authorizable_xfrm(x)) {
-				struct xfrm_sec_ctx *ctx = x->security;
-				return ctx->ctx_sid;
-			}
-		}
-	}
-
-	return SECSID_NULL;
-}
-
  /*
   * LSM hook implementation that authorizes deletion of labeled SAs.
   */
--- linux-2.6.18.i686/security/selinux/include/xfrm.h.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/include/xfrm.h	2006-11-27 18:46:37.000000000 -0500
@@ -36,7 +36,6 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s
 			struct avc_audit_data *ad);
 int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
 			struct avc_audit_data *ad, u8 proto);
-u32 selinux_socket_getpeer_dgram(struct sk_buff *skb);
 int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
 #else
 static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
@@ -51,10 +50,6 @@ static inline int selinux_xfrm_postroute
 	return 0;
 }
 
-static inline int selinux_socket_getpeer_dgram(struct sk_buff *skb)
-{
-	return SECSID_NULL;
-}
 static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
 {
 	*sid = SECSID_NULL;
--- linux-2.6.18.i686/security/selinux/include/objsec.h.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/include/objsec.h	2006-11-27 18:46:37.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/fs.h>
 #include <linux/binfmts.h>
 #include <linux/in.h>
+#include <linux/spinlock.h>
 #include "flask.h"
 #include "avc.h"
 
@@ -107,6 +108,7 @@ struct sk_security_struct {
 		NLBL_REQUIRE,
 		NLBL_LABELED,
 	} nlbl_state;
+	spinlock_t nlbl_lock;		/* protects nlbl_state */
 #endif
 };
 
--- linux-2.6.18.i686/security/selinux/include/selinux_netlabel.h.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/include/selinux_netlabel.h	2006-11-27 18:46:37.000000000 -0500
@@ -38,19 +38,17 @@
 
 #ifdef CONFIG_NETLABEL
 void selinux_netlbl_cache_invalidate(void);
-int selinux_netlbl_socket_post_create(struct socket *sock,
-				      int sock_family,
-				      u32 sid);
+int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid);
+int selinux_netlbl_socket_post_create(struct socket *sock);
 void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
-u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid);
 int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
 				struct sk_buff *skb,
 				struct avc_audit_data *ad);
-u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock);
-u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb);
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
+				      int family);
 void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
 				     int family);
-void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
+void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
 				      struct sk_security_struct *newssec);
 int selinux_netlbl_inode_permission(struct inode *inode, int mask);
 int selinux_netlbl_socket_setsockopt(struct socket *sock,
@@ -62,23 +60,23 @@ static inline void selinux_netlbl_cache_
 	return;
 }
 
-static inline int selinux_netlbl_socket_post_create(struct socket *sock,
-						    int sock_family,
-						    u32 sid)
+static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
+					       u32 base_sid,
+					       u32 *sid)
 {
+	*sid = SECSID_NULL;
 	return 0;
 }
 
-static inline void selinux_netlbl_sock_graft(struct sock *sk,
-					     struct socket *sock)
+static inline int selinux_netlbl_socket_post_create(struct socket *sock)
 {
-	return;
+	return 0;
 }
 
-static inline u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb,
-						   u32 sock_sid)
+static inline void selinux_netlbl_sock_graft(struct sock *sk,
+					     struct socket *sock)
 {
-	return SECSID_NULL;
+	return;
 }
 
 static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
@@ -88,14 +86,11 @@ static inline int selinux_netlbl_sock_rc
 	return 0;
 }
 
-static inline u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
-{
-	return SECSID_NULL;
-}
-
-static inline u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
+static inline void selinux_netlbl_sk_security_reset(
+					       struct sk_security_struct *ssec,
+					       int family)
 {
-	return SECSID_NULL;
+	return;
 }
 
 static inline void selinux_netlbl_sk_security_init(
@@ -105,7 +100,7 @@ static inline void selinux_netlbl_sk_sec
 	return;
 }
 
-static inline void selinux_netlbl_sk_clone_security(
+static inline void selinux_netlbl_sk_security_clone(
 	                                   struct sk_security_struct *ssec,
 					   struct sk_security_struct *newssec)
 {
--- linux-2.6.18.i686/security/selinux/include/security.h.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/security/selinux/include/security.h	2006-11-27 18:47:49.000000000 -0500
@@ -34,6 +34,8 @@
 #define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
 #endif
 
+struct sk_buff;
+
 extern int selinux_enabled;
 extern int selinux_mls_enabled;
 
@@ -80,6 +82,8 @@ int security_netif_sid(char *name, u32 *
 int security_node_sid(u16 domain, void *addr, u32 addrlen,
 	u32 *out_sid);
 
+void security_skb_extlbl_sid(struct sk_buff *skb, u32 base_sid, u32 *sid);
+
 int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
                                  u16 tclass);
 
--- linux-2.6.18.i686/net/ipv4/cipso_ipv4.c.pre.bugs	2006-11-27 18:46:23.000000000 -0500
+++ linux-2.6.18.i686/net/ipv4/cipso_ipv4.c	2006-11-27 18:46:37.000000000 -0500
@@ -447,8 +447,22 @@ static struct cipso_v4_doi *cipso_v4_doi
  */
 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
 {
+	u32 iter;
+
 	if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
 		return -EINVAL;
+	for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
+		switch (doi_def->tags[iter]) {
+		case CIPSO_V4_TAG_RBITMAP:
+			break;
+		case CIPSO_V4_TAG_INVALID:
+			if (iter == 0)
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
 
 	doi_def->valid = 1;
 	INIT_RCU_HEAD(&doi_def->rcu);
@@ -853,6 +867,8 @@ static int cipso_v4_map_cat_rbm_hton(con
 				return -EPERM;
 
 			net_spot = host_cat_array[host_spot];
+			if (net_spot >= CIPSO_V4_INV_CAT)
+				return -EPERM;
 			if (net_spot >= net_clen_bits)
 				return -ENOSPC;
 			cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
@@ -921,6 +937,8 @@ static int cipso_v4_map_cat_rbm_ntoh(con
 				return -EPERM;
 
 			host_spot = net_cat_array[net_spot];
+			if (host_spot >= CIPSO_V4_INV_CAT)
+				return -EPERM;
 			if (host_spot >= host_clen_bits)
 				return -ENOSPC;
 			cipso_v4_bitmap_setbit(host_cat, host_spot, 1);