oss-sec mailing list archives

[CVE-2020-27171] Numeric error when restricting speculative pointer arithmetic allows unprivileged local users to leak content of kernel memory


From: Piotr Krysiuk <piotras () gmail com>
Date: Thu, 18 Mar 2021 23:47:24 +0000

Numeric error in the Linux kernel mechanism to mitigate speculatively
out-of-bounds loads (Spectre mitigation) has been identified.

Unprivileged BPF programs running on affected 64-bit systems can
exploit this to execute speculatively out-of-bounds loads from 4GB
window within the kernel memory. This can be abused to extract
contents of kernel memory via side-channel.

The identified issue is when computing ptr_limit for preventing
out-of-bounds speculation on pointer arithmetic. The computation of
ptr_limit is off-by-one whenever the pointer moves to the left.

The computed ptr_limit is zero in particular when subtracting zero
offset from a pointer that is already at the beginning of map element
value. This leads to integer underflow in fixup_bpf_calls() where
sanitization code is generated.

I developed a PoC to demonstrate how unprivileged local users can
extract contents of kernel memory.

The PoC has been shared privately with <security () kernel org> to assist
with fix development.

The patches are available from BPF subsystem public git repository. The
minimal fix is:

* bpf: Fix off-by-one for area size in creating mask to left [
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/patch/?id=10d2bb2e6b1d8c4576c56a748f697dbeb8388899
]

However it is recommended to apply the whole series as it includes
fix for another speculatively out-of-bounds vulnerability in BPF
[CVE-2020-27170] that I reported at the same time and some additional
hardening of the affected code:

* bpf: Prohibit alu ops for pointer types not defining ptr_limit [
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/patch/?id=f232326f6966cf2a1d1db7bc917a4ce5f9f55f76
]
* bpf: Fix off-by-one for area size in creating mask to left [
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/patch/?id=10d2bb2e6b1d8c4576c56a748f697dbeb8388899
]
* bpf: Simplify alu_limit masking for pointer arithmetic [
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/patch/?id=b5871dca250cd391885218b99cc015aca1a51aea
]
* bpf: Add sanity check for upper ptr_limit [
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/patch/?id=1b1597e64e1a610c7a96710fc4717158e98a08b3
]
* bpf, selftests: Fix up some test_verifier cases for unprivileged [
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/patch/?id=0a13e3537ea67452d549a6a80da3776d6b7dedb3
]

# Discoverer

Piotr Krysiuk <piotras () gmail com>

# References

CVE-2020-27171 (reserved via https://cveform.mitre.org/)

Current thread: