mbox series

[SRU,F,0/1] CVE-2024-26885

Message ID 20240906061449.734300-1-koichiro.den@canonical.com
Headers show
Series CVE-2024-26885 | expand

Message

Koichiro Den Sept. 6, 2024, 6:14 a.m. UTC
[Impact]

bpf: Fix DEVMAP_HASH overflow check on 32-bit arches

The devmap code allocates a number hash buckets equal to the next power
of two of the max_entries value provided when creating the map. When
rounding up to the next power of two, the 32-bit variable storing the
number of buckets can overflow, and the code checks for overflow by
checking if the truncated 32-bit value is equal to 0. However, on 32-bit
arches the rounding up itself can overflow mid-way through, because it
ends up doing a left-shift of 32 bits on an unsigned long value. If the
size of an unsigned long is four bytes, this is undefined behaviour, so
there is no guarantee that we'll end up with a nice and tidy 0-value at
the end.

Syzbot managed to turn this into a crash on arm32 by creating a
DEVMAP_HASH with max_entries > 0x80000000 and then trying to update it.
Fix this by moving the overflow check to before the rounding up
operation.

[Backport]

There were conflicts due to missing commits:
- commit 844f157f6c0a ("bpf: Eliminate rlimit-based memory accounting for devmap maps")
- commit 96360004b862 ("xdp: Make devmap flush_list common for all map instances")

and resolved these conflicts by adjusting contexts without merging them
to avoid unnecessary changes to the code base.

[Fix]

Noble:  not affected
Jammy:  fixed via stable
Focal:  Backport - adjusted contexts due to missing commits, see [Backport]
Bionic: not affected
Xenial: not affected
Trusty: not affected

[Test Case]

Compile and boot tested.

Also (stress) tested using the syzbot reproducer [1] on my local armhf
focal qemu instance, with and without this backport, though it did not
trigger the reported issue even without the backport, likely due to a
compiler difference from syzbot (i.e. the original overflow checking
seemed to work even without the backport). I've not investigated more
into it, but still the test confirms the robustness of this backport.

[1] https://syzkaller.appspot.com/bug?extid=8cd36f6b65f3cafd400a

[Where problems could occur]

This fix potentially affects 32-bit arches, an issue with this fix would
cause underfined behaviour when creating a DEVMAP_HASH with max_entries
greater than 0x80000000.


Toke Høiland-Jørgensen (1):
  bpf: Fix DEVMAP_HASH overflow check on 32-bit arches

 kernel/bpf/devmap.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Manuel Diewald Sept. 6, 2024, 9:50 a.m. UTC | #1
On Fri, Sep 06, 2024 at 03:14:37PM +0900, Koichiro Den wrote:
> [Impact]
> 
> bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
> 
> The devmap code allocates a number hash buckets equal to the next power
> of two of the max_entries value provided when creating the map. When
> rounding up to the next power of two, the 32-bit variable storing the
> number of buckets can overflow, and the code checks for overflow by
> checking if the truncated 32-bit value is equal to 0. However, on 32-bit
> arches the rounding up itself can overflow mid-way through, because it
> ends up doing a left-shift of 32 bits on an unsigned long value. If the
> size of an unsigned long is four bytes, this is undefined behaviour, so
> there is no guarantee that we'll end up with a nice and tidy 0-value at
> the end.
> 
> Syzbot managed to turn this into a crash on arm32 by creating a
> DEVMAP_HASH with max_entries > 0x80000000 and then trying to update it.
> Fix this by moving the overflow check to before the rounding up
> operation.
> 
> [Backport]
> 
> There were conflicts due to missing commits:
> - commit 844f157f6c0a ("bpf: Eliminate rlimit-based memory accounting for devmap maps")
> - commit 96360004b862 ("xdp: Make devmap flush_list common for all map instances")
> 
> and resolved these conflicts by adjusting contexts without merging them
> to avoid unnecessary changes to the code base.
> 
> [Fix]
> 
> Noble:  not affected
> Jammy:  fixed via stable
> Focal:  Backport - adjusted contexts due to missing commits, see [Backport]
> Bionic: not affected
> Xenial: not affected
> Trusty: not affected
> 
> [Test Case]
> 
> Compile and boot tested.
> 
> Also (stress) tested using the syzbot reproducer [1] on my local armhf
> focal qemu instance, with and without this backport, though it did not
> trigger the reported issue even without the backport, likely due to a
> compiler difference from syzbot (i.e. the original overflow checking
> seemed to work even without the backport). I've not investigated more
> into it, but still the test confirms the robustness of this backport.
> 
> [1] https://syzkaller.appspot.com/bug?extid=8cd36f6b65f3cafd400a
> 
> [Where problems could occur]
> 
> This fix potentially affects 32-bit arches, an issue with this fix would
> cause underfined behaviour when creating a DEVMAP_HASH with max_entries
> greater than 0x80000000.
> 
> 
> Toke Høiland-Jørgensen (1):
>   bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
> 
>  kernel/bpf/devmap.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> -- 
> 2.43.0
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team

