diff options
-rw-r--r-- | security/selinux/hooks.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6e4937fe062b..b13be15165f5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -630,6 +630,16 @@ static inline u16 inode_mode_to_security_class(umode_t mode) | |||
630 | return SECCLASS_FILE; | 630 | return SECCLASS_FILE; |
631 | } | 631 | } |
632 | 632 | ||
633 | static inline int default_protocol_stream(int protocol) | ||
634 | { | ||
635 | return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP); | ||
636 | } | ||
637 | |||
638 | static inline int default_protocol_dgram(int protocol) | ||
639 | { | ||
640 | return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP); | ||
641 | } | ||
642 | |||
633 | static inline u16 socket_type_to_security_class(int family, int type, int protocol) | 643 | static inline u16 socket_type_to_security_class(int family, int type, int protocol) |
634 | { | 644 | { |
635 | switch (family) { | 645 | switch (family) { |
@@ -646,10 +656,16 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
646 | case PF_INET6: | 656 | case PF_INET6: |
647 | switch (type) { | 657 | switch (type) { |
648 | case SOCK_STREAM: | 658 | case SOCK_STREAM: |
649 | return SECCLASS_TCP_SOCKET; | 659 | if (default_protocol_stream(protocol)) |
660 | return SECCLASS_TCP_SOCKET; | ||
661 | else | ||
662 | return SECCLASS_RAWIP_SOCKET; | ||
650 | case SOCK_DGRAM: | 663 | case SOCK_DGRAM: |
651 | return SECCLASS_UDP_SOCKET; | 664 | if (default_protocol_dgram(protocol)) |
652 | case SOCK_RAW: | 665 | return SECCLASS_UDP_SOCKET; |
666 | else | ||
667 | return SECCLASS_RAWIP_SOCKET; | ||
668 | default: | ||
653 | return SECCLASS_RAWIP_SOCKET; | 669 | return SECCLASS_RAWIP_SOCKET; |
654 | } | 670 | } |
655 | break; | 671 | break; |
@@ -2970,6 +2986,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
2970 | 2986 | ||
2971 | /* | 2987 | /* |
2972 | * If PF_INET or PF_INET6, check name_bind permission for the port. | 2988 | * If PF_INET or PF_INET6, check name_bind permission for the port. |
2989 | * Multiple address binding for SCTP is not supported yet: we just | ||
2990 | * check the first address now. | ||
2973 | */ | 2991 | */ |
2974 | family = sock->sk->sk_family; | 2992 | family = sock->sk->sk_family; |
2975 | if (family == PF_INET || family == PF_INET6) { | 2993 | if (family == PF_INET || family == PF_INET6) { |
@@ -3014,12 +3032,12 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3014 | goto out; | 3032 | goto out; |
3015 | } | 3033 | } |
3016 | 3034 | ||
3017 | switch(sk->sk_protocol) { | 3035 | switch(isec->sclass) { |
3018 | case IPPROTO_TCP: | 3036 | case SECCLASS_TCP_SOCKET: |
3019 | node_perm = TCP_SOCKET__NODE_BIND; | 3037 | node_perm = TCP_SOCKET__NODE_BIND; |
3020 | break; | 3038 | break; |
3021 | 3039 | ||
3022 | case IPPROTO_UDP: | 3040 | case SECCLASS_UDP_SOCKET: |
3023 | node_perm = UDP_SOCKET__NODE_BIND; | 3041 | node_perm = UDP_SOCKET__NODE_BIND; |
3024 | break; | 3042 | break; |
3025 | 3043 | ||