Skip to content

Commit

Permalink
kernel: fix conntrack leak for flow_offload connections and timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
coolsnowwolf committed Jun 14, 2018
1 parent bce04f5 commit 6eab209
Show file tree
Hide file tree
Showing 17 changed files with 229 additions and 571 deletions.
4 changes: 2 additions & 2 deletions feeds.conf.default
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#src-git packages https://git.openwrt.org/feed/packages.git^1b73f267eae2dedc18969b70ed7c5d9b02288bac
src-git packages https://github.com/openwrt/packages.git
#src-git luci https://git.openwrt.org/project/luci.git^7d55be315d758b2a40494e732d7bdc300ee15c00
src-git luci https://github.com/openwrt/luci.git^80cb4fef8c7db0dadc373fef122d7abb092a7191
src-git luci https://github.com/openwrt/luci.git
#src-git luci https://github.com/openwrt/luci.git^80cb4fef8c7db0dadc373fef122d7abb092a7191
#src-git luci https://github.com/openwrt/luci.git;openwrt-18.06
src-git routing https://git.openwrt.org/feed/routing.git;openwrt-18.06
src-git telephony https://github.com/openwrt/telephony.git;openwrt-18.06
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Signed-off-by: Pablo Neira Ayuso <[email protected]>
static struct pernet_operations clusterip_net_ops = {
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6477,6 +6477,12 @@ static int __net_init nf_tables_init_net(struct net *net)
@@ -6477,6 +6477,12 @@ static int __net_init nf_tables_init_net
return 0;
}

