Blame SOURCES/CVE-2022-25636.patch

ec4dc6
From e34e7e4a82e772c705bacee9ef5b63fec54e729c Mon Sep 17 00:00:00 2001
ec4dc6
From: Yannick Cote <ycote@redhat.com>
ec4dc6
Date: Tue, 29 Mar 2022 13:21:16 -0400
ec4dc6
Subject: [KPATCH CVE-2022-25636] netfilter: kpatch fixes for CVE-2022-25636
ec4dc6
ec4dc6
Kernels:
ec4dc6
4.18.0-348.el8
ec4dc6
4.18.0-348.2.1.el8_5
ec4dc6
4.18.0-348.7.1.el8_5
ec4dc6
4.18.0-348.12.2.el8_5
ec4dc6
4.18.0-348.20.1.el8_5
ec4dc6
ec4dc6
ec4dc6
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/45
ec4dc6
Approved-by: Joe Lawrence (@joe.lawrence)
ec4dc6
Changes since last build:
ec4dc6
[x86_64]:
ec4dc6
cma.o: changed function: rdma_listen
ec4dc6
nf_tables_api.o: changed function: __nf_tables_abort
ec4dc6
nf_tables_api.o: changed function: __nft_release_basechain
ec4dc6
nf_tables_api.o: changed function: nf_tables_commit
ec4dc6
nf_tables_api.o: changed function: nf_tables_exit_net
ec4dc6
nf_tables_api.o: changed function: nf_tables_newrule
ec4dc6
nf_tables_api.o: changed function: nf_tables_rule_destroy
ec4dc6
nf_tables_api.o: changed function: nft_delrule
ec4dc6
nf_tables_api.o: new function: nft_rule_expr_deactivate
ec4dc6
nf_tables_offload.o: changed function: nft_flow_rule_create
ec4dc6
ec4dc6
[ppc64le]:
ec4dc6
cma.o: changed function: rdma_listen
ec4dc6
nf_tables_api.o: changed function: __nf_tables_abort
ec4dc6
nf_tables_api.o: changed function: __nft_release_basechain
ec4dc6
nf_tables_api.o: changed function: nf_tables_commit
ec4dc6
nf_tables_api.o: changed function: nf_tables_exit_net
ec4dc6
nf_tables_api.o: changed function: nf_tables_newrule
ec4dc6
nf_tables_api.o: changed function: nf_tables_trans_destroy_work
ec4dc6
nf_tables_api.o: changed function: nft_delrule
ec4dc6
nf_tables_offload.o: changed function: nft_flow_rule_create
ec4dc6
ec4dc6
---------------------------
ec4dc6
ec4dc6
Modifications:
ec4dc6
- Simplify code to fixing the vulnerability root cause.
ec4dc6
- For this, replace (netfilter: nf_tables_offload: incorrect flow
ec4dc6
offload action array size) with localized code to make sure that
ec4dc6
'forward' and 'dup' rules (all types really) act as having the
ec4dc6
NFT_OFFLOAD_F_ACTION flag set.
ec4dc6
ec4dc6
commit 9a8d76cbd3d4321f2207bc89fdf0029fe2de3705
ec4dc6
Author: Florian Westphal <fwestpha@redhat.com>
ec4dc6
Date:   Tue Feb 22 00:40:19 2022 +0100
ec4dc6
ec4dc6
    netfilter: nftables_offload: KASAN slab-out-of-bounds Read in nft_flow_rule_create
ec4dc6
ec4dc6
    Bugzilla: https://bugzilla.redhat.com/2056866
ec4dc6
    Y-Commit: c8c8daf989226dca2bab98b8c408a4967e24926d
ec4dc6
ec4dc6
    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2056728
ec4dc6
    Upstream Status: commit 31cc578ae2de
ec4dc6
ec4dc6
    commit 31cc578ae2de19c748af06d859019dced68e325d
ec4dc6
    Author: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com>
ec4dc6
    Date:   Tue Oct 20 13:41:36 2020 +0200
