Selinux in FC4 is blocking SCTP [PATCH RFC]

James Morris jmorris at namei.org
Fri Sep 30 06:49:02 UTC 2005


On Fri, 30 Sep 2005, James Morris wrote:

> We can't simply classify SCTP as 'raw', as it has some different 
> semantics, such as multiple local and remote addresses, which we need to 
> investigate and develop proper controls for.

Actually, this does like a viable short term solution until full SCTP 
support is available.  In the case of the extended IP level bind(2) 
checks, we just check the first/default IP address being bound, which is 
better than nothing.  (We could do a special detection of SCTP in there 
and avoid this check, but for what gain?)

Please review the following patch.

It changes the SELinux IP socket classification logic, which is currently 
broken (well, out of date), so that an IPPROTO_IP protocol value passed to 
socket(2) classify the socket as TCP or UDP.  Currently, a SOCK_STREAM 
with a protocol of IPPROTO_ARBITRARY will default to SECCLASS_TCP_SOCKET.  
With this patch, it will instead default to SECCLASS_RAWIP_SOCKET, the 
generic IP socket class.

The patch also drops the check for SOCK_RAW and converts it into a 
default, so that socket types like SOCK_DCCP and SOCK_SEQPACKET are 
classified as SECCLASS_RAWIP_SOCKET (instead of generic sockets).

This now causes all SCTP sockets to be classified as 
SECCLASS_RAWIP_SOCKET.

This patch also unifies the way IP sockets classes are determined in 
selinux_socket_bind(), so we use the already calculated value instead of 
trying to recalculate it (which can lead to inconsistencies).

To get SCTP working now in targeted policy,  permissions for the 
rawip_socket classs need to be added to unconfined_domain:

avc:  denied  { name_bind } for  pid=16484 comm="lt-sctp_test" src=3339 
scontext=root:system_r:unconfined_t tcontext=system_u:object_r:port_t 
tclass=rawip_socket

(that should be it, I think).

Comments?

---

 security/selinux/hooks.c |   30 ++++++++++++++++++++++++------
 1 files changed, 24 insertions(+), 6 deletions(-)

diff -X dontdiff -purN linux-2.6.14-rc2.s1/security/selinux/hooks.c linux-2.6.14-rc2.t/security/selinux/hooks.c
--- linux-2.6.14-rc2.s1/security/selinux/hooks.c	2005-09-24 10:08:25.000000000 -0400
+++ linux-2.6.14-rc2.t/security/selinux/hooks.c	2005-09-30 02:24:44.000000000 -0400
@@ -630,6 +630,16 @@ static inline u16 inode_mode_to_security
 	return SECCLASS_FILE;
 }
 
+static inline int default_protocol_stream(int protocol)
+{
+	return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
+}
+
+static inline int default_protocol_dgram(int protocol)
+{
+	return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
+}
+
 static inline u16 socket_type_to_security_class(int family, int type, int protocol)
 {
 	switch (family) {
@@ -646,10 +656,16 @@ static inline u16 socket_type_to_securit
 	case PF_INET6:
 		switch (type) {
 		case SOCK_STREAM:
-			return SECCLASS_TCP_SOCKET;
+			if (default_protocol_stream(protocol))
+				return SECCLASS_TCP_SOCKET;
+			else
+				return SECCLASS_RAWIP_SOCKET;
 		case SOCK_DGRAM:
-			return SECCLASS_UDP_SOCKET;
-		case SOCK_RAW:
+			if (default_protocol_dgram(protocol))
+				return SECCLASS_UDP_SOCKET;
+			else
+				return SECCLASS_RAWIP_SOCKET;
+		default:
 			return SECCLASS_RAWIP_SOCKET;
 		}
 		break;
@@ -2970,6 +2986,8 @@ static int selinux_socket_bind(struct so
 
 	/*
 	 * If PF_INET or PF_INET6, check name_bind permission for the port.
+	 * Multiple address binding for SCTP is not supported yet: we just
+	 * check the first address now.
 	 */
 	family = sock->sk->sk_family;
 	if (family == PF_INET || family == PF_INET6) {
@@ -3014,12 +3032,12 @@ static int selinux_socket_bind(struct so
 				goto out;
 		}
 		
-		switch(sk->sk_protocol) {
-		case IPPROTO_TCP:
+		switch(isec->sclass) {
+		case SECCLASS_TCP_SOCKET:
 			node_perm = TCP_SOCKET__NODE_BIND;
 			break;
 			
-		case IPPROTO_UDP:
+		case SECCLASS_UDP_SOCKET:
 			node_perm = UDP_SOCKET__NODE_BIND;
 			break;
 			




More information about the fedora-selinux-list mailing list