diff options
author | Huw Davies <huw@codeweavers.com> | 2016-06-27 15:05:27 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2016-06-27 15:05:27 -0400 |
commit | 1f440c99d3207d684a3ac48d6e528af548b5c915 (patch) | |
tree | 9cbeedd54d1e5363d1ae012ce75e5bbb1fe0ffb3 /security | |
parent | ceba1832b1b2da0149c51de62a847c00bca1677a (diff) |
netlabel: Prevent setsockopt() from changing the hop-by-hop option.
If a socket has a netlabel in place then don't let setsockopt() alter
the socket's IPv6 hop-by-hop option. This is in the same spirit as
the existing check for IPv4.
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/netlabel.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 5470f32eca54..2477a75f16e7 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -410,6 +410,21 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | |||
410 | } | 410 | } |
411 | 411 | ||
412 | /** | 412 | /** |
413 | * selinux_netlbl_option - Is this a NetLabel option | ||
414 | * @level: the socket level or protocol | ||
415 | * @optname: the socket option name | ||
416 | * | ||
417 | * Description: | ||
418 | * Returns true if @level and @optname refer to a NetLabel option. | ||
419 | * Helper for selinux_netlbl_socket_setsockopt(). | ||
420 | */ | ||
421 | static inline int selinux_netlbl_option(int level, int optname) | ||
422 | { | ||
423 | return (level == IPPROTO_IP && optname == IP_OPTIONS) || | ||
424 | (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS); | ||
425 | } | ||
426 | |||
427 | /** | ||
413 | * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel | 428 | * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel |
414 | * @sock: the socket | 429 | * @sock: the socket |
415 | * @level: the socket level or protocol | 430 | * @level: the socket level or protocol |
@@ -431,7 +446,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
431 | struct sk_security_struct *sksec = sk->sk_security; | 446 | struct sk_security_struct *sksec = sk->sk_security; |
432 | struct netlbl_lsm_secattr secattr; | 447 | struct netlbl_lsm_secattr secattr; |
433 | 448 | ||
434 | if (level == IPPROTO_IP && optname == IP_OPTIONS && | 449 | if (selinux_netlbl_option(level, optname) && |
435 | (sksec->nlbl_state == NLBL_LABELED || | 450 | (sksec->nlbl_state == NLBL_LABELED || |
436 | sksec->nlbl_state == NLBL_CONNLABELED)) { | 451 | sksec->nlbl_state == NLBL_CONNLABELED)) { |
437 | netlbl_secattr_init(&secattr); | 452 | netlbl_secattr_init(&secattr); |