CVE-2024-47702

In the Linux kernel, the following vulnerability has been resolved: bpf: Fail verification for sign-extension of packet data/data_end/data_meta syzbot reported a kernel crash due to commit 1f1e864b6555 ("bpf: Handle sign-extenstin ctx member accesses"). The reason is due to sign-extension of 32-bit load for packet data/data_end/data_meta uapi field. The original code looks like: r2 = *(s32 *)(r1 + 76) /* load __sk_buff->data */ r3 = *(u32 *)(r1 + 80) /* load __sk_buff->data_end */ r0 = r2 r0 += 8 if r3 > r0 goto +1 ... Note that __sk_buff->data load has 32-bit sign extension. After verification and convert_ctx_accesses(), the final asm code looks like: r2 = *(u64 *)(r1 +208) r2 = (s32)r2 r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 > r0 goto pc+1 ... Note that 'r2 = (s32)r2' may make the kernel __sk_buff->data address invalid which may cause runtime failure. Currently, in C code, typically we have void *data = (void *)(long)skb->data; void *data_end = (void *)(long)skb->data_end; ... and it will generate r2 = *(u64 *)(r1 +208) r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 > r0 goto pc+1 If we allow sign-extension, void *data = (void *)(long)(int)skb->data; void *data_end = (void *)(long)skb->data_end; ... the generated code looks like r2 = *(u64 *)(r1 +208) r2 <<= 32 r2 s>>= 32 r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 > r0 goto pc+1 and this will cause verification failure since "r2 <<= 32" is not allowed as "r2" is a packet pointer. To fix this issue for case r2 = *(s32 *)(r1 + 76) /* load __sk_buff->data */ this patch added additional checking in is_valid_access() callback function for packet data/data_end/data_meta access. If those accesses are with sign-extenstion, the verification will fail. [1] https://lore.kernel.org/bpf/000000000000c90eee061d236d37@google.com/
Configurations

Configuration 1 (hide)

OR cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*

History

24 Oct 2024, 13:30

Type Values Removed Values Added
References () https://git.kernel.org/stable/c/92de36080c93296ef9005690705cba260b9bd68a - () https://git.kernel.org/stable/c/92de36080c93296ef9005690705cba260b9bd68a - Patch
References () https://git.kernel.org/stable/c/f09757fe97a225ae505886eac572e4cbfba96537 - () https://git.kernel.org/stable/c/f09757fe97a225ae505886eac572e4cbfba96537 - Patch
References () https://git.kernel.org/stable/c/f1620c93a1ec950d87ef327a565d3907736d3340 - () https://git.kernel.org/stable/c/f1620c93a1ec950d87ef327a565d3907736d3340 - Patch
CVSS v2 : unknown
v3 : unknown
v2 : unknown
v3 : 5.5
CPE cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Summary
  • (es) En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: bpf: Error en la verificación de la extensión de signo del paquete data/data_end/data_meta syzbot informó de un fallo del kernel debido a el commit 1f1e864b6555 ("bpf: Manejar los accesos a miembros ctx de la extensión de signo"). La razón se debe a la extensión de signo de la carga de 32 bits para el campo uapi del paquete data/data_end/data_meta. El código original se ve así: r2 = *(s32 *)(r1 + 76) /* load __sk_buff-&gt;data */ r3 = *(u32 *)(r1 + 80) /* load __sk_buff-&gt;data_end */ r0 = r2 r0 += 8 if r3 &gt; r0 goto +1 ... Tenga en cuenta que la carga de __sk_buff-&gt;data tiene una extensión de signo de 32 bits. Después de la verificación y convert_ctx_accesses(), el código asm final se ve así: r2 = *(u64 *)(r1 +208) r2 = (s32)r2 r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 &gt; r0 goto pc+1 ... Tenga en cuenta que 'r2 = (s32)r2' puede hacer que la dirección __sk_buff-&gt;data del núcleo sea inválida, lo que puede causar un error en tiempo de ejecución. Actualmente, en el código C, normalmente tenemos void *data = (void *)(long)skb-&gt;data; void *data_end = (void *)(long)skb-&gt;data_end; ... y generará r2 = *(u64 *)(r1 +208) r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 &gt; r0 goto pc+1 Si permitimos la extensión de signo, void *data = (void *)(long)(int)skb-&gt;data; void *data_end = (void *)(long)skb-&gt;data_end; ... el código generado se ve así r2 = *(u64 *)(r1 +208) r2 &lt;&lt;= 32 r2 s&gt;&gt;= 32 r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 &gt; r0 goto pc+1 y esto causará un error de verificación ya que "r2 &lt;&lt;= 32" no está permitido ya que "r2" es un puntero de paquete. Para solucionar este problema en el caso r2 = *(s32 *)(r1 + 76) /* load __sk_buff-&gt;data */, este parche agregó una verificación adicional en la función de devolución de llamada is_valid_access() para el acceso a los paquetes data/data_end/data_meta. Si esos accesos son con la extensión sign-extenstion, la verificación fallará. [1] https://lore.kernel.org/bpf/000000000000c90eee061d236d37@google.com/
CWE NVD-CWE-noinfo
First Time Linux linux Kernel
Linux

21 Oct 2024, 12:15

Type Values Removed Values Added
New CVE

Information

Published : 2024-10-21 12:15

Updated : 2024-10-24 13:30


NVD link : CVE-2024-47702

Mitre link : CVE-2024-47702

CVE.ORG link : CVE-2024-47702


JSON object : View

Products Affected

linux

  • linux_kernel