ec4dc6
ec4dc6
        netfilter: nftables_offload: KASAN slab-out-of-bounds Read in nft_flow_rule_create
ec4dc6
ec4dc6
        This patch fixes the issue due to:
ec4dc6
ec4dc6
        BUG: KASAN: slab-out-of-bounds in nft_flow_rule_create+0x622/0x6a2
ec4dc6
        net/netfilter/nf_tables_offload.c:40
ec4dc6
        Read of size 8 at addr ffff888103910b58 by task syz-executor227/16244
ec4dc6
ec4dc6
        The error happens when expr->ops is accessed early on before performing the boundary check and after nft_expr_next() moves the expr to go out-of-bounds.
ec4dc6
ec4dc6
        This patch checks the boundary condition before expr->ops that fixes the slab-out-of-bounds Read issue.
ec4dc6
ec4dc6
        Add nft_expr_more() and use it to fix this problem.
ec4dc6
ec4dc6
        Signed-off-by: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com>
ec4dc6
        Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
ec4dc6
ec4dc6
    Signed-off-by: Florian Westphal <fwestpha@redhat.com>
ec4dc6
    Signed-off-by: Patrick Talbert <ptalbert@redhat.com>
ec4dc6
ec4dc6
commit bd5cf01bee78b2d9c5356021d7f9bfed8d0cbe27
ec4dc6
Author: Florian Westphal <fwestpha@redhat.com>
ec4dc6
Date:   Tue Feb 22 00:40:20 2022 +0100
ec4dc6
ec4dc6
    netfilter: nf_tables_offload: incorrect flow offload action array size
ec4dc6
ec4dc6
    Bugzilla: https://bugzilla.redhat.com/2056866
ec4dc6
    CVE: CVE-2022-25636
ec4dc6
    Y-Commit: fa41e65b922a9f624d51fdd9f698c096e340a6b7
ec4dc6
ec4dc6
    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2056728
ec4dc6
    O-CVE: CVE-2022-25636
ec4dc6
    Upstream Status: nf.git commit b1a5983f56e3
ec4dc6
ec4dc6
    Conflicts:
ec4dc6
            include/net/netfilter/nf_tables.h
ec4dc6
ec4dc6
    Context only, RHEL8 lacks the offload_stats callback.
ec4dc6
ec4dc6
    commit b1a5983f56e371046dcf164f90bfaf704d2b89f6
ec4dc6
    Author: Pablo Neira Ayuso <pablo@netfilter.org>
ec4dc6
    Date:   Thu Feb 17 23:41:20 2022 +0100
ec4dc6
ec4dc6
        netfilter: nf_tables_offload: incorrect flow offload action array size
ec4dc6
ec4dc6
        immediate verdict expression needs to allocate one slot in the flow offload
ec4dc6
        action array, however, immediate data expression does not need to do so.
ec4dc6
ec4dc6
        fwd and dup expression need to allocate one slot, this is missing.
ec4dc6
ec4dc6
        Add a new offload_action interface to report if this expression needs to
ec4dc6
        allocate one slot in the flow offload action array.
ec4dc6
ec4dc6
        Fixes: be2861dc36d7 ("netfilter: nft_{fwd,dup}_netdev: add offload support")
ec4dc6
        Reported-and-tested-by: Nick Gregory <Nick.Gregory@Sophos.com>
ec4dc6
        Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
ec4dc6
ec4dc6
    Signed-off-by: Florian Westphal <fwestpha@redhat.com>
ec4dc6
    Signed-off-by: Patrick Talbert <ptalbert@redhat.com>
ec4dc6
ec4dc6
Signed-off-by: Yannick Cote <ycote@redhat.com>
ec4dc6
---
ec4dc6
 include/net/netfilter/nf_tables.h | 6 ++++++
ec4dc6
 net/netfilter/nf_tables_api.c     | 6 +++---
ec4dc6
 net/netfilter/nf_tables_offload.c | 6 +++---
ec4dc6
 3 files changed, 12 insertions(+), 6 deletions(-)
