[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <f3f701803859d5aacff9134026de0ae656ede3a6.1477959702.git.tgraf@suug.ch>
Date: Tue, 1 Nov 2016 01:37:09 +0100
From: Thomas Graf <tgraf@...g.ch>
To: davem@...emloft.net
Cc: alexei.starovoitov@...il.com, daniel@...earbox.net,
tom@...bertland.com, roopa@...ulusnetworks.com,
netdev@...r.kernel.org
Subject: [PATCH net-next v2 5/5] lwtunnel: Limit number of recursions on output to 5
Signed-off-by: Thomas Graf <tgraf@...g.ch>
---
net/core/lwtunnel.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index 554d901..6363d0b 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -231,6 +231,10 @@ int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
}
EXPORT_SYMBOL(lwtunnel_cmp_encap);
+/* Per CPU recursion counter for dst_output() redirections via LWT */
+#define DST_RECURSION_LIMIT 5
+DEFINE_PER_CPU(int, dst_recursion);
+
int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
@@ -246,11 +250,19 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
lwtstate->type > LWTUNNEL_ENCAP_MAX)
return 0;
+ if (unlikely(__this_cpu_read(dst_recursion) > DST_RECURSION_LIMIT)) {
+ net_crit_ratelimited("lwt: recursion limit reached of redirected dst_output calls\n");
+ return -EFAULT;
+ }
+
ret = -EOPNOTSUPP;
rcu_read_lock();
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
- if (likely(ops && ops->output))
+ if (likely(ops && ops->output)) {
+ __this_cpu_inc(dst_recursion);
ret = ops->output(net, sk, skb);
+ __this_cpu_dec(dst_recursion);
+ }
rcu_read_unlock();
if (ret == -EOPNOTSUPP)
--
2.7.4
Powered by blists - more mailing lists