summaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
authorSalvatore Bonaccorso <carnil@debian.org>2022-02-25 16:54:12 +0100
committerSalvatore Bonaccorso <carnil@debian.org>2022-02-25 16:54:54 +0100
commit337bfe4dfc8b8037efaeee60ffbf720ddd45d04a (patch)
tree00be785a7c50cc0afdd45a5fb76f9516e0759805 /debian/patches
parent76d8443195a840bb0277d0b7c84edaa70cadc8b0 (diff)
downloadlinux-debian-337bfe4dfc8b8037efaeee60ffbf720ddd45d04a.tar.gz
netfilter: nf_tables_offload: incorrect flow offload action array size (CVE-2022-25636)
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/bugfix/all/netfilter-nf_tables_offload-incorrect-flow-offload-a.patch150
-rw-r--r--debian/patches/series1
2 files changed, 151 insertions, 0 deletions
diff --git a/debian/patches/bugfix/all/netfilter-nf_tables_offload-incorrect-flow-offload-a.patch b/debian/patches/bugfix/all/netfilter-nf_tables_offload-incorrect-flow-offload-a.patch
new file mode 100644
index 000000000..27353d1d8
--- /dev/null
+++ b/debian/patches/bugfix/all/netfilter-nf_tables_offload-incorrect-flow-offload-a.patch
@@ -0,0 +1,150 @@
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Thu, 17 Feb 2022 23:41:20 +0100
+Subject: netfilter: nf_tables_offload: incorrect flow offload action array
+ size
+Origin: https://git.kernel.org/linus/b1a5983f56e371046dcf164f90bfaf704d2b89f6
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-25636
+
+immediate verdict expression needs to allocate one slot in the flow offload
+action array, however, immediate data expression does not need to do so.
+
+fwd and dup expression need to allocate one slot, this is missing.
+
+Add a new offload_action interface to report if this expression needs to
+allocate one slot in the flow offload action array.
+
+Fixes: be2861dc36d7 ("netfilter: nft_{fwd,dup}_netdev: add offload support")
+Reported-and-tested-by: Nick Gregory <Nick.Gregory@Sophos.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/net/netfilter/nf_tables.h | 2 +-
+ include/net/netfilter/nf_tables_offload.h | 2 --
+ net/netfilter/nf_tables_offload.c | 3 ++-
+ net/netfilter/nft_dup_netdev.c | 6 ++++++
+ net/netfilter/nft_fwd_netdev.c | 6 ++++++
+ net/netfilter/nft_immediate.c | 12 +++++++++++-
+ 6 files changed, 26 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index eaf55da9a205..c4c0861deac1 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -905,9 +905,9 @@ struct nft_expr_ops {
+ int (*offload)(struct nft_offload_ctx *ctx,
+ struct nft_flow_rule *flow,
+ const struct nft_expr *expr);
++ bool (*offload_action)(const struct nft_expr *expr);
+ void (*offload_stats)(struct nft_expr *expr,
+ const struct flow_stats *stats);
+- u32 offload_flags;
+ const struct nft_expr_type *type;
+ void *data;
+ };
+diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
+index f9d95ff82df8..797147843958 100644
+--- a/include/net/netfilter/nf_tables_offload.h
++++ b/include/net/netfilter/nf_tables_offload.h
+@@ -67,8 +67,6 @@ struct nft_flow_rule {
+ struct flow_rule *rule;
+ };
+
+-#define NFT_OFFLOAD_F_ACTION (1 << 0)
+-
+ void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow,
+ enum flow_dissector_key_id addr_type);
+
+diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
+index 9656c1646222..2d36952b1392 100644
+--- a/net/netfilter/nf_tables_offload.c
++++ b/net/netfilter/nf_tables_offload.c
+@@ -94,7 +94,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
+
+ expr = nft_expr_first(rule);
+ while (nft_expr_more(rule, expr)) {
+- if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
++ if (expr->ops->offload_action &&
++ expr->ops->offload_action(expr))
+ num_actions++;
+
+ expr = nft_expr_next(expr);
+diff --git a/net/netfilter/nft_dup_netdev.c b/net/netfilter/nft_dup_netdev.c
+index bbf3fcba3df4..5b5c607fbf83 100644
+--- a/net/netfilter/nft_dup_netdev.c
++++ b/net/netfilter/nft_dup_netdev.c
+@@ -67,6 +67,11 @@ static int nft_dup_netdev_offload(struct nft_offload_ctx *ctx,
+ return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_MIRRED, oif);
+ }
+
++static bool nft_dup_netdev_offload_action(const struct nft_expr *expr)
++{
++ return true;
++}
++
+ static struct nft_expr_type nft_dup_netdev_type;
+ static const struct nft_expr_ops nft_dup_netdev_ops = {
+ .type = &nft_dup_netdev_type,
+@@ -75,6 +80,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = {
+ .init = nft_dup_netdev_init,
+ .dump = nft_dup_netdev_dump,
+ .offload = nft_dup_netdev_offload,
++ .offload_action = nft_dup_netdev_offload_action,
+ };
+
+ static struct nft_expr_type nft_dup_netdev_type __read_mostly = {
+diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
+index fa9301ca6033..619e394a91de 100644
+--- a/net/netfilter/nft_fwd_netdev.c
++++ b/net/netfilter/nft_fwd_netdev.c
+@@ -79,6 +79,11 @@ static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx,
+ return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_REDIRECT, oif);
+ }
+
++static bool nft_fwd_netdev_offload_action(const struct nft_expr *expr)
++{
++ return true;
++}
++
+ struct nft_fwd_neigh {
+ u8 sreg_dev;
+ u8 sreg_addr;
+@@ -222,6 +227,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = {
+ .dump = nft_fwd_netdev_dump,
+ .validate = nft_fwd_validate,
+ .offload = nft_fwd_netdev_offload,
++ .offload_action = nft_fwd_netdev_offload_action,
+ };
+
+ static const struct nft_expr_ops *
+diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
+index 90c64d27ae53..d0f67d325bdf 100644
+--- a/net/netfilter/nft_immediate.c
++++ b/net/netfilter/nft_immediate.c
+@@ -213,6 +213,16 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx,
+ return 0;
+ }
+
++static bool nft_immediate_offload_action(const struct nft_expr *expr)
++{
++ const struct nft_immediate_expr *priv = nft_expr_priv(expr);
++
++ if (priv->dreg == NFT_REG_VERDICT)
++ return true;
++
++ return false;
++}
++
+ static const struct nft_expr_ops nft_imm_ops = {
+ .type = &nft_imm_type,
+ .size = NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)),
+@@ -224,7 +234,7 @@ static const struct nft_expr_ops nft_imm_ops = {
+ .dump = nft_immediate_dump,
+ .validate = nft_immediate_validate,
+ .offload = nft_immediate_offload,
+- .offload_flags = NFT_OFFLOAD_F_ACTION,
++ .offload_action = nft_immediate_offload_action,
+ };
+
+ struct nft_expr_type nft_imm_type __read_mostly = {
+--
+2.35.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 78c49ce52..30436b853 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -103,6 +103,7 @@ features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signatu
# Security fixes
debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
debian/ntfs-mark-it-as-broken.patch
+bugfix/all/netfilter-nf_tables_offload-incorrect-flow-offload-a.patch
# Fix exported symbol versions
bugfix/all/module-disable-matching-missing-version-crc.patch