]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'skb_to_full_sk'
authorDavid S. Miller <davem@davemloft.net>
Mon, 9 Nov 2015 01:56:39 +0000 (20:56 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 Nov 2015 01:56:39 +0000 (20:56 -0500)
Eric Dumazet says:

====================
net: add skb_to_full_sk() helper

Many contexts need to reach listener socket from skb attached
to a request socket. This patch series add skb_to_full_sk() to
clearly express this need and use it where appropriate.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/inet_sock.h
net/netfilter/nft_meta.c
net/netfilter/xt_owner.c
net/sched/cls_flow.c
net/sched/em_meta.c
security/selinux/hooks.c
security/selinux/netlabel.c
security/smack/smack_netfilter.c

index f5bf7310e3343468bddf7e51940a77ed497ad7f1..2134e6d815bcb0611a2f65cd7b4da44cb7762b8c 100644 (file)
@@ -210,6 +210,18 @@ struct inet_sock {
 #define IP_CMSG_ORIGDSTADDR    BIT(6)
 #define IP_CMSG_CHECKSUM       BIT(7)
 
+/* SYNACK messages might be attached to request sockets.
+ * Some places want to reach the listener in this case.
+ */
+static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
+{
+       struct sock *sk = skb->sk;
+
+       if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
+               sk = inet_reqsk(sk)->rsk_listener;
+       return sk;
+}
+
 static inline struct inet_sock *inet_sk(const struct sock *sk)
 {
        return (struct inet_sock *)sk;
index e4ad2c24bc4122e6470966f75da7b92f8273ba51..9dfaf4d55ee0b1bd92d8d7d2e64eebc42e8e5b04 100644 (file)
@@ -31,6 +31,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
        const struct nft_meta *priv = nft_expr_priv(expr);
        const struct sk_buff *skb = pkt->skb;
        const struct net_device *in = pkt->in, *out = pkt->out;
+       struct sock *sk;
        u32 *dest = &regs->data[priv->dreg];
 
        switch (priv->key) {
@@ -86,33 +87,35 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                *(u16 *)dest = out->type;
                break;
        case NFT_META_SKUID:
-               if (skb->sk == NULL || !sk_fullsock(skb->sk))
+               sk = skb_to_full_sk(skb);
+               if (!sk || !sk_fullsock(sk))
                        goto err;
 
-               read_lock_bh(&skb->sk->sk_callback_lock);
-               if (skb->sk->sk_socket == NULL ||
-                   skb->sk->sk_socket->file == NULL) {
-                       read_unlock_bh(&skb->sk->sk_callback_lock);
+               read_lock_bh(&sk->sk_callback_lock);
+               if (sk->sk_socket == NULL ||
+                   sk->sk_socket->file == NULL) {
+                       read_unlock_bh(&sk->sk_callback_lock);
                        goto err;
                }
 
                *dest = from_kuid_munged(&init_user_ns,
-                               skb->sk->sk_socket->file->f_cred->fsuid);
-               read_unlock_bh(&skb->sk->sk_callback_lock);
+                               sk->sk_socket->file->f_cred->fsuid);
+               read_unlock_bh(&sk->sk_callback_lock);
                break;
        case NFT_META_SKGID:
-               if (skb->sk == NULL || !sk_fullsock(skb->sk))
+               sk = skb_to_full_sk(skb);
+               if (!sk || !sk_fullsock(sk))
                        goto err;
 
-               read_lock_bh(&skb->sk->sk_callback_lock);
-               if (skb->sk->sk_socket == NULL ||
-                   skb->sk->sk_socket->file == NULL) {
-                       read_unlock_bh(&skb->sk->sk_callback_lock);
+               read_lock_bh(&sk->sk_callback_lock);
+               if (sk->sk_socket == NULL ||
+                   sk->sk_socket->file == NULL) {
+                       read_unlock_bh(&sk->sk_callback_lock);
                        goto err;
                }
                *dest = from_kgid_munged(&init_user_ns,
-                                skb->sk->sk_socket->file->f_cred->fsgid);
-               read_unlock_bh(&skb->sk->sk_callback_lock);
+                                sk->sk_socket->file->f_cred->fsgid);
+               read_unlock_bh(&sk->sk_callback_lock);
                break;
 #ifdef CONFIG_IP_ROUTE_CLASSID
        case NFT_META_RTCLASSID: {
@@ -168,9 +171,10 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                break;
 #ifdef CONFIG_CGROUP_NET_CLASSID
        case NFT_META_CGROUP:
-               if (skb->sk == NULL || !sk_fullsock(skb->sk))
+               sk = skb_to_full_sk(skb);
+               if (!sk || !sk_fullsock(sk))
                        goto err;
-               *dest = skb->sk->sk_classid;
+               *dest = sk->sk_classid;
                break;
 #endif
        default:
index ca2e577ed8ac196caca1190d9ae65557bd5ab8ed..1302b475abcbe0c6c2f7c93d416635005ae9b91f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/skbuff.h>
 #include <linux/file.h>
 #include <net/sock.h>
+#include <net/inet_sock.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_owner.h>
 
@@ -33,8 +34,9 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
        const struct xt_owner_match_info *info = par->matchinfo;
        const struct file *filp;
+       struct sock *sk = skb_to_full_sk(skb);
 
-       if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+       if (sk == NULL || sk->sk_socket == NULL)
                return (info->match ^ info->invert) == 0;
        else if (info->match & info->invert & XT_OWNER_SOCKET)
                /*
@@ -43,7 +45,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
                 */
                return false;
 
-       filp = skb->sk->sk_socket->file;
+       filp = sk->sk_socket->file;
        if (filp == NULL)
                return ((info->match ^ info->invert) &
                       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
index 536838b657bfcfb8e33596b7a7d5aec76b72e4f4..fbfec6a188390007fd30cf0a351e74f5b2d77057 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <net/inet_sock.h>
 
 #include <net/pkt_cls.h>
 #include <net/ip.h>
@@ -197,8 +198,11 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb)
 
 static u32 flow_get_skuid(const struct sk_buff *skb)
 {
-       if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
-               kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid;
+       struct sock *sk = skb_to_full_sk(skb);
+
+       if (sk && sk->sk_socket && sk->sk_socket->file) {
+               kuid_t skuid = sk->sk_socket->file->f_cred->fsuid;
+
                return from_kuid(&init_user_ns, skuid);
        }
        return 0;
@@ -206,8 +210,11 @@ static u32 flow_get_skuid(const struct sk_buff *skb)
 
 static u32 flow_get_skgid(const struct sk_buff *skb)
 {
-       if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
-               kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid;
+       struct sock *sk = skb_to_full_sk(skb);
+
+       if (sk && sk->sk_socket && sk->sk_socket->file) {
+               kgid_t skgid = sk->sk_socket->file->f_cred->fsgid;
+
                return from_kgid(&init_user_ns, skgid);
        }
        return 0;
index b5294ce20cd467063721cea69348cb35d7999921..f2aabc0089da203cd6b4d5b15eea40ad5299babe 100644 (file)
@@ -343,119 +343,145 @@ META_COLLECTOR(int_sk_refcnt)
 
 META_COLLECTOR(int_sk_rcvbuf)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_rcvbuf;
+       dst->value = sk->sk_rcvbuf;
 }
 
 META_COLLECTOR(int_sk_shutdown)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_shutdown;
+       dst->value = sk->sk_shutdown;
 }
 
 META_COLLECTOR(int_sk_proto)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_protocol;
+       dst->value = sk->sk_protocol;
 }
 
 META_COLLECTOR(int_sk_type)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_type;
+       dst->value = sk->sk_type;
 }
 
 META_COLLECTOR(int_sk_rmem_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = sk_rmem_alloc_get(skb->sk);
+       dst->value = sk_rmem_alloc_get(sk);
 }
 
 META_COLLECTOR(int_sk_wmem_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = sk_wmem_alloc_get(skb->sk);
+       dst->value = sk_wmem_alloc_get(sk);
 }
 
 META_COLLECTOR(int_sk_omem_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = atomic_read(&skb->sk->sk_omem_alloc);
+       dst->value = atomic_read(&sk->sk_omem_alloc);
 }
 
 META_COLLECTOR(int_sk_rcv_qlen)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_receive_queue.qlen;
+       dst->value = sk->sk_receive_queue.qlen;
 }
 
 META_COLLECTOR(int_sk_snd_qlen)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_write_queue.qlen;
+       dst->value = sk->sk_write_queue.qlen;
 }
 
 META_COLLECTOR(int_sk_wmem_queued)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_wmem_queued;
+       dst->value = sk->sk_wmem_queued;
 }
 
 META_COLLECTOR(int_sk_fwd_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_forward_alloc;
+       dst->value = sk->sk_forward_alloc;
 }
 
 META_COLLECTOR(int_sk_sndbuf)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_sndbuf;
