[no subject]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---

I hope it was clear from my base PoC code that to ensure the filter is a "pure
function" it is enough to reproduce the memory access semantics and protections
introduced by BPF's verifier.c with additional limited scope. This at least
practically ensures something using the mechanism of CVE-2021-33909 (_on
Android in particular, generic linux is another ballpark_) cannot transform the
seccomp code page into something breaking verifier.c's semantics. Though it may
break the intended seccomp policy itself, I think that level of checking can be
added on as an additional layer once this basic exploit is resolved.

This in mind, as of last week, I've gone ahead and gotten my earlier, buggy PoC
for an EL2-level seccomp verifier (in another earlier email in this chain)
running on a real device. After I fixed some other bugs (they are pretty
obvious once you look through the PoC code), I discovered empirically a QCOM
hardware abstraction layer (HAL) service has a filter program that uses the
stack (uses a store instruction to BPF_REGS_FP), so my initial hope of
"banning" stores to memory outright *did* end up a no-go for one empirical
case. The clear solution seems to be to relax the restrictions the smallest
amount possible: check that stores in the program are in the predefined stack
memory scratch area.

Thankfully, BPF_REGS_FP is read-only. And I totally understand and support the
possibility that a filter program can load/store from its well-defined stack
space as a scratch area. Additionally, bpf_check_classic and the existence of

        BUILD_BUG_ON(BPF_MEMWORDS * sizeof(u32) > MAX_BPF_STACK);

Seems to communicate to me that the intentions here are that the BPF_STX
allowed by seccomp's verifier is limited to the defined stack space relative to
FP. My gut says check_load_and_stores and bpf_check_classic are not technically
as strict as they should be for the intentions of SECCOMP, but just happen to
work. I'd expect to see some code that just says "every store must index memory
from a well-defined offset from the read-only FP", but I don't quite see that,
unless I missed it (I think something to do with how fp->k is decided for
struct sock_filter in the classic verfier), despite there being indications
this was the intention elsewhere.

But maybe I am incorrect to assume the stack is the theoretical limit on what
can be the destination register for a seccomp filter store instruction for now
(and into the future)? If not, why? Is there an explicit exception I can make
in an EL2 verifier for filter programs that do not abide by these rules?

For now, based on what I am seeing in the kernel, I think it may be fine to
assume BPF_MEMWORDS associated with the stack is the theoretical limit on which
memory should be store-able, and "hope" that all associated instructions are
FP-relative.  If not, the alias register should be readily resolvable back to
FP, though having a formal contract that it would be FP-relative in the
kernel's JIT for cBPF would be awesome.

Regards,
Maxwell Bland





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux