2018-11-23 17:22:09 UTC
we were notified on the Linux distros list of a vulnerability in the bpf
subsystem of the Linux kernel.
I asked the reported (Wei Wu) if ***@k.o had been notified, and
this was done in the following mail, leading Eric Dumazet to suggest
posting this on netdev.
In turn, this has been done just afterwards  so the issue is now
public. According to the linux-distros list policy, the original
reporter should also have made the issue public here, but failed to do
I'm posting this right now in order to raise awareness for the
distributions already including 4.19 in a supported release.
As the original mail indicates, an exploit code had been provided by the
reporter, but I intend to wait until a 4.19 kernel including the patch
is released (but not after next Thursday) to publish it as a followup.
----- Forwarded message from Wei Wu <***@gmail.com> -----
Date: Thu, 22 Nov 2018 21:45:11 +0800
From: Wei Wu <***@gmail.com>
Subject: [vs-plain] Kernel heap overflow in bpf leading to LPE (exploit provided)
X-Mailer: MIME-tools 5.501 (Entity 5.501)
I am writing to report a heap overflow vulnerability in kernel bpf module
There is an integer-overflow-to-buffer-overflow vulnerability in the
bpf functions introduced in 4.19 and affect up to 4.20-rc3, attached
is an LPE exploit which is able to spawn a root shell.
I will first introduce the root cause vulnerability and then discuss
how to fix this vulnerability.
In the following code shows a integer overflow when calculating size =
attr->max_entries + 1;
size is used to calculate queue_size in line 72, and queue size is
used to malloc,
if attr->max_entries is 0xffffffff, then size will be zero, which
result in a smaller buffer allocated.
static struct bpf_map *queue_stack_map_alloc(union bpf_attr *attr)
64 int ret, numa_node = bpf_map_attr_numa_node(attr);
65 struct bpf_queue_stack *qs;
66 u32 size, value_size;
67 u64 queue_size, cost;
69 size = attr->max_entries + 1;
70 value_size = attr->value_size;
72 queue_size = sizeof(*qs) + (u64) value_size * size;
74 cost = queue_size;
75 if (cost >= U32_MAX - PAGE_SIZE)
76 return ERR_PTR(-E2BIG);
78 cost = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT;
80 ret = bpf_map_precharge_memlock(cost);
81 if (ret < 0)
82 return ERR_PTR(ret);
84 qs = bpf_map_area_alloc(queue_size, numa_node);
later in function queue_stack_map_push_elem we can overflow this
buffer with arbitrary length with user-controllable content.
229 dst = &qs->elements[qs->head * qs->map.value_size];
230 memcpy(dst, value, qs->map.value_size);
running the exploit gives me a root shell in a custom compiled 4.20-rc3 system:
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:kernel_t:s0
# uname -a
Linux syzkaller 4.20.0-rc3 #1 SMP Thu Nov 22 15:12:38 CST 2018 x86_64 GNU/Linux
To fix this vulnerability, we should add check prevent the integer overflow.
Luckily it does not affect any distributions now, hope it get fixed soon : )
Wei Wu (ww9210)
University of Chinese Academy of Sciences
----- End forwarded message -----