Sophie

Sophie

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

kernel-2.6.18-128.1.10.el5.src.rpm

From: Eric Paris <eparis@redhat.com>
Subject: [PATCH RHEL5] NetLabel: BZ 221504 Correct locking in 	selinux_netlbl_inode_permission and selinux_netlbl_socket_setsid
Date: Fri, 05 Jan 2007 17:47:18 -0500
Bugzilla: 221504
Message-Id: <1168037238.3339.98.camel@localhost.localdomain>
Changelog: NetLabel: fix locking issues


BZ 221504

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9883a13c72dbf8c518814b6091019643cdb34429
and also (not the same thing)
http://marc.theaimsgroup.com/?l=linux-netdev&m=116802828128874&w=2

Two different locking problems pointed out by the lockdep code.  One has
been fixed upstream and one was just submitted today.  I did hit both on
my local system and haven't hit either with this patch.  No flags (and
not even time for much upstream comment on the one patch) but they may
still be coming.  

The spinlock protecting the update of the "sksec->nlbl_state" variable
is not currently softirq safe which can lead to problems.  This patch
fixes this by changing the spin_{un}lock() functions into
spin_{un}lock_bh() functions.

do not call a sleeping lock API in an RCU read section. lock_sock_nested
can sleep, its BH counterpart doesn't. selinux_netlbl_inode_permission()
needs to use the BH counterpart unconditionally.

added BH disabling, because this function can be called from non-atomic
contexts too, so a naked bh_lock_sock() would be deadlock-prone.

--- linux-2.6.18.i686/security/selinux/ss/services.c.pre.netlabel.locking
+++ linux-2.6.18.i686/security/selinux/ss/services.c
@@ -2456,9 +2456,9 @@ static int selinux_netlbl_socket_setsid(
 
 	rc = netlbl_socket_setattr(sock, &secattr);
 	if (rc == 0) {
-		spin_lock(&sksec->nlbl_lock);
+		spin_lock_bh(&sksec->nlbl_lock);
 		sksec->nlbl_state = NLBL_LABELED;
-		spin_unlock(&sksec->nlbl_lock);
+		spin_unlock_bh(&sksec->nlbl_lock);
 	}
 
 netlbl_socket_setsid_return:
@@ -2624,9 +2624,11 @@ int selinux_netlbl_inode_permission(stru
 		rcu_read_unlock();
 		return 0;
 	}
-	lock_sock(sock->sk);
+	local_bh_disable();
+	bh_lock_sock_nested(sock->sk);
 	rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
-	release_sock(sock->sk);
+	bh_unlock_sock(sock->sk);
+	local_bh_enable();
 	rcu_read_unlock();
 
 	return rc;