CVE-2022-48998 Information
Description
In the Linux kernel the following vulnerability has been resolved:
powerpc/bpf/32: Fix Oops on tail call tests
test_bpf tail call tests end up as:
test_bpf: 0 Tail call leaf jited:1 85 PASS
test_bpf: 1 Tail call 2 jited:1 111 PASS
test_bpf: 2 Tail call 3 jited:1 145 PASS
test_bpf: 3 Tail call 4 jited:1 170 PASS
test_bpf: 4 Tail call load/store leaf jited:1 190 PASS
test_bpf: 5 Tail call load/store jited:1
BUG: Unable to handle kernel data access on write at 0xf1b4e000
Faulting instruction address: 0xbe86b710
Oops: Kernel access of bad area sig: 11 [1]
BE PAGE_SIZE=4K MMU=Hash PowerMac
Modules linked in: test_bpf(+)
CPU: 0 PID: 97 Comm: insmod Not tainted 6.1.0-rc4+ 195
Hardware name: PowerMac31 750CL 0x87210 PowerMac
NIP: be86b710 LR: be857e88 CTR: be86b704
REGS: f1b4df20 TRAP: 0300 Not tainted (6.1.0-rc4+)
MSR: 00009032
This is a tentative to write above the stack. The problem is encoutered with tests added by commit 38608ee7b690 (pf tests: Add load store test case for tail call)
This happens because tail call is done to a BPF prog with a different stack_depth. At the time being the stack is kept as is when the caller tail calls its callee. But at exit the callee restores the stack based on its own properties. Therefore here at each run r1 is erroneously increased by 32 - 16 = 16 bytes.
This was done that way in order to pass the tail call count from caller to callee through the stack. As powerpc32 doesn’t have a red zone in the stack it was necessary the maintain the stack as is for the tail call. But it was not anticipated that the BPF frame size could be different.
Let’s take a new approach. Use register r4 to carry the tail call count during the tail call and save it into the stack at function entry if required. This means the input parameter must be in r3 which is more correct as it is a 32 bits parameter then tail call better match with normal BPF function entry the down side being that we move that input parameter back and forth between r3 and r4. That can be optimised later.
Doing that also has the advantage of maximising the common parts between tail calls and a normal function exit.
With the fix tail call tests are now successfull:
test_bpf: 0 Tail call leaf jited:1 53 PASS test_bpf: 1 Tail call 2 jited:1 115 PASS test_bpf: 2 Tail call 3 jited:1 154 PASS test_bpf: 3 Tail call 4 jited:1 165 PASS test_bpf: 4 Tail call load/store leaf jited:1 101 PASS test_bpf: 5 Tail call load/store jited:1 141 PASS test_bpf: 6 Tail call error path max count reached jited:1 994 PASS test_bpf: 7 Tail call count preserved across function calls jited:1 140975 PASS test_bpf: 8 Tail call error path NULL target jited:1 110 PASS test_bpf: 9 Tail call error path index out of range jited:1 69 PASS test_bpf: test_tail_calls: Summary: 10 PASSED 0 FAILED [10/10 JIT’ed]
Reference
https://git.kernel.org/stable/c/747a6e547240baaaf41874d27333b87b87cfd24c https://git.kernel.org/stable/c/89d21e259a94f7d5582ec675aa445f5a79f347e4
Share on: