]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Apr 2023 16:22:59 +0000 (18:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Apr 2023 16:22:59 +0000 (18:22 +0200)
added patches:
maple_tree-fix-a-potential-memory-leak-oob-access-or-other-unpredictable-bug.patch
maple_tree-fix-mas_empty_area-search.patch
maple_tree-make-maple-state-reusable-after-mas_empty_area_rev.patch

queue-6.1/maple_tree-fix-a-potential-memory-leak-oob-access-or-other-unpredictable-bug.patch [new file with mode: 0644]
queue-6.1/maple_tree-fix-mas_empty_area-search.patch [new file with mode: 0644]
queue-6.1/maple_tree-make-maple-state-reusable-after-mas_empty_area_rev.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/maple_tree-fix-a-potential-memory-leak-oob-access-or-other-unpredictable-bug.patch b/queue-6.1/maple_tree-fix-a-potential-memory-leak-oob-access-or-other-unpredictable-bug.patch
new file mode 100644 (file)
index 0000000..c8d62e3
--- /dev/null
@@ -0,0 +1,67 @@
+From 1f5f12ece722aacea1769fb644f27790ede339dc Mon Sep 17 00:00:00 2001
+From: Peng Zhang <zhangpeng.00@bytedance.com>
+Date: Tue, 11 Apr 2023 12:10:04 +0800
+Subject: maple_tree: fix a potential memory leak, OOB access, or other unpredictable bug
+
+From: Peng Zhang <zhangpeng.00@bytedance.com>
+
+commit 1f5f12ece722aacea1769fb644f27790ede339dc upstream.
+
+In mas_alloc_nodes(), "node->node_count = 0" means to initialize the
+node_count field of the new node, but the node may not be a new node.  It
+may be a node that existed before and node_count has a value, setting it
+to 0 will cause a memory leak.  At this time, mas->alloc->total will be
+greater than the actual number of nodes in the linked list, which may
+cause many other errors.  For example, out-of-bounds access in
+mas_pop_node(), and mas_pop_node() may return addresses that should not be
+used.  Fix it by initializing node_count only for new nodes.
+
+Also, by the way, an if-else statement was removed to simplify the code.
+
+Link: https://lkml.kernel.org/r/20230411041005.26205-1-zhangpeng.00@bytedance.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Peng Zhang <zhangpeng.00@bytedance.com>
+Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c |   19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -1293,26 +1293,21 @@ static inline void mas_alloc_nodes(struc
+       node = mas->alloc;
+       node->request_count = 0;
+       while (requested) {
+-              max_req = MAPLE_ALLOC_SLOTS;
+-              if (node->node_count) {
+-                      unsigned int offset = node->node_count;
+-
+-                      slots = (void **)&node->slot[offset];
+-                      max_req -= offset;
+-              } else {
+-                      slots = (void **)&node->slot;
+-              }
+-
++              max_req = MAPLE_ALLOC_SLOTS - node->node_count;
++              slots = (void **)&node->slot[node->node_count];
+               max_req = min(requested, max_req);
+               count = mt_alloc_bulk(gfp, max_req, slots);
+               if (!count)
+                       goto nomem_bulk;
++              if (node->node_count == 0) {
++                      node->slot[0]->node_count = 0;
++                      node->slot[0]->request_count = 0;
++              }
++
+               node->node_count += count;
+               allocated += count;
+               node = node->slot[0];
+-              node->node_count = 0;
+-              node->request_count = 0;
+               requested -= count;
+       }
+       mas->alloc->total = allocated;
diff --git a/queue-6.1/maple_tree-fix-mas_empty_area-search.patch b/queue-6.1/maple_tree-fix-mas_empty_area-search.patch
new file mode 100644 (file)
index 0000000..ea04b89
--- /dev/null
@@ -0,0 +1,65 @@
+From 06e8fd999334bcd76b4d72d7b9206d4aea89764e Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Fri, 14 Apr 2023 10:57:27 -0400
+Subject: maple_tree: fix mas_empty_area() search
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit 06e8fd999334bcd76b4d72d7b9206d4aea89764e upstream.
+
+The internal function of mas_awalk() was incorrectly skipping the last
+entry in a node, which could potentially be NULL.  This is only a problem
+for the left-most node in the tree - otherwise that NULL would not exist.
+
+Fix mas_awalk() by using the metadata to obtain the end of the node for
+the loop and the logical pivot as apposed to the raw pivot value.
+
+Link: https://lkml.kernel.org/r/20230414145728.4067069-2-Liam.Howlett@oracle.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reported-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c |   20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -5059,10 +5059,10 @@ static inline bool mas_anode_descend(str
+ {
+       enum maple_type type = mte_node_type(mas->node);
+       unsigned long pivot, min, gap = 0;
+-      unsigned char offset;
+-      unsigned long *gaps;
+-      unsigned long *pivots = ma_pivots(mas_mn(mas), type);
+-      void __rcu **slots = ma_slots(mas_mn(mas), type);
++      unsigned char offset, data_end;
++      unsigned long *gaps, *pivots;
++      void __rcu **slots;
++      struct maple_node *node;
+       bool found = false;
+       if (ma_is_dense(type)) {
+@@ -5070,13 +5070,15 @@ static inline bool mas_anode_descend(str
+               return true;
+       }
+-      gaps = ma_gaps(mte_to_node(mas->node), type);
++      node = mas_mn(mas);
++      pivots = ma_pivots(node, type);
++      slots = ma_slots(node, type);
++      gaps = ma_gaps(node, type);
+       offset = mas->offset;
+       min = mas_safe_min(mas, pivots, offset);
+-      for (; offset < mt_slots[type]; offset++) {
+-              pivot = mas_safe_pivot(mas, pivots, offset, type);
+-              if (offset && !pivot)
+-                      break;
++      data_end = ma_data_end(node, type, pivots, mas->max);
++      for (; offset <= data_end; offset++) {
++              pivot = mas_logical_pivot(mas, pivots, offset, type);
+               /* Not within lower bounds */
+               if (mas->index > pivot)
diff --git a/queue-6.1/maple_tree-make-maple-state-reusable-after-mas_empty_area_rev.patch b/queue-6.1/maple_tree-make-maple-state-reusable-after-mas_empty_area_rev.patch
new file mode 100644 (file)
index 0000000..7194714
--- /dev/null
@@ -0,0 +1,99 @@
+From fad8e4291da5e3243e086622df63cb952db444d8 Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Fri, 14 Apr 2023 10:57:26 -0400
+Subject: maple_tree: make maple state reusable after mas_empty_area_rev()
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit fad8e4291da5e3243e086622df63cb952db444d8 upstream.
+
+Stop using maple state min/max for the range by passing through pointers
+for those values.  This will allow the maple state to be reused without
+resetting.
+
+Also add some logic to fail out early on searching with invalid
+arguments.
+
+Link: https://lkml.kernel.org/r/20230414145728.4067069-1-Liam.Howlett@oracle.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reported-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c |   27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -4968,7 +4968,8 @@ not_found:
+  * Return: True if found in a leaf, false otherwise.
+  *
+  */
+-static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
++static bool mas_rev_awalk(struct ma_state *mas, unsigned long size,
++              unsigned long *gap_min, unsigned long *gap_max)
+ {
+       enum maple_type type = mte_node_type(mas->node);
+       struct maple_node *node = mas_mn(mas);
+@@ -5033,8 +5034,8 @@ static bool mas_rev_awalk(struct ma_stat
+       if (unlikely(ma_is_leaf(type))) {
+               mas->offset = offset;
+-              mas->min = min;
+-              mas->max = min + gap - 1;
++              *gap_min = min;
++              *gap_max = min + gap - 1;
+               return true;
+       }
+@@ -5310,6 +5311,9 @@ int mas_empty_area(struct ma_state *mas,
+       unsigned long *pivots;
+       enum maple_type mt;
++      if (min >= max)
++              return -EINVAL;
++
+       if (mas_is_start(mas))
+               mas_start(mas);
+       else if (mas->offset >= 2)
+@@ -5364,6 +5368,9 @@ int mas_empty_area_rev(struct ma_state *
+ {
+       struct maple_enode *last = mas->node;
++      if (min >= max)
++              return -EINVAL;
++
+       if (mas_is_start(mas)) {
+               mas_start(mas);
+               mas->offset = mas_data_end(mas);
+@@ -5383,7 +5390,7 @@ int mas_empty_area_rev(struct ma_state *
+       mas->index = min;
+       mas->last = max;
+-      while (!mas_rev_awalk(mas, size)) {
++      while (!mas_rev_awalk(mas, size, &min, &max)) {
+               if (last == mas->node) {
+                       if (!mas_rewind_node(mas))
+                               return -EBUSY;
+@@ -5398,17 +5405,9 @@ int mas_empty_area_rev(struct ma_state *
+       if (unlikely(mas->offset == MAPLE_NODE_SLOTS))
+               return -EBUSY;
+-      /*
+-       * mas_rev_awalk() has set mas->min and mas->max to the gap values.  If
+-       * the maximum is outside the window we are searching, then use the last
+-       * location in the search.
+-       * mas->max and mas->min is the range of the gap.
+-       * mas->index and mas->last are currently set to the search range.
+-       */
+-
+       /* Trim the upper limit to the max. */
+-      if (mas->max <= mas->last)
+-              mas->last = mas->max;
++      if (max <= mas->last)
++              mas->last = max;
+       mas->index = mas->last - size + 1;
+       return 0;
index c05e8bb598afe449a25db67a8be2d15b746e0eb2..406d86c75cf59ad6d689edb24e366c1ff5af0664 100644 (file)
@@ -55,3 +55,6 @@ btrfs-get-the-next-extent-map-during-fiemap-lseek-more-efficiently.patch
 rust-kernel-mark-rust_fmt_argument-as-extern-c.patch
 loongarch-fix-probing-of-the-crc32-feature.patch
 loongarch-mark-3-symbol-exports-as-non-gpl.patch
+maple_tree-make-maple-state-reusable-after-mas_empty_area_rev.patch
+maple_tree-fix-mas_empty_area-search.patch
+maple_tree-fix-a-potential-memory-leak-oob-access-or-other-unpredictable-bug.patch