bpf: Fail verification for sign-extension of packet data/data_end/data_meta
- Published
- Last modified
- Where the record stands: published, rejected by its publisher, or superseded by another id.What do these mean? →
- published
- Whether CISA lists it in its Known Exploited Vulnerabilities catalog: proof that attackers are using it.What do these mean? →
- Not listed in CISA KEV
- Fix
- Fixed in 6.6.158, 6.10.13, 6.11.2
- Whether working attack code is public (Exploit-DB, Metasploit, Nuclei or GitHub). Public code makes attacks easier.What do these mean? →
- None on Exploit-DB, Metasploit or GitHub
- Exploitation: none
- Automatable: no
- Technical impact: partial
Summary
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/
Timeline
- CVE published
- CISA SSVC assessment
Exploitation: none · Automatable: no · Technical impact: partial
- Record last updated
Affected versions
- Linux Linux
From 1f1e864b65554e33fe74e3377e58b12f4302f2eb · fixed in 4b48228eebce2ab1b01e3133da822164472b7e46; From 1f1e864b65554e33fe74e3377e58b12f4302f2eb · fixed in f1620c93a1ec950d87ef327a565d3907736d3340; From 1f1e864b65554e33fe74e3377e58b12f4302f2eb · fixed in f09757fe97a225ae505886eac572e4cbfba96537; From 1f1e864b65554e33fe74e3377e58b12f4302f2eb · fixed in 92de36080c93296ef9005690705cba260b9bd68a
- Linux Linux
6.6
- KernelLinux
From 6.6.0 · fixed in 6.6.158; From 6.7.0 · fixed in 6.10.13; From 6.11.0 · fixed in 6.11.2