summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-20177/0001-netfilter-add-and-use-nf_hook_slow_list.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-20177/0001-netfilter-add-and-use-nf_hook_slow_list.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-20177/0001-netfilter-add-and-use-nf_hook_slow_list.patch119
1 files changed, 119 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-20177/0001-netfilter-add-and-use-nf_hook_slow_list.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-20177/0001-netfilter-add-and-use-nf_hook_slow_list.patch
new file mode 100644
index 000000000..8563d5cae
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-20177/0001-netfilter-add-and-use-nf_hook_slow_list.patch
@@ -0,0 +1,119 @@
+From ca58fbe06c54795f00db79e447f94c2028d30124 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 11 Oct 2019 00:30:37 +0200
+Subject: [PATCH] netfilter: add and use nf_hook_slow_list()
+
+At this time, NF_HOOK_LIST() macro will iterate the list and then calls
+nf_hook() for each individual skb.
+
+This makes it so the entire list is passed into the netfilter core.
+The advantage is that we only need to fetch the rule blob once per list
+instead of per-skb.
+
+NF_HOOK_LIST now only works for ipv4 and ipv6, as those are the only
+callers.
+
+v2: use skb_list_del_init() instead of list_del (Edward Cree)
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Edward Cree <ecree@solarflare.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/linux/netfilter.h | 41 +++++++++++++++++++++++++++++----------
+ net/netfilter/core.c | 20 +++++++++++++++++++
+ 2 files changed, 51 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
+index 77ebb61faf48..eb312e7ca36e 100644
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -199,6 +199,8 @@ extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
+ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
+ const struct nf_hook_entries *e, unsigned int i);
+
++void nf_hook_slow_list(struct list_head *head, struct nf_hook_state *state,
++ const struct nf_hook_entries *e);
+ /**
+ * nf_hook - call a netfilter hook
+ *
+@@ -311,17 +313,36 @@ NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
+ struct list_head *head, struct net_device *in, struct net_device *out,
+ int (*okfn)(struct net *, struct sock *, struct sk_buff *))
+ {
+- struct sk_buff *skb, *next;
+- struct list_head sublist;
+-
+- INIT_LIST_HEAD(&sublist);
+- list_for_each_entry_safe(skb, next, head, list) {
+- list_del(&skb->list);
+- if (nf_hook(pf, hook, net, sk, skb, in, out, okfn) == 1)
+- list_add_tail(&skb->list, &sublist);
++ struct nf_hook_entries *hook_head = NULL;
++
++#ifdef CONFIG_JUMP_LABEL
++ if (__builtin_constant_p(pf) &&
++ __builtin_constant_p(hook) &&
++ !static_key_false(&nf_hooks_needed[pf][hook]))
++ return;
++#endif
++
++ rcu_read_lock();
++ switch (pf) {
++ case NFPROTO_IPV4:
++ hook_head = rcu_dereference(net->nf.hooks_ipv4[hook]);
++ break;
++ case NFPROTO_IPV6:
++ hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]);
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ break;
+ }
+- /* Put passed packets back on main list */
+- list_splice(&sublist, head);
++
++ if (hook_head) {
++ struct nf_hook_state state;
++
++ nf_hook_state_init(&state, hook, pf, in, out, sk, net, okfn);
++
++ nf_hook_slow_list(head, &state, hook_head);
++ }
++ rcu_read_unlock();
+ }
+
+ /* Call setsockopt() */
+diff --git a/net/netfilter/core.c b/net/netfilter/core.c
+index 5d5bdf450091..78f046ec506f 100644
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -536,6 +536,26 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
+ }
+ EXPORT_SYMBOL(nf_hook_slow);
+
++void nf_hook_slow_list(struct list_head *head, struct nf_hook_state *state,
++ const struct nf_hook_entries *e)
++{
++ struct sk_buff *skb, *next;
++ struct list_head sublist;
++ int ret;
++
++ INIT_LIST_HEAD(&sublist);
++
++ list_for_each_entry_safe(skb, next, head, list) {
++ skb_list_del_init(skb);
++ ret = nf_hook_slow(skb, state, e, 0);
++ if (ret == 1)
++ list_add_tail(&skb->list, &sublist);
++ }
++ /* Put passed packets back on main list */
++ list_splice(&sublist, head);
++}
++EXPORT_SYMBOL(nf_hook_slow_list);
++
+ /* This needs to be compiled in any case to avoid dependencies between the
+ * nfnetlink_queue code and nf_conntrack.
+ */
+--
+2.17.1
+