+       dst->value = sk->sk_sndbuf;
 }
 
 META_COLLECTOR(int_sk_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = (__force int) skb->sk->sk_allocation;
+       dst->value = (__force int) sk->sk_allocation;
 }
 
 META_COLLECTOR(int_sk_hash)
@@ -469,92 +495,112 @@ META_COLLECTOR(int_sk_hash)
 
 META_COLLECTOR(int_sk_lingertime)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_lingertime / HZ;
+       dst->value = sk->sk_lingertime / HZ;
 }
 
 META_COLLECTOR(int_sk_err_qlen)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_error_queue.qlen;
+       dst->value = sk->sk_error_queue.qlen;
 }
 
 META_COLLECTOR(int_sk_ack_bl)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_ack_backlog;
+       dst->value = sk->sk_ack_backlog;
 }
 
 META_COLLECTOR(int_sk_max_ack_bl)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_max_ack_backlog;
+       dst->value = sk->sk_max_ack_backlog;
 }
 
 META_COLLECTOR(int_sk_prio)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_priority;
+       dst->value = sk->sk_priority;
 }
 
 META_COLLECTOR(int_sk_rcvlowat)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_rcvlowat;
+       dst->value = sk->sk_rcvlowat;
 }
 
 META_COLLECTOR(int_sk_rcvtimeo)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_rcvtimeo / HZ;
