lib/maple_tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
From: Josh Law <objecting@objecting.org>
The call to mas_safe_pivot() in mas_wr_extend_null() has the pivot index
and maple type arguments swapped. The function signature expects
(mas, pivots, piv, type) but the call passes (mas, pivots, type, piv).
This causes the pivot index to be interpreted as a maple node type and
vice versa, leading to incorrect pivot lookups. In practice, this means
a null-extending store into a maple tree node can read the wrong pivot
value, potentially corrupting the range tracked by the maple state. For
a VMA maple tree, this could cause an incorrect vm_area_struct range to
be returned during operations like mmap or munmap, leading to silent
memory mapping corruption.
Every other mas_safe_pivot() call site in the file passes the arguments
in the correct (piv, type) order; this is the only one with them
reversed.
Signed-off-by: Josh Law <objecting@objecting.org>
---
lib/maple_tree.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index 5aa4c9500018..f82000821293 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -3279,7 +3279,7 @@ static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas,
(r_mas->last < r_mas->max) &&
!mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
- r_wr_mas->type, r_mas->offset + 1);
+ r_mas->offset + 1, r_wr_mas->type);
r_mas->offset++;
}
}
--
2.43.0
On Fri, 6 Mar 2026 20:08:20 +0000 Josh Law <hlcj1234567@gmail.com> wrote:
> From: Josh Law <objecting@objecting.org>
>
> The call to mas_safe_pivot() in mas_wr_extend_null() has the pivot index
> and maple type arguments swapped. The function signature expects
> (mas, pivots, piv, type) but the call passes (mas, pivots, type, piv).
>
> This causes the pivot index to be interpreted as a maple node type and
> vice versa, leading to incorrect pivot lookups. In practice, this means
> a null-extending store into a maple tree node can read the wrong pivot
> value, potentially corrupting the range tracked by the maple state. For
> a VMA maple tree, this could cause an incorrect vm_area_struct range to
> be returned during operations like mmap or munmap, leading to silent
> memory mapping corruption.
>
> Every other mas_safe_pivot() call site in the file passes the arguments
> in the correct (piv, type) order; this is the only one with them
> reversed.
>
> ...
>
> --- a/lib/maple_tree.c
> +++ b/lib/maple_tree.c
> @@ -3279,7 +3279,7 @@ static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas,
> (r_mas->last < r_mas->max) &&
> !mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
> r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
> - r_wr_mas->type, r_mas->offset + 1);
> + r_mas->offset + 1, r_wr_mas->type);
> r_mas->offset++;
> }
Whoops. How come nobody has noticed after 4+ years?
I'll add
Fixes: 54a611b60590 ("Maple Tree: add new data structure")
and maybe cc:stable if we have a reason to do so.
6 Mar 2026 21:33:22 Andrew Morton <akpm@linux-foundation.org>:
> On Fri, 6 Mar 2026 20:08:20 +0000 Josh Law <hlcj1234567@gmail.com> wrote:
>
>> From: Josh Law <objecting@objecting.org>
>>
>> The call to mas_safe_pivot() in mas_wr_extend_null() has the pivot index
>> and maple type arguments swapped. The function signature expects
>> (mas, pivots, piv, type) but the call passes (mas, pivots, type, piv).
>>
>> This causes the pivot index to be interpreted as a maple node type and
>> vice versa, leading to incorrect pivot lookups. In practice, this means
>> a null-extending store into a maple tree node can read the wrong pivot
>> value, potentially corrupting the range tracked by the maple state. For
>> a VMA maple tree, this could cause an incorrect vm_area_struct range to
>> be returned during operations like mmap or munmap, leading to silent
>> memory mapping corruption.
>>
>> Every other mas_safe_pivot() call site in the file passes the arguments
>> in the correct (piv, type) order; this is the only one with them
>> reversed.
>>
>> ...
>>
>> --- a/lib/maple_tree.c
>> +++ b/lib/maple_tree.c
>> @@ -3279,7 +3279,7 @@ static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas,
>> (r_mas->last < r_mas->max) &&
>> !mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
>> r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
>> - r_wr_mas->type, r_mas->offset + 1);
>> + r_mas->offset + 1, r_wr_mas->type);
>> r_mas->offset++;
>> }
>
> Whoops. How come nobody has noticed after 4+ years?
>
> I'll add
>
> Fixes: 54a611b60590 ("Maple Tree: add new data structure")
>
> and maybe cc:stable if we have a reason to do so.
Hi Andrew, on thought, I'd like to add Cc: stable@vger.kernel.org to this.
Even though it's been 4 years, a swapped argument in a core data structure like Maple Tree is a silent bug that could cause rare corruption. Better to defuse it in the LTS kernels.
On Fri, 6 Mar 2026 22:11:54 +0000 Josh Law <hlcj1234567@gmail.com> wrote:
> >> --- a/lib/maple_tree.c
> >> +++ b/lib/maple_tree.c
> >> @@ -3279,7 +3279,7 @@ static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas,
> >> (r_mas->last < r_mas->max) &&
> >> !mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
> >> r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
> >> - r_wr_mas->type, r_mas->offset + 1);
> >> + r_mas->offset + 1, r_wr_mas->type);
> >> r_mas->offset++;
> >> }
> >
> > Whoops. How come nobody has noticed after 4+ years?
> >
> > I'll add
> >
> > Fixes: 54a611b60590 ("Maple Tree: add new data structure")
> >
> > and maybe cc:stable if we have a reason to do so.
>
> Hi Andrew, on thought, I'd like to add Cc: stable@vger.kernel.org to this.
> Even though it's been 4 years, a swapped argument in a core data structure like Maple Tree is a silent bug that could cause rare corruption. Better to defuse it in the LTS kernels.
Seems appropriate. But not as a hotfix, given the 3+ year thing.
I was hoping to hear some thoughts on why this has proven to be so benign.
6 Mar 2026 22:54:36 Andrew Morton <akpm@linux-foundation.org>:
> On Fri, 6 Mar 2026 22:11:54 +0000 Josh Law <hlcj1234567@gmail.com> wrote:
>
>>>> --- a/lib/maple_tree.c
>>>> +++ b/lib/maple_tree.c
>>>> @@ -3279,7 +3279,7 @@ static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas,
>>>> (r_mas->last < r_mas->max) &&
>>>> !mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
>>>> r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
>>>> - r_wr_mas->type, r_mas->offset + 1);
>>>> + r_mas->offset + 1, r_wr_mas->type);
>>>> r_mas->offset++;
>>>> }
>>>
>>> Whoops. How come nobody has noticed after 4+ years?
>>>
>>> I'll add
>>>
>>> Fixes: 54a611b60590 ("Maple Tree: add new data structure")
>>>
>>> and maybe cc:stable if we have a reason to do so.
>>
>> Hi Andrew, on thought, I'd like to add Cc: stable@vger.kernel.org to this.
>> Even though it's been 4 years, a swapped argument in a core data structure like Maple Tree is a silent bug that could cause rare corruption. Better to defuse it in the LTS kernels.
>
>> Seems appropriate. But not as a hotfix, given the 3+ year thing.
>>
>> I was hoping to hear some thoughts on why this has proven to be so benign.
I suspect it has proven benign because, in most common workloads, the maple_type enum and the offset happen to be small, overlapping integers. mas_safe_pivot likely returned a 'plausible' boundary that didn't trigger an immediate OOB access, and the tree's walking logic is resilient enough to handle a slightly miscalculated pivot during a spanning-null extension without crashing. It was a silent logic error rather than a loud memory error.
V/R
V/R
Josh law
© 2016 - 2026 Red Hat, Inc.