Skip to content

Commit 29ad6bb

Browse files
zhangpeng-00akpm00
authored andcommitted
maple_tree: fix allocation in mas_sparse_area()
In the case of reverse allocation, mas->index and mas->last do not point to the correct allocation range, which will cause users to get incorrect allocation results, so fix it. If the user does not use it in a specific way, this bug will not be triggered. This is a bug, but only VMA uses it now, the way VMA is used now will not trigger it. There is a possibility that a user will trigger it in the future. Also re-check whether the size is still satisfied after the lower bound was increased, which is a corner case and is incorrect in previous versions. Link: https://lkml.kernel.org/r/20230419093625.99201-1-zhangpeng.00@bytedance.com Fixes: 54a611b ("Maple Tree: add new data structure") Signed-off-by: Peng Zhang <zhangpeng.00@bytedance.com> Cc: Liam R. Howlett <Liam.Howlett@Oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 5315644 commit 29ad6bb

1 file changed

Lines changed: 20 additions & 21 deletions

File tree

lib/maple_tree.c

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5250,25 +5250,28 @@ static inline void mas_fill_gap(struct ma_state *mas, void *entry,
52505250
* @size: The size of the gap
52515251
* @fwd: Searching forward or back
52525252
*/
5253-
static inline void mas_sparse_area(struct ma_state *mas, unsigned long min,
5253+
static inline int mas_sparse_area(struct ma_state *mas, unsigned long min,
52545254
unsigned long max, unsigned long size, bool fwd)
52555255
{
5256-
unsigned long start = 0;
5257-
5258-
if (!unlikely(mas_is_none(mas)))
5259-
start++;
5256+
if (!unlikely(mas_is_none(mas)) && min == 0) {
5257+
min++;
5258+
/*
5259+
* At this time, min is increased, we need to recheck whether
5260+
* the size is satisfied.
5261+
*/
5262+
if (min > max || max - min + 1 < size)
5263+
return -EBUSY;
5264+
}
52605265
/* mas_is_ptr */
52615266

5262-
if (start < min)
5263-
start = min;
5264-
52655267
if (fwd) {
5266-
mas->index = start;
5267-
mas->last = start + size - 1;
5268-
return;
5268+
mas->index = min;
5269+
mas->last = min + size - 1;
5270+
} else {
5271+
mas->last = max;
5272+
mas->index = max - size + 1;
52695273
}
5270-
5271-
mas->index = max;
5274+
return 0;
52725275
}
52735276

52745277
/*
@@ -5297,10 +5300,8 @@ int mas_empty_area(struct ma_state *mas, unsigned long min,
52975300
return -EBUSY;
52985301

52995302
/* Empty set */
5300-
if (mas_is_none(mas) || mas_is_ptr(mas)) {
5301-
mas_sparse_area(mas, min, max, size, true);
5302-
return 0;
5303-
}
5303+
if (mas_is_none(mas) || mas_is_ptr(mas))
5304+
return mas_sparse_area(mas, min, max, size, true);
53045305

53055306
/* The start of the window can only be within these values */
53065307
mas->index = min;
@@ -5356,10 +5357,8 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
53565357
}
53575358

53585359
/* Empty set. */
5359-
if (mas_is_none(mas) || mas_is_ptr(mas)) {
5360-
mas_sparse_area(mas, min, max, size, false);
5361-
return 0;
5362-
}
5360+
if (mas_is_none(mas) || mas_is_ptr(mas))
5361+
return mas_sparse_area(mas, min, max, size, false);
53635362

53645363
/* The start of the window can only be within these values. */
53655364
mas->index = min;

0 commit comments

Comments
 (0)