Acked-by: Manuel Diewald <manuel.diewald@canonical.com>
Thibault Ferrante Sept. 6, 2024, 10:25 a.m. UTC | #2
Acked-by: Thibault Ferrante <thibault.ferrante@canonical.com>


On 06-09-2024 08:14, Koichiro Den wrote:
> [Impact]
> 
> bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
> 
> The devmap code allocates a number hash buckets equal to the next power
> of two of the max_entries value provided when creating the map. When
> rounding up to the next power of two, the 32-bit variable storing the
> number of buckets can overflow, and the code checks for overflow by
> checking if the truncated 32-bit value is equal to 0. However, on 32-bit
> arches the rounding up itself can overflow mid-way through, because it
> ends up doing a left-shift of 32 bits on an unsigned long value. If the
> size of an unsigned long is four bytes, this is undefined behaviour, so
> there is no guarantee that we'll end up with a nice and tidy 0-value at
> the end.
> 
> Syzbot managed to turn this into a crash on arm32 by creating a
> DEVMAP_HASH with max_entries > 0x80000000 and then trying to update it.
> Fix this by moving the overflow check to before the rounding up
> operation.
> 
> [Backport]
> 
> There were conflicts due to missing commits:
> - commit 844f157f6c0a ("bpf: Eliminate rlimit-based memory accounting for devmap maps")
> - commit 96360004b862 ("xdp: Make devmap flush_list common for all map instances")
> 
> and resolved these conflicts by adjusting contexts without merging them
> to avoid unnecessary changes to the code base.
> 
> [Fix]
> 
> Noble:  not affected
> Jammy:  fixed via stable
> Focal:  Backport - adjusted contexts due to missing commits, see [Backport]
> Bionic: not affected
> Xenial: not affected
> Trusty: not affected
> 
> [Test Case]
> 
> Compile and boot tested.
> 
> Also (stress) tested using the syzbot reproducer [1] on my local armhf
> focal qemu instance, with and without this backport, though it did not
> trigger the reported issue even without the backport, likely due to a
> compiler difference from syzbot (i.e. the original overflow checking
> seemed to work even without the backport). I've not investigated more
> into it, but still the test confirms the robustness of this backport.
> 
> [1] https://syzkaller.appspot.com/bug?extid=8cd36f6b65f3cafd400a
> 
> [Where problems could occur]
> 
> This fix potentially affects 32-bit arches, an issue with this fix would
> cause underfined behaviour when creating a DEVMAP_HASH with max_entries
> greater than 0x80000000.
> 
> 
> Toke Høiland-Jørgensen (1):
>    bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
> 
>   kernel/bpf/devmap.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
>
Stefan Bader Sept. 6, 2024, 2:44 p.m. UTC | #3
On 06.09.24 08:14, Koichiro Den wrote:
> [Impact]
> 
> bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
> 
> The devmap code allocates a number hash buckets equal to the next power
> of two of the max_entries value provided when creating the map. When
> rounding up to the next power of two, the 32-bit variable storing the
> number of buckets can overflow, and the code checks for overflow by
> checking if the truncated 32-bit value is equal to 0. However, on 32-bit
> arches the rounding up itself can overflow mid-way through, because it
> ends up doing a left-shift of 32 bits on an unsigned long value. If the
> size of an unsigned long is four bytes, this is undefined behaviour, so
> there is no guarantee that we'll end up with a nice and tidy 0-value at
> the end.
> 
> Syzbot managed to turn this into a crash on arm32 by creating a
> DEVMAP_HASH with max_entries > 0x80000000 and then trying to update it.
> Fix this by moving the overflow check to before the rounding up
> operation.
> 
> [Backport]
> 
> There were conflicts due to missing commits:
> - commit 844f157f6c0a ("bpf: Eliminate rlimit-based memory accounting for devmap maps")
> - commit 96360004b862 ("xdp: Make devmap flush_list common for all map instances")
> 
> and resolved these conflicts by adjusting contexts without merging them
> to avoid unnecessary changes to the code base.
> 
> [Fix]
> 
> Noble:  not affected
> Jammy:  fixed via stable
> Focal:  Backport - adjusted contexts due to missing commits, see [Backport]
> Bionic: not affected
> Xenial: not affected
> Trusty: not affected
> 
> [Test Case]
> 
> Compile and boot tested.
> 
> Also (stress) tested using the syzbot reproducer [1] on my local armhf
> focal qemu instance, with and without this backport, though it did not
> trigger the reported issue even without the backport, likely due to a
> compiler difference from syzbot (i.e. the original overflow checking
> seemed to work even without the backport). I've not investigated more
> into it, but still the test confirms the robustness of this backport.
> 
> [1] https://syzkaller.appspot.com/bug?extid=8cd36f6b65f3cafd400a
> 
> [Where problems could occur]
> 
> This fix potentially affects 32-bit arches, an issue with this fix would
> cause underfined behaviour when creating a DEVMAP_HASH with max_entries
> greater than 0x80000000.
> 
> 
> Toke Høiland-Jørgensen (1):
>    bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
> 
>   kernel/bpf/devmap.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
> 

Applied to focal:linux/master-next. Thanks.

-Stefan