From: Greg Kroah-Hartman Date: Sat, 22 Apr 2023 16:22:59 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v4.14.314~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c3e7e6e4544e0d3be296472cad3864916d0d3099;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches 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 --- 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 index 00000000000..c8d62e32c03 --- /dev/null +++ b/queue-6.1/maple_tree-fix-a-potential-memory-leak-oob-access-or-other-unpredictable-bug.patch @@ -0,0 +1,67 @@ +From 1f5f12ece722aacea1769fb644f27790ede339dc Mon Sep 17 00:00:00 2001 +From: Peng Zhang +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 + +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 +Reviewed-by: Liam R. Howlett +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ea04b898bba --- /dev/null +++ b/queue-6.1/maple_tree-fix-mas_empty_area-search.patch @@ -0,0 +1,65 @@ +From 06e8fd999334bcd76b4d72d7b9206d4aea89764e Mon Sep 17 00:00:00 2001 +From: "Liam R. Howlett" +Date: Fri, 14 Apr 2023 10:57:27 -0400 +Subject: maple_tree: fix mas_empty_area() search + +From: Liam R. Howlett + +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 +Reported-by: Rick Edgecombe +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..7194714b758 --- /dev/null +++ b/queue-6.1/maple_tree-make-maple-state-reusable-after-mas_empty_area_rev.patch @@ -0,0 +1,99 @@ +From fad8e4291da5e3243e086622df63cb952db444d8 Mon Sep 17 00:00:00 2001 +From: "Liam R. Howlett" +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 + +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 +Reported-by: Rick Edgecombe +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-6.1/series b/queue-6.1/series index c05e8bb598a..406d86c75cf 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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