]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 11:34:19 +0000 (12:34 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 11:34:19 +0000 (12:34 +0100)
added patches:
netfilter-nftables_offload-kasan-slab-out-of-bounds-read-in-nft_flow_rule_create.patch

queue-5.8/netfilter-nftables_offload-kasan-slab-out-of-bounds-read-in-nft_flow_rule_create.patch [new file with mode: 0644]

diff --git a/queue-5.8/netfilter-nftables_offload-kasan-slab-out-of-bounds-read-in-nft_flow_rule_create.patch b/queue-5.8/netfilter-nftables_offload-kasan-slab-out-of-bounds-read-in-nft_flow_rule_create.patch
new file mode 100644 (file)
index 0000000..432695c
--- /dev/null
@@ -0,0 +1,95 @@
+From 31cc578ae2de19c748af06d859019dced68e325d Mon Sep 17 00:00:00 2001
+From: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com>
+Date: Tue, 20 Oct 2020 13:41:36 +0200
+Subject: netfilter: nftables_offload: KASAN slab-out-of-bounds Read in nft_flow_rule_create
+
+From: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com>
+
+commit 31cc578ae2de19c748af06d859019dced68e325d upstream.
+
+This patch fixes the issue due to:
+
+BUG: KASAN: slab-out-of-bounds in nft_flow_rule_create+0x622/0x6a2
+net/netfilter/nf_tables_offload.c:40
+Read of size 8 at addr ffff888103910b58 by task syz-executor227/16244
+
+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.
+
+This patch checks the boundary condition before expr->ops that fixes the slab-out-of-bounds Read issue.
+
+Add nft_expr_more() and use it to fix this problem.
+
+Signed-off-by: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/netfilter/nf_tables.h |    6 ++++++
+ net/netfilter/nf_tables_api.c     |    6 +++---
+ net/netfilter/nf_tables_offload.c |    4 ++--
+ 3 files changed, 11 insertions(+), 5 deletions(-)
+
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -896,6 +896,12 @@ static inline struct nft_expr *nft_expr_
+       return (struct nft_expr *)&rule->data[rule->dlen];
+ }
++static inline bool nft_expr_more(const struct nft_rule *rule,
++                               const struct nft_expr *expr)
++{
++      return expr != nft_expr_last(rule) && expr->ops;
++}
++
+ static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
+ {
+       return (void *)&rule->data[rule->dlen];
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -295,7 +295,7 @@ static void nft_rule_expr_activate(const
+       struct nft_expr *expr;
+       expr = nft_expr_first(rule);
+-      while (expr != nft_expr_last(rule) && expr->ops) {
++      while (nft_expr_more(rule, expr)) {
+               if (expr->ops->activate)
+                       expr->ops->activate(ctx, expr);
+@@ -310,7 +310,7 @@ static void nft_rule_expr_deactivate(con
+       struct nft_expr *expr;
+       expr = nft_expr_first(rule);
+-      while (expr != nft_expr_last(rule) && expr->ops) {
++      while (nft_expr_more(rule, expr)) {
+               if (expr->ops->deactivate)
+                       expr->ops->deactivate(ctx, expr, phase);
+@@ -2917,7 +2917,7 @@ static void nf_tables_rule_destroy(const
+        * is called on error from nf_tables_newrule().
+        */
+       expr = nft_expr_first(rule);
+-      while (expr != nft_expr_last(rule) && expr->ops) {
++      while (nft_expr_more(rule, expr)) {
+               next = nft_expr_next(expr);
+               nf_tables_expr_destroy(ctx, expr);
+               expr = next;
+--- a/net/netfilter/nf_tables_offload.c
++++ b/net/netfilter/nf_tables_offload.c
+@@ -37,7 +37,7 @@ struct nft_flow_rule *nft_flow_rule_crea
+       struct nft_expr *expr;
+       expr = nft_expr_first(rule);
+-      while (expr->ops && expr != nft_expr_last(rule)) {
++      while (nft_expr_more(rule, expr)) {
+               if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
+                       num_actions++;
+@@ -61,7 +61,7 @@ struct nft_flow_rule *nft_flow_rule_crea
+       ctx->net = net;
+       ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
+-      while (expr->ops && expr != nft_expr_last(rule)) {
++      while (nft_expr_more(rule, expr)) {
+               if (!expr->ops->offload) {
+                       err = -EOPNOTSUPP;
+                       goto err_out;