Merge tag 'v3.13' into stable-3.14
authorPaul Moore <pmoore@redhat.com>
Tue, 28 Jan 2014 19:44:16 +0000 (14:44 -0500)
committerPaul Moore <pmoore@redhat.com>
Wed, 5 Feb 2014 15:39:48 +0000 (10:39 -0500)
Linux 3.13

Conflicts:
security/selinux/hooks.c

Trivial merge issue in selinux_inet_conn_request() likely due to me
including patches that I sent to the stable folks in my next tree
resulting in the patch hitting twice (I think).  Thankfully it was an
easy fix this time, but regardless, lesson learned, I will not do that
again.

1  2 
security/selinux/hooks.c

diff --combined security/selinux/hooks.c
@@@ -82,6 -82,7 +82,6 @@@
  #include <linux/syslog.h>
  #include <linux/user_namespace.h>
  #include <linux/export.h>
 -#include <linux/security.h>
  #include <linux/msg.h>
  #include <linux/shm.h>
  
@@@ -233,6 -234,14 +233,14 @@@ static int inode_alloc_security(struct 
        return 0;
  }
  
+ static void inode_free_rcu(struct rcu_head *head)
+ {
+       struct inode_security_struct *isec;
+       isec = container_of(head, struct inode_security_struct, rcu);
+       kmem_cache_free(sel_inode_cache, isec);
+ }
  static void inode_free_security(struct inode *inode)
  {
        struct inode_security_struct *isec = inode->i_security;
                list_del_init(&isec->list);
        spin_unlock(&sbsec->isec_lock);
  
-       inode->i_security = NULL;
-       kmem_cache_free(sel_inode_cache, isec);
+       /*
+        * The inode may still be referenced in a path walk and
+        * a call to selinux_inode_permission() can be made
+        * after inode_free_security() is called. Ideally, the VFS
+        * wouldn't do this, but fixing that is a much harder
+        * job. For now, simply free the i_security via RCU, and
+        * leave the current inode->i_security pointer intact.
+        * The inode will be freed after the RCU grace period too.
+        */
+       call_rcu(&isec->rcu, inode_free_rcu);
  }
  
  static int file_alloc_security(struct file *file)
@@@ -3989,7 -4006,7 +4005,7 @@@ static int selinux_socket_bind(struct s
                if (snum) {
                        int low, high;
  
-                       inet_get_local_port_range(&low, &high);
+                       inet_get_local_port_range(sock_net(sk), &low, &high);
  
                        if (snum < max(PROT_SOCK, low) || snum > high) {
                                err = sel_netport_sid(sk->sk_protocol,
@@@ -4473,10 -4490,14 +4489,10 @@@ static int selinux_inet_conn_request(st
  {
        struct sk_security_struct *sksec = sk->sk_security;
        int err;
 -      u16 family = sk->sk_family;
 +      u16 family = req->rsk_ops->family;
        u32 connsid;
        u32 peersid;
  
 -      /* handle mapped IPv4 packets arriving via IPv6 sockets */
 -      if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
 -              family = PF_INET;
 -
        err = selinux_skb_peerlbl_sid(skb, family, &peersid);
        if (err)
                return err;
@@@ -4721,7 -4742,7 +4737,7 @@@ static unsigned int selinux_ip_forward(
        return NF_ACCEPT;
  }
  
- static unsigned int selinux_ipv4_forward(unsigned int hooknum,
+ static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops,
                                         struct sk_buff *skb,
                                         const struct net_device *in,
                                         const struct net_device *out,
  }
  
  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- static unsigned int selinux_ipv6_forward(unsigned int hooknum,
+ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
                                         struct sk_buff *skb,
                                         const struct net_device *in,
                                         const struct net_device *out,
@@@ -4783,7 -4804,7 +4799,7 @@@ static unsigned int selinux_ip_output(s
        return NF_ACCEPT;
  }
  
- static unsigned int selinux_ipv4_output(unsigned int hooknum,
+ static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops,
                                        struct sk_buff *skb,
                                        const struct net_device *in,
                                        const struct net_device *out,
@@@ -4957,7 -4978,7 +4973,7 @@@ static unsigned int selinux_ip_postrout
        return NF_ACCEPT;
  }
  
- static unsigned int selinux_ipv4_postroute(unsigned int hooknum,
+ static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops,
                                           struct sk_buff *skb,
                                           const struct net_device *in,
                                           const struct net_device *out,
  }
  
  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- static unsigned int selinux_ipv6_postroute(unsigned int hooknum,
+ static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
                                           struct sk_buff *skb,
                                           const struct net_device *in,
                                           const struct net_device *out,