diff options
author | James Morris <jmorris@namei.org> | 2006-11-13 19:09:01 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:22:24 -0500 |
commit | 2ee92d46c6cabedd50edf6f273fa8cf84f707618 (patch) | |
tree | bdf7c64514a5063ba4ef41915f9efb6f803fc38a | |
parent | 90833aa4f496d69ca374af6acef7d1614c8693ff (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.c | 66 | ||||
-rw-r--r-- | security/selinux/include/av_inherit.h | 1 | ||||
-rw-r--r-- | security/selinux/include/av_perm_to_string.h | 8 | ||||
-rw-r--r-- | security/selinux/include/av_permissions.h | 32 | ||||
-rw-r--r-- | security/selinux/include/class_to_string.h | 2 | ||||
-rw-r--r-- | security/selinux/include/flask.h | 2 |
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 |