aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2006-11-13 19:09:01 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:22:24 -0500
commit2ee92d46c6cabedd50edf6f273fa8cf84f707618 (patch)
treebdf7c64514a5063ba4ef41915f9efb6f803fc38a
parent90833aa4f496d69ca374af6acef7d1614c8693ff (diff)
[SELinux]: Add support for DCCP
This patch implements SELinux kernel support for DCCP (http://linux-net.osdl.org/index.php/DCCP), which is similar in operation to TCP in terms of connected state between peers. The SELinux support for DCCP is thus modeled on existing handling of TCP. A new DCCP socket class is introduced, to allow protocol differentation. The permissions for this class inherit all of the socket permissions, as well as the current TCP permissions (node_bind, name_bind etc). IPv4 and IPv6 are supported, although labeled networking is not, at this stage. Patches for SELinux userspace are at: http://people.redhat.com/jmorris/selinux/dccp/user/ I've performed some basic testing, and it seems to be working as expected. Adding policy support is similar to TCP, the only real difference being that it's a different protocol. Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--security/selinux/hooks.c66
-rw-r--r--security/selinux/include/av_inherit.h1
-rw-r--r--security/selinux/include/av_perm_to_string.h8
-rw-r--r--security/selinux/include/av_permissions.h32
-rw-r--r--security/selinux/include/class_to_string.h2
-rw-r--r--security/selinux/include/flask.h2
6 files changed, 103 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 956137baf3e7..0cf98740ddc6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -58,6 +58,7 @@
58#include <linux/netlink.h> 58#include <linux/netlink.h>
59#include <linux/tcp.h> 59#include <linux/tcp.h>
60#include <linux/udp.h> 60#include <linux/udp.h>
61#include <linux/dccp.h>
61#include <linux/quota.h> 62#include <linux/quota.h>
62#include <linux/un.h> /* for Unix socket types */ 63#include <linux/un.h> /* for Unix socket types */
63#include <net/af_unix.h> /* for Unix socket types */ 64#include <net/af_unix.h> /* for Unix socket types */
@@ -751,6 +752,8 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
751 return SECCLASS_UDP_SOCKET; 752 return SECCLASS_UDP_SOCKET;
752 else 753 else
753 return SECCLASS_RAWIP_SOCKET; 754 return SECCLASS_RAWIP_SOCKET;
755 case SOCK_DCCP:
756 return SECCLASS_DCCP_SOCKET;
754 default: 757 default:
755 return SECCLASS_RAWIP_SOCKET; 758 return SECCLASS_RAWIP_SOCKET;
756 } 759 }
@@ -2944,6 +2947,22 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
2944 break; 2947 break;
2945 } 2948 }
2946 2949
2950 case IPPROTO_DCCP: {
2951 struct dccp_hdr _dccph, *dh;
2952
2953 if (ntohs(ih->frag_off) & IP_OFFSET)
2954 break;
2955
2956 offset += ihlen;
2957 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
2958 if (dh == NULL)
2959 break;
2960
2961 ad->u.net.sport = dh->dccph_sport;
2962 ad->u.net.dport = dh->dccph_dport;
2963 break;
2964 }
2965
2947 default: 2966 default:
2948 break; 2967 break;
2949 } 2968 }
@@ -3004,6 +3023,18 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
3004 break; 3023 break;
3005 } 3024 }
3006 3025
3026 case IPPROTO_DCCP: {
3027 struct dccp_hdr _dccph, *dh;
3028
3029 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3030 if (dh == NULL)
3031 break;
3032
3033 ad->u.net.sport = dh->dccph_sport;
3034 ad->u.net.dport = dh->dccph_dport;
3035 break;
3036 }
3037
3007 /* includes fragments */ 3038 /* includes fragments */
3008 default: 3039 default:
3009 break; 3040 break;
@@ -3188,7 +3219,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3188 case SECCLASS_UDP_SOCKET: 3219 case SECCLASS_UDP_SOCKET:
3189 node_perm = UDP_SOCKET__NODE_BIND; 3220 node_perm = UDP_SOCKET__NODE_BIND;
3190 break; 3221 break;
3191 3222
3223 case SECCLASS_DCCP_SOCKET:
3224 node_perm = DCCP_SOCKET__NODE_BIND;
3225 break;
3226
3192 default: 3227 default:
3193 node_perm = RAWIP_SOCKET__NODE_BIND; 3228 node_perm = RAWIP_SOCKET__NODE_BIND;
3194 break; 3229 break;
@@ -3226,16 +3261,17 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3226 return err; 3261 return err;
3227 3262
3228 /* 3263 /*
3229 * If a TCP socket, check name_connect permission for the port. 3264 * If a TCP or DCCP socket, check name_connect permission for the port.
3230 */ 3265 */
3231 isec = SOCK_INODE(sock)->i_security; 3266 isec = SOCK_INODE(sock)->i_security;
3232 if (isec->sclass == SECCLASS_TCP_SOCKET) { 3267 if (isec->sclass == SECCLASS_TCP_SOCKET ||
3268 isec->sclass == SECCLASS_DCCP_SOCKET) {
3233 struct sock *sk = sock->sk; 3269 struct sock *sk = sock->sk;
3234 struct avc_audit_data ad; 3270 struct avc_audit_data ad;
3235 struct sockaddr_in *addr4 = NULL; 3271 struct sockaddr_in *addr4 = NULL;
3236 struct sockaddr_in6 *addr6 = NULL; 3272 struct sockaddr_in6 *addr6 = NULL;
3237 unsigned short snum; 3273 unsigned short snum;
3238 u32 sid; 3274 u32 sid, perm;
3239 3275
3240 if (sk->sk_family == PF_INET) { 3276 if (sk->sk_family == PF_INET) {
3241 addr4 = (struct sockaddr_in *)address; 3277 addr4 = (struct sockaddr_in *)address;
@@ -3254,11 +3290,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3254 if (err) 3290 if (err)
3255 goto out; 3291 goto out;
3256 3292
3293 perm = (isec->sclass == SECCLASS_TCP_SOCKET) ?
3294 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
3295
3257 AVC_AUDIT_DATA_INIT(&ad,NET); 3296 AVC_AUDIT_DATA_INIT(&ad,NET);
3258 ad.u.net.dport = htons(snum); 3297 ad.u.net.dport = htons(snum);
3259 ad.u.net.family = sk->sk_family; 3298 ad.u.net.family = sk->sk_family;
3260 err = avc_has_perm(isec->sid, sid, isec->sclass, 3299 err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad);
3261 TCP_SOCKET__NAME_CONNECT, &ad);
3262 if (err) 3300 if (err)
3263 goto out; 3301 goto out;
3264 } 3302 }
@@ -3446,7 +3484,13 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3446 node_perm = NODE__TCP_RECV; 3484 node_perm = NODE__TCP_RECV;
3447 recv_perm = TCP_SOCKET__RECV_MSG; 3485 recv_perm = TCP_SOCKET__RECV_MSG;
3448 break; 3486 break;
3449 3487
3488 case SECCLASS_DCCP_SOCKET:
3489 netif_perm = NETIF__DCCP_RECV;
3490 node_perm = NODE__DCCP_RECV;
3491 recv_perm = DCCP_SOCKET__RECV_MSG;
3492 break;
3493
3450 default: 3494 default:
3451 netif_perm = NETIF__RAWIP_RECV; 3495 netif_perm = NETIF__RAWIP_RECV;
3452 node_perm = NODE__RAWIP_RECV; 3496 node_perm = NODE__RAWIP_RECV;
@@ -3777,7 +3821,13 @@ static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *
3777 node_perm = NODE__TCP_SEND; 3821 node_perm = NODE__TCP_SEND;
3778 send_perm = TCP_SOCKET__SEND_MSG; 3822 send_perm = TCP_SOCKET__SEND_MSG;
3779 break; 3823 break;
3780 3824
3825 case SECCLASS_DCCP_SOCKET:
3826 netif_perm = NETIF__DCCP_SEND;
3827 node_perm = NODE__DCCP_SEND;
3828 send_perm = DCCP_SOCKET__SEND_MSG;
3829 break;
3830
3781 default: 3831 default:
3782 netif_perm = NETIF__RAWIP_SEND; 3832 netif_perm = NETIF__RAWIP_SEND;
3783 node_perm = NODE__RAWIP_SEND; 3833 node_perm = NODE__RAWIP_SEND;
diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
index a68fdd55597f..8377a4ba3b95 100644
--- a/security/selinux/include/av_inherit.h
+++ b/security/selinux/include/av_inherit.h
@@ -30,3 +30,4 @@
30 S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL) 30 S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL)
31 S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL) 31 S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL)
32 S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL) 32 S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL)
33 S_(SECCLASS_DCCP_SOCKET, socket, 0x00400000UL)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 09fc8a2345eb..ad9fb2d69b50 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -35,12 +35,16 @@
35 S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv") 35 S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv")
36 S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send") 36 S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send")
37 S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest") 37 S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
38 S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv")
39 S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send")
38 S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv") 40 S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
39 S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send") 41 S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
40 S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv") 42 S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
41 S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send") 43 S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send")
42 S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv") 44 S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv")
43 S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send") 45 S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
46 S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv")
47 S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send")
44 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto") 48 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto")
45 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn") 49 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn")
46 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom") 50 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom")
@@ -252,3 +256,7 @@
252 S_(SECCLASS_KEY, KEY__LINK, "link") 256 S_(SECCLASS_KEY, KEY__LINK, "link")
253 S_(SECCLASS_KEY, KEY__SETATTR, "setattr") 257 S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
254 S_(SECCLASS_KEY, KEY__CREATE, "create") 258 S_(SECCLASS_KEY, KEY__CREATE, "create")
259 S_(SECCLASS_CONTEXT, CONTEXT__TRANSLATE, "translate")
260 S_(SECCLASS_CONTEXT, CONTEXT__CONTAINS, "contains")
261 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
262 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 81f4f526c8b1..2de4b5fe3aa1 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -312,6 +312,8 @@
312#define NODE__RAWIP_RECV 0x00000010UL 312#define NODE__RAWIP_RECV 0x00000010UL
313#define NODE__RAWIP_SEND 0x00000020UL 313#define NODE__RAWIP_SEND 0x00000020UL
314#define NODE__ENFORCE_DEST 0x00000040UL 314#define NODE__ENFORCE_DEST 0x00000040UL
315#define NODE__DCCP_RECV 0x00000080UL
316#define NODE__DCCP_SEND 0x00000100UL
315 317
316#define NETIF__TCP_RECV 0x00000001UL 318#define NETIF__TCP_RECV 0x00000001UL
317#define NETIF__TCP_SEND 0x00000002UL 319#define NETIF__TCP_SEND 0x00000002UL
@@ -319,6 +321,8 @@
319#define NETIF__UDP_SEND 0x00000008UL 321#define NETIF__UDP_SEND 0x00000008UL
320#define NETIF__RAWIP_RECV 0x00000010UL 322#define NETIF__RAWIP_RECV 0x00000010UL
321#define NETIF__RAWIP_SEND 0x00000020UL 323#define NETIF__RAWIP_SEND 0x00000020UL
324#define NETIF__DCCP_RECV 0x00000040UL
325#define NETIF__DCCP_SEND 0x00000080UL
322 326
323#define NETLINK_SOCKET__IOCTL 0x00000001UL 327#define NETLINK_SOCKET__IOCTL 0x00000001UL
324#define NETLINK_SOCKET__READ 0x00000002UL 328#define NETLINK_SOCKET__READ 0x00000002UL
@@ -970,3 +974,31 @@
970#define KEY__LINK 0x00000010UL 974#define KEY__LINK 0x00000010UL
971#define KEY__SETATTR 0x00000020UL 975#define KEY__SETATTR 0x00000020UL
972#define KEY__CREATE 0x00000040UL 976#define KEY__CREATE 0x00000040UL
977
978#define CONTEXT__TRANSLATE 0x00000001UL
979#define CONTEXT__CONTAINS 0x00000002UL
980
981#define DCCP_SOCKET__IOCTL 0x00000001UL
982#define DCCP_SOCKET__READ 0x00000002UL
983#define DCCP_SOCKET__WRITE 0x00000004UL
984#define DCCP_SOCKET__CREATE 0x00000008UL
985#define DCCP_SOCKET__GETATTR 0x00000010UL
986#define DCCP_SOCKET__SETATTR 0x00000020UL
987#define DCCP_SOCKET__LOCK 0x00000040UL
988#define DCCP_SOCKET__RELABELFROM 0x00000080UL
989#define DCCP_SOCKET__RELABELTO 0x00000100UL
990#define DCCP_SOCKET__APPEND 0x00000200UL
991#define DCCP_SOCKET__BIND 0x00000400UL
992#define DCCP_SOCKET__CONNECT 0x00000800UL
993#define DCCP_SOCKET__LISTEN 0x00001000UL
994#define DCCP_SOCKET__ACCEPT 0x00002000UL
995#define DCCP_SOCKET__GETOPT 0x00004000UL
996#define DCCP_SOCKET__SETOPT 0x00008000UL
997#define DCCP_SOCKET__SHUTDOWN 0x00010000UL
998#define DCCP_SOCKET__RECVFROM 0x00020000UL
999#define DCCP_SOCKET__SENDTO 0x00040000UL
1000#define DCCP_SOCKET__RECV_MSG 0x00080000UL
1001#define DCCP_SOCKET__SEND_MSG 0x00100000UL
1002#define DCCP_SOCKET__NAME_BIND 0x00200000UL
1003#define DCCP_SOCKET__NODE_BIND 0x00400000UL
1004#define DCCP_SOCKET__NAME_CONNECT 0x00800000UL
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
index 24303b61309f..9f3ebb1bfae6 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -61,3 +61,5 @@
61 S_("appletalk_socket") 61 S_("appletalk_socket")
62 S_("packet") 62 S_("packet")
63 S_("key") 63 S_("key")
64 S_("context")
65 S_("dccp_socket")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index 95887aed2a68..67cef371ee00 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -63,6 +63,8 @@
63#define SECCLASS_APPLETALK_SOCKET 56 63#define SECCLASS_APPLETALK_SOCKET 56
64#define SECCLASS_PACKET 57 64#define SECCLASS_PACKET 57
65#define SECCLASS_KEY 58 65#define SECCLASS_KEY 58
66#define SECCLASS_CONTEXT 59
67#define SECCLASS_DCCP_SOCKET 60
66 68
67/* 69/*
68 * Security identifier indices for initial entities 70 * Security identifier indices for initial entities