A recently discovered vulnerability (CVE-2024-26883) in the Linux kernel has been resolved. The issue pertains to the stackmap overflow check on 32-bit architectures, and is related to the use of the bpf (Berkeley Packet Filter) system. The issue was reported by syzbot and occurs in the DEVMAP_HASH type, which contains the same faulty check as the hashtab code. A previous attempt at fixing this issue was unsuccessful due to not accounting for undefined behavior. However, a new solution has been implemented, and this article will provide the details of this fix, along with the original references and exploit details.

Original References

1. Linux Kernel Mailing List for the bpf
2. syzbot report for the DEVMAP_HASH type

Exploit Details

The vulnerability was in the stackmap code, which relied on the function roundup_pow_of_two() to compute the number of hash buckets. An overflow check was present to verify if the resulting value was . However, on 32-bit architectures, the roundup code itself could overflow by doing a 32-bit left-shift of an unsigned long value - an undefined behavior. The undefined behavior means that it is not guaranteed to truncate neatly, leading to a security vulnerability.

Previous Fix

The commit in the fixes tag attempted to resolve the issue, but the fix was not effective as it did not account for the undefined behavior. Consequently, the fix only worked on CPUs where an overflow resulted in a neat truncation to zero, which is not guaranteed.

New Solution

The new fix involves checking the value before rounding, as it does not have the same problem as the previous fix. The following code snippet showcases the updated solution:

// Old code snippet (issue present):
static inline u32 roundup_pow_of_two_old(u32 n)
{
    return 1UL << (32 - __builtin_clz(n - 1));
}

u32 num_buckets = roundup_pow_of_two(num_entries);

// Issue: overflow check after rounding
if (num_buckets == )
    return -ENOMEM;

// New Code Snippet (issue fixed):
static inline u32 roundup_pow_of_two(u32 n)
{
    return 1UL << (32 - __builtin_clz(n - 1));
}

// Fix: Check value before rounding
if (num_entries > ((u32) -1) >> 1)
    return -ENOMEM;

u32 num_buckets = roundup_pow_of_two(num_entries);

By changing the check on the number of hash buckets to before the rounding process, the undefined behavior caused by overflow is avoided, and the security issue is resolved.

Conclusion

The CVE-2024-26883 vulnerability in the Linux kernel has been successfully addressed, with a new working fix for the stackmap overflow check on 32-bit architectures in place. The updated fix ensures that the undefined behavior is avoided, thereby eliminating any security issues arising from the vulnerability. Further information can be found in the provided references and the exploitation details discussed in this article.

Timeline

Published on: 04/17/2024 11:15:10 UTC
Last modified on: 06/27/2024 12:15:21 UTC