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 /security | |
| 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>
Diffstat (limited to 'security')
| -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 |