ec4dc6
ec4dc6
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
ec4dc6
index aa5b025771b4..2f6d9959d695 100644
ec4dc6
--- a/include/net/netfilter/nf_tables.h
ec4dc6
+++ b/include/net/netfilter/nf_tables.h
ec4dc6
@@ -896,6 +896,12 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
ec4dc6
 	return (struct nft_expr *)&rule->data[rule->dlen];
ec4dc6
 }
ec4dc6
 
ec4dc6
+static inline bool nft_expr_more(const struct nft_rule *rule,
ec4dc6
+				 const struct nft_expr *expr)
ec4dc6
+{
ec4dc6
+	return expr != nft_expr_last(rule) && expr->ops;
ec4dc6
+}
ec4dc6
+
ec4dc6
 static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
ec4dc6
 {
ec4dc6
 	return (void *)&rule->data[rule->dlen];
ec4dc6
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
ec4dc6
index 353201d81205..9620daa81a15 100644
ec4dc6
--- a/net/netfilter/nf_tables_api.c
ec4dc6
+++ b/net/netfilter/nf_tables_api.c
ec4dc6
@@ -335,7 +335,7 @@ static void nft_rule_expr_activate(const struct nft_ctx *ctx,
ec4dc6
 	struct nft_expr *expr;
ec4dc6
 
ec4dc6
 	expr = nft_expr_first(rule);
ec4dc6
-	while (expr != nft_expr_last(rule) && expr->ops) {
ec4dc6
+	while (nft_expr_more(rule, expr)) {
ec4dc6
 		if (expr->ops->activate)
ec4dc6
 			expr->ops->activate(ctx, expr);
ec4dc6
 
ec4dc6
@@ -350,7 +350,7 @@ static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
ec4dc6
 	struct nft_expr *expr;
ec4dc6
 
ec4dc6
 	expr = nft_expr_first(rule);
ec4dc6
-	while (expr != nft_expr_last(rule) && expr->ops) {
ec4dc6
+	while (nft_expr_more(rule, expr)) {
ec4dc6
 		if (expr->ops->deactivate)
ec4dc6
 			expr->ops->deactivate(ctx, expr, phase);
ec4dc6
 
ec4dc6
@@ -2951,7 +2951,7 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
ec4dc6
 	 * is called on error from nf_tables_newrule().
ec4dc6
 	 */
ec4dc6
 	expr = nft_expr_first(rule);
ec4dc6
-	while (expr != nft_expr_last(rule) && expr->ops) {
ec4dc6
+	while (nft_expr_more(rule, expr)) {
ec4dc6
 		next = nft_expr_next(expr);
ec4dc6
 		nf_tables_expr_destroy(ctx, expr);
ec4dc6
 		expr = next;
ec4dc6
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
ec4dc6
index 499e5c51da22..091640fcc2f6 100644
ec4dc6
--- a/net/netfilter/nf_tables_offload.c
ec4dc6
+++ b/net/netfilter/nf_tables_offload.c
ec4dc6
@@ -93,8 +93,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
ec4dc6
 	struct nft_expr *expr;
ec4dc6
 
ec4dc6
 	expr = nft_expr_first(rule);
ec4dc6
-	while (expr->ops && expr != nft_expr_last(rule)) {
ec4dc6
-		if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
ec4dc6
+	while (nft_expr_more(rule, expr)) {
ec4dc6
+		if (expr->ops->offload)
ec4dc6
 			num_actions++;
ec4dc6
 
ec4dc6
 		expr = nft_expr_next(expr);
ec4dc6
@@ -117,7 +117,7 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
ec4dc6
 	ctx->net = net;
ec4dc6
 	ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
ec4dc6
 
ec4dc6
-	while (expr->ops && expr != nft_expr_last(rule)) {
ec4dc6
+	while (nft_expr_more(rule, expr)) {
ec4dc6
 		if (!expr->ops->offload) {
ec4dc6
 			err = -EOPNOTSUPP;
ec4dc6
 			goto err_out;
ec4dc6
-- 
ec4dc6
2.34.1
ec4dc6
ec4dc6