Closed marckwei closed 4 months ago
Hi
Thanks for your question.
The goal of the pointer arithmetic strategy (and any other strategy of buzzer) is to fuzz for logic bugs in the verifier.
You are right that if R8 is not zero, then the contents of index 0 and 1 will be different at run time, this is precisely what we are looking for.
If the verifier thought that it was safe to add R8 to the map element, then the verifier also thought that R8 was 0, because this is the only value that it considers safe to add to map pointers.
If, however at runtime of the bpf program we detect that R8 was not 0, in other words that the verifier was wrong, then we can take that corrupted R8 register and turn it into an LPE exploit, this is more or less what happened with CVE-2023-2163 (https://github.com/google/security-research/tree/master/pocs/linux/cve-2023-2163)
That being said. I recently discovered that this strategy is not as efficient as I thought because the verifier does some instruction patching that effectively mitigate these kind of attacks (https://elixir.bootlin.com/linux/v6.9.5/source/kernel/bpf/verifier.c#L19747)
Hi,
I have been reviewing the
PointerArithmetic
strategy in thebuzzer
project and I have some questions regarding the logic used to determine if a boundary write has occurred. Specifically, I am confused about the comparison of the contents at key 0 and key 1 in the map to determine if a boundary write has occurred.Code in Question:
Issue:
The strategy compares the contents at key 0 and key 1 in the map to determine if a boundary write has occurred:
However, if
R8
is not zero, the pointer arithmetic will cause the value to be written to an offset location, which means the contents at key 0 and key 1 will inherently be different. This makes the comparison unreliable for detecting boundary writes.Questions:
R8
?I appreciate any clarification or guidance you can provide on this matter.
Thank you!