Expand All @@ -34,7 +34,7 @@ Signed-off-by: Pablo Neira Ayuso <[email protected]>
int __nft_release_basechain(struct nft_ctx *ctx)
{
struct nft_rule *rule, *nr;
@@ -6554,6 +6560,7 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
@@ -6554,6 +6560,7 @@ static void __nft_release_afinfo(struct

static struct pernet_operations nf_tables_net_ops = {
.init = nf_tables_init_net,
Expand All @@ -44,7 +44,7 @@ Signed-off-by: Pablo Neira Ayuso <[email protected]>
static int __init nf_tables_module_init(void)
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(struct net *net)
@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(

static void __net_exit nfnl_log_net_exit(struct net *net)
{
Expand All @@ -62,7 +62,7 @@ Signed-off-by: Pablo Neira Ayuso <[email protected]>
static struct pernet_operations nfnl_log_net_ops = {
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_init(struct net *net)
@@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_ini

static void __net_exit nfnl_queue_net_exit(struct net *net)
{
Expand All @@ -80,7 +80,7 @@ Signed-off-by: Pablo Neira Ayuso <[email protected]>
static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list)
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1785,8 +1785,17 @@ static int __net_init xt_net_init(struct net *net)
@@ -1785,8 +1785,17 @@ static int __net_init xt_net_init(struct
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
From: Felix Fietkau <[email protected]>
Date: Wed, 13 Jun 2018 12:33:39 +0200
Subject: [PATCH] netfilter: nf_flow_table: fix offloaded connection timeout
corner case

The full teardown of offloaded flows is deferred to a gc work item,
however processing of packets by netfilter needs to happen immediately
after a teardown is requested, because the conntrack state needs to be
fixed up.

Since the IPS_OFFLOAD_BIT is still kept until the teardown is complete,
the netfilter conntrack gc can accidentally bump the timeout of a
connection where offload was just stopped, causing a conntrack entry
leak.

Fix this by moving the conntrack timeout bumping from conntrack core to
the nf_flow_offload and add a check to prevent bogus timeout bumps.

Signed-off-by: Felix Fietkau <[email protected]>
---

--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -978,18 +978,6 @@ static bool gc_worker_can_early_drop(con
return false;
}

-#define DAY (86400 * HZ)
-
-/* Set an arbitrary timeout large enough not to ever expire, this save
- * us a check for the IPS_OFFLOAD_BIT from the packet path via
- * nf_ct_is_expired().
- */
-static void nf_ct_offload_timeout(struct nf_conn *ct)
-{
- if (nf_ct_expires(ct) < DAY / 2)
- ct->timeout = nfct_time_stamp + DAY;
-}
-
static void gc_worker(struct work_struct *work)
{
unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u);
@@ -1026,10 +1014,8 @@ static void gc_worker(struct work_struct
tmp = nf_ct_tuplehash_to_ctrack(h);

scanned++;
- if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) {
- nf_ct_offload_timeout(tmp);
+ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status))
continue;
- }

if (nf_ct_is_expired(tmp)) {
nf_ct_gc_expired(tmp);
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -185,8 +185,27 @@ static const struct rhashtable_params nf
.automatic_shrinking = true,
};

+#define DAY (86400 * HZ)
+
+/* Set an arbitrary timeout large enough not to ever expire, this save
+ * us a check for the IPS_OFFLOAD_BIT from the packet path via
+ * nf_ct_is_expired().
+ */
+static void nf_ct_offload_timeout(struct flow_offload *flow)
+{
+ struct flow_offload_entry *entry;
+ struct nf_conn *ct;
+
+ entry = container_of(flow, struct flow_offload_entry, flow);
+ ct = entry->ct;
+
+ if (nf_ct_expires(ct) < DAY / 2)
+ ct->timeout = nfct_time_stamp + DAY;
+}
+
int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
{
+ nf_ct_offload_timeout(flow);
flow->timeout = (u32)jiffies;

rhashtable_insert_fast(&flow_table->rhashtable,
@@ -307,6 +326,8 @@ static int nf_flow_offload_gc_step(struc
rhashtable_walk_start(&hti);

while ((tuplehash = rhashtable_walk_next(&hti))) {
+ bool teardown;
+
if (IS_ERR(tuplehash)) {
err = PTR_ERR(tuplehash);
if (err != -EAGAIN)
@@ -319,9 +340,13 @@ static int nf_flow_offload_gc_step(struc

flow = container_of(tuplehash, struct flow_offload, tuplehash[0]);

- if (nf_flow_has_expired(flow) ||
- (flow->flags & (FLOW_OFFLOAD_DYING |
- FLOW_OFFLOAD_TEARDOWN)))
+ teardown = flow->flags & (FLOW_OFFLOAD_DYING |
+ FLOW_OFFLOAD_TEARDOWN);
+
+ if (!teardown)
+ nf_ct_offload_timeout(flow);
+
+ if (nf_flow_has_expired(flow) || teardown)
flow_offload_del(flow_table, flow);
}
out:
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
From: Felix Fietkau <[email protected]>
Date: Thu, 14 Jun 2018 11:20:09 +0200
Subject: [PATCH] netfilter: nf_flow_table: fix up ct state of flows after
timeout

If a connection simply times out instead of being torn down, it is left
active with a long timeout. Fix this by calling flow_offload_fixup_ct_state
here as well.

Signed-off-by: Felix Fietkau <[email protected]>
---

--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -233,6 +233,9 @@ static void flow_offload_del(struct nf_f
e = container_of(flow, struct flow_offload_entry, flow);
clear_bit(IPS_OFFLOAD_BIT, &e->ct->status);

+ if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
+ flow_offload_fixup_ct_state(e->ct);
+
flow_offload_free(flow);
}

Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <[email protected]>
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
--- /dev/null
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
@@ -0,0 +1,365 @@
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2018 Felix Fietkau <[email protected]>
+ *
Expand Down Expand Up @@ -326,6 +326,9 @@ Signed-off-by: Felix Fietkau <[email protected]>
+ if (!this_dst || !other_dst)
+ return -ENOENT;
+
+ if (dst_xfrm(this_dst) || dst_xfrm(other_dst))
+ return -EINVAL;
+
+ route->tuple[dir].dst = this_dst;
+ route->tuple[dir].ifindex = xt_in(par)->ifindex;
+ route->tuple[!dir].dst = other_dst;
Expand Down

This file was deleted.

14 changes: 7 additions & 7 deletions target/linux/generic/hack-4.14/721-phy_packets.patch
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <[email protected]>
*/
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2492,6 +2492,10 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
@@ -2491,6 +2491,10 @@ static inline int pskb_trim(struct sk_bu
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
}

Expand All @@ -67,7 +67,7 @@ Signed-off-by: Felix Fietkau <[email protected]>
/**
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
* @skb: buffer to alter
@@ -2622,16 +2626,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
@@ -2621,16 +2625,6 @@ static inline struct sk_buff *dev_alloc_
}


Expand Down Expand Up @@ -101,9 +101,9 @@ Signed-off-by: Felix Fietkau <[email protected]>
help
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2988,10 +2988,20 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev,
dev_queue_xmit_nit(skb, dev);
}
@@ -2982,10 +2982,20 @@ static int xmit_one(struct sk_buff *skb,
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
dev_queue_xmit_nit(skb, dev);

- len = skb->len;
- trace_net_dev_start_xmit(skb, dev);
Expand Down Expand Up @@ -136,7 +136,7 @@ Signed-off-by: Felix Fietkau <[email protected]>

#include <net/protocol.h>
#include <net/dst.h>
@@ -499,6 +500,22 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len,
@@ -499,6 +500,22 @@ skb_fail:
}
EXPORT_SYMBOL(__napi_alloc_skb);

Expand All @@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau <[email protected]>
{
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
@@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *sk
const struct ethhdr *eth;

skb->dev = dev;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Signed-off-by: Hauke Mehrtens <[email protected]>

--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_device *core)
@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_devic
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
Expand Down
Loading

0 comments on commit 6eab209

Please sign in to comment.