diff options
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | debian/patches/bugfix/all/netfilter-nf_tables_offload-incorrect-flow-offload-a.patch | 150 | ||||
-rw-r--r-- | debian/patches/series | 1 |
3 files changed, 153 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index b51de4af0..f03edf926 100644 --- a/debian/changelog +++ b/debian/changelog @@ -174,6 +174,8 @@ linux (5.16.11-1) UNRELEASED; urgency=medium * cgroup-v1: Correct privileges check in release_agent writes * netfilter: xt_socket: fix a typo in socket_mt_destroy() * netfilter: xt_socket: missing ifdef CONFIG_IP6_NF_IPTABLES dependency + * netfilter: nf_tables_offload: incorrect flow offload action array size + (CVE-2022-25636) [ Vincent Blut ] * drivers/hid: Enable HID_NINTENDO as module and NINTENDO_FF as built-in 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 |