--- 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