diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -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 | ||