+       dst->value = sk->sk_rcvtimeo / HZ;
 }
 
 META_COLLECTOR(int_sk_sndtimeo)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_sndtimeo / HZ;
+       dst->value = sk->sk_sndtimeo / HZ;
 }
 
 META_COLLECTOR(int_sk_sendmsg_off)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_frag.offset;
+       dst->value = sk->sk_frag.offset;
 }
 
 META_COLLECTOR(int_sk_write_pend)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_write_pending;
+       dst->value = sk->sk_write_pending;
 }
 
 /**************************************************************************
index c9b2d546747787d1464ff1185d3b853ad459979c..23307da15f1db7f7cd6612805e11c0efa916550a 100644 (file)
@@ -4931,23 +4931,11 @@ static unsigned int selinux_ipv4_output(void *priv,
        return selinux_ip_output(skb, PF_INET);
 }
 
-/* SYNACK messages might be attached to request sockets.
- * To get back to sk_security, we need to look at the listener.
- */
-static struct sock *selinux_skb_sk(const struct sk_buff *skb)
-{
-       struct sock *sk = skb->sk;
-
-       if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
-               sk = inet_reqsk(sk)->rsk_listener;
-       return sk;
-}
-
 static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                                                int ifindex,
                                                u16 family)
 {
-       struct sock *sk = selinux_skb_sk(skb);
+       struct sock *sk = skb_to_full_sk(skb);
        struct sk_security_struct *sksec;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
@@ -5002,7 +4990,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
        if (!secmark_active && !peerlbl_active)
                return NF_ACCEPT;
 
-       sk = selinux_skb_sk(skb);
+       sk = skb_to_full_sk(skb);
 
 #ifdef CONFIG_XFRM
        /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
index 0364120d1ec8705da7e8c1636f645d0885731509..1f989a539fd4abe08e3797b5d49f7b26ded4fe41 100644 (file)
@@ -245,7 +245,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 
        /* if this is a locally generated packet check to see if it is already
         * being labeled by it's parent socket, if it is just exit */
-       sk = skb->sk;
+       sk = skb_to_full_sk(skb);
        if (sk != NULL) {
                struct sk_security_struct *sksec = sk->sk_security;
                if (sksec->nlbl_state != NLBL_REQSKB)
index 6d1706c9777e64fc69ca305e6ef55a2d563bb29d..aa6bf1b22ec5b3ec3d8e64db683d7db92b2c4f1b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/netdevice.h>
+#include <net/inet_sock.h>
 #include "smack.h"
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -25,11 +26,12 @@ static unsigned int smack_ipv6_output(void *priv,
                                        struct sk_buff *skb,
                                        const struct nf_hook_state *state)
 {
+       struct sock *sk = skb_to_full_sk(skb);
        struct socket_smack *ssp;
        struct smack_known *skp;
 
-       if (skb && skb->sk && skb->sk->sk_security) {
-               ssp = skb->sk->sk_security;
+       if (sk && sk->sk_security) {
+               ssp = sk->sk_security;
                skp = ssp->smk_out;
                skb->secmark = skp->smk_secid;
        }
@@ -42,11 +44,12 @@ static unsigned int smack_ipv4_output(void *priv,
                                        struct sk_buff *skb,
                                        const struct nf_hook_state *state)
 {
+       struct sock *sk = skb_to_full_sk(skb);
        struct socket_smack *ssp;
        struct smack_known *skp;
 
-       if (skb && skb->sk && skb->sk->sk_security) {
-               ssp = skb->sk->sk_security;
+       if (sk && sk->sk_security) {
+               ssp = sk->sk_security;
                skp = ssp->smk_out;
                skb->secmark = skp->smk_secid;
        }