summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJoe Stringer <joe@wand.net.nz>2018-11-30 18:32:20 -0500
committerAlexei Starovoitov <ast@kernel.org>2018-11-30 20:17:38 -0500
commitf71c6143c2038df1cb43a4b9c90740d14f77467c (patch)
treefef0cee90ee0a015b24c8916c6ccb3983b47d688 /net
parentb7df9ada9a7700dbcca1ba53d217c01e3d48179c (diff)
bpf: Support sk lookup in netns with id 0
David Ahern and Nicolas Dichtel report that the handling of the netns id 0 is incorrect for the BPF socket lookup helpers: rather than finding the netns with id 0, it is resolving to the current netns. This renders the netns_id 0 inaccessible. To fix this, adjust the API for the netns to treat all negative s32 values as a lookup in the current netns (including u64 values which when truncated to s32 become negative), while any values with a positive value in the signed 32-bit integer space would result in a lookup for a socket in the netns corresponding to that id. As before, if the netns with that ID does not exist, no socket will be found. Any netns outside of these ranges will fail to find a corresponding socket, as those values are reserved for future usage. Signed-off-by: Joe Stringer <joe@wand.net.nz> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Joey Pabalinas <joeypabalinas@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/core/filter.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index 6ee605da990f..8d2c629501e2 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4890,22 +4890,23 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
4890 struct net *net; 4890 struct net *net;
4891 4891
4892 family = len == sizeof(tuple->ipv4) ? AF_INET : AF_INET6; 4892 family = len == sizeof(tuple->ipv4) ? AF_INET : AF_INET6;
4893 if (unlikely(family == AF_UNSPEC || netns_id > U32_MAX || flags)) 4893 if (unlikely(family == AF_UNSPEC || flags ||
4894 !((s32)netns_id < 0 || netns_id <= S32_MAX)))
4894 goto out; 4895 goto out;
4895 4896
4896 if (skb->dev) 4897 if (skb->dev)
4897 caller_net = dev_net(skb->dev); 4898 caller_net = dev_net(skb->dev);
4898 else 4899 else
4899 caller_net = sock_net(skb->sk); 4900 caller_net = sock_net(skb->sk);
4900 if (netns_id) { 4901 if ((s32)netns_id < 0) {
4902 net = caller_net;
4903 sk = sk_lookup(net, tuple, skb, family, proto);
4904 } else {
4901 net = get_net_ns_by_id(caller_net, netns_id); 4905 net = get_net_ns_by_id(caller_net, netns_id);
4902 if (unlikely(!net)) 4906 if (unlikely(!net))
4903 goto out; 4907 goto out;
4904 sk = sk_lookup(net, tuple, skb, family, proto); 4908 sk = sk_lookup(net, tuple, skb, family, proto);
4905 put_net(net); 4909 put_net(net);
4906 } else {
4907 net = caller_net;
4908 sk = sk_lookup(net, tuple, skb, family, proto);
4909 } 4910 }
4910 4911
4911 if (sk) 4912 if (sk)