netlabel: Prevent setsockopt() from changing the hop-by-hop option.
authorHuw Davies <huw@codeweavers.com>
Mon, 27 Jun 2016 19:05:27 +0000 (15:05 -0400)
committerPaul Moore <paul@paul-moore.com>
Mon, 27 Jun 2016 19:05:27 +0000 (15:05 -0400)
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>
security/selinux/netlabel.c

index 5470f32eca545c2883a000bc3ad1f617d793472a..2477a75f16e7274b643d7c033bccd68c6861f1bb 100644 (file)
@@ -409,6 +409,21 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
        return rc;
 }
 
+/**
+ * selinux_netlbl_option - Is this a NetLabel option
+ * @level: the socket level or protocol
+ * @optname: the socket option name
+ *
+ * Description:
+ * Returns true if @level and @optname refer to a NetLabel option.
+ * Helper for selinux_netlbl_socket_setsockopt().
+ */
+static inline int selinux_netlbl_option(int level, int optname)
+{
+       return (level == IPPROTO_IP && optname == IP_OPTIONS) ||
+               (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS);
+}
+
 /**
  * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
  * @sock: the socket
@@ -431,7 +446,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
        struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr secattr;
 
-       if (level == IPPROTO_IP && optname == IP_OPTIONS &&
+       if (selinux_netlbl_option(level, optname) &&
            (sksec->nlbl_state == NLBL_LABELED ||
             sksec->nlbl_state == NLBL_CONNLABELED)) {
                netlbl_secattr_init(&secattr);