aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2018-11-01 17:57:55 +0100
committerHauke Mehrtens <hauke@hauke-m.de>2018-12-15 12:50:06 +0100
commit52a82ce3dd901a1536c7d7d9d963e9c2d761c816 (patch)
tree79020fb59420fcea7bdc4b12272f7251e101fe64 /target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch
parenta272af75cd8c67d265400f96c1e6bb172315c23c (diff)
downloadupstream-52a82ce3dd901a1536c7d7d9d963e9c2d761c816.tar.gz
upstream-52a82ce3dd901a1536c7d7d9d963e9c2d761c816.tar.bz2
upstream-52a82ce3dd901a1536c7d7d9d963e9c2d761c816.zip
kernel: Copy patches from kernel 4.14 to 4.19
This just copies the files from the kernel 4.14 specific folders into the kernel 4.19 specific folder, no changes are done to the files in this commit. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Diffstat (limited to 'target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch')
-rw-r--r--target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch95
1 files changed, 95 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch b/target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch
new file mode 100644
index 0000000000..331f22d19a
--- /dev/null
+++ b/target/linux/generic/backport-4.19/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch
@@ -0,0 +1,95 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 7 Feb 2018 09:23:25 +0100
+Subject: [PATCH] netfilter: nf_flow_offload: fix use-after-free and a resource
+ leak
+
+flow_offload_del frees the flow, so all associated resource must be
+freed before.
+
+Since the ct entry in struct flow_offload_entry was allocated by
+flow_offload_alloc, it should be freed by flow_offload_free to take care
+of the error handling path when flow_offload_add fails.
+
+While at it, make flow_offload_del static, since it should never be
+called directly, only from the gc step
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/include/net/netfilter/nf_flow_table.h
++++ b/include/net/netfilter/nf_flow_table.h
+@@ -90,7 +90,6 @@ struct flow_offload *flow_offload_alloc(
+ void flow_offload_free(struct flow_offload *flow);
+
+ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow);
+-void flow_offload_del(struct nf_flowtable *flow_table, struct flow_offload *flow);
+ struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table,
+ struct flow_offload_tuple *tuple);
+ int nf_flow_table_iterate(struct nf_flowtable *flow_table,
+--- a/net/netfilter/nf_flow_table.c
++++ b/net/netfilter/nf_flow_table.c
+@@ -125,7 +125,9 @@ void flow_offload_free(struct flow_offlo
+ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache);
+ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache);
+ e = container_of(flow, struct flow_offload_entry, flow);
+- kfree(e);
++ nf_ct_delete(e->ct, 0, 0);
++ nf_ct_put(e->ct);
++ kfree_rcu(e, rcu_head);
+ }
+ EXPORT_SYMBOL_GPL(flow_offload_free);
+
+@@ -149,11 +151,9 @@ int flow_offload_add(struct nf_flowtable
+ }
+ EXPORT_SYMBOL_GPL(flow_offload_add);
+
+-void flow_offload_del(struct nf_flowtable *flow_table,
+- struct flow_offload *flow)
++static void flow_offload_del(struct nf_flowtable *flow_table,
++ struct flow_offload *flow)
+ {
+- struct flow_offload_entry *e;
+-
+ rhashtable_remove_fast(&flow_table->rhashtable,
+ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node,
+ *flow_table->type->params);
+@@ -161,10 +161,8 @@ void flow_offload_del(struct nf_flowtabl
+ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node,
+ *flow_table->type->params);
+
+- e = container_of(flow, struct flow_offload_entry, flow);
+- kfree_rcu(e, rcu_head);
++ flow_offload_free(flow);
+ }
+-EXPORT_SYMBOL_GPL(flow_offload_del);
+
+ struct flow_offload_tuple_rhash *
+ flow_offload_lookup(struct nf_flowtable *flow_table,
+@@ -175,15 +173,6 @@ flow_offload_lookup(struct nf_flowtable
+ }
+ EXPORT_SYMBOL_GPL(flow_offload_lookup);
+
+-static void nf_flow_release_ct(const struct flow_offload *flow)
+-{
+- struct flow_offload_entry *e;
+-
+- e = container_of(flow, struct flow_offload_entry, flow);
+- nf_ct_delete(e->ct, 0, 0);
+- nf_ct_put(e->ct);
+-}
+-
+ int nf_flow_table_iterate(struct nf_flowtable *flow_table,
+ void (*iter)(struct flow_offload *flow, void *data),
+ void *data)
+@@ -259,10 +248,8 @@ static int nf_flow_offload_gc_step(struc
+ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]);
+
+ if (nf_flow_has_expired(flow) ||
+- nf_flow_is_dying(flow)) {
++ nf_flow_is_dying(flow))
+ flow_offload_del(flow_table, flow);
+- nf_flow_release_ct(flow);
+- }
+ }
+ out:
+ rhashtable_walk_stop(&hti);