SBPF.Verifier — static checks and the step-safety theorem #
The instruction-level part of the Solana verifier, ported from verifier.thy,
and the safety property it guarantees (VerifierSafety.thy, Lemma 6.4): an
instruction the verifier accepts never drives step into the err state (the
"malformed instruction" outcome the verifier exists to exclude).
verifyInstr models the Err-relevant content of verify_one: the version
gating (e.g. addStk/pqr are v2-only, neg/le are v1-only) and the
non-zero-divisor checks. The byte-level checks of verify_one
(check_load_dw, check_jmp_offset, check_registers) concern other safety
properties (in-bounds jumps, register ranges) that do not affect Err-freedom and
are omitted here.
Main definitions #
Solanalib.SBPF.verifyInstr— the instruction-level verifier.
Main statements #
Solanalib.SBPF.step_ne_err— verified instruction ⇒step ≠ err.
The verifier #
A division/remainder immediate operand must be non-zero.
Equations
Instances For
Version/divisor checks for an ALU op (mul/div/mod are v1-only;
div/mod immediates must be non-zero).
Equations
- Solanalib.SBPF.verifyAlu Solanalib.SBPF.Binop.mul sop isV1 = isV1
- Solanalib.SBPF.verifyAlu Solanalib.SBPF.Binop.div sop isV1 = (isV1 && Solanalib.SBPF.checkImmNonzero sop)
- Solanalib.SBPF.verifyAlu Solanalib.SBPF.Binop.mod sop isV1 = (isV1 && Solanalib.SBPF.checkImmNonzero sop)
- Solanalib.SBPF.verifyAlu bop sop isV1 = true
Instances For
Divisor checks for a PQR op (div/rem immediates must be non-zero).
Equations
- Solanalib.SBPF.verifyPqr Solanalib.SBPF.Pqrop.lmul sop = true
- Solanalib.SBPF.verifyPqr Solanalib.SBPF.Pqrop.udiv sop = Solanalib.SBPF.checkImmNonzero sop
- Solanalib.SBPF.verifyPqr Solanalib.SBPF.Pqrop.urem sop = Solanalib.SBPF.checkImmNonzero sop
- Solanalib.SBPF.verifyPqr Solanalib.SBPF.Pqrop.sdiv sop = Solanalib.SBPF.checkImmNonzero sop
- Solanalib.SBPF.verifyPqr Solanalib.SBPF.Pqrop.srem sop = Solanalib.SBPF.checkImmNonzero sop
Instances For
The instruction-level verifier (verify_one, Err-relevant content).
Equations
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.ldImm dst immLo immHi) Solanalib.SBPF.SBPFV.v1 = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.ldImm dst immLo immHi) Solanalib.SBPF.SBPFV.v2 = false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.ldx chunk dst src off) sv = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.st chunk dst src off) sv = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.addStk imm) Solanalib.SBPF.SBPFV.v1 = !true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.addStk imm) Solanalib.SBPF.SBPFV.v2 = !false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.alu bop dst sop) Solanalib.SBPF.SBPFV.v1 = Solanalib.SBPF.verifyAlu bop sop true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.alu bop dst sop) Solanalib.SBPF.SBPFV.v2 = Solanalib.SBPF.verifyAlu bop sop false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.neg32Reg dst) Solanalib.SBPF.SBPFV.v1 = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.neg32Reg dst) Solanalib.SBPF.SBPFV.v2 = false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.le dst i) Solanalib.SBPF.SBPFV.v1 = (true && (i == 16 || i == 32 || i == 64))
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.le dst i) Solanalib.SBPF.SBPFV.v2 = (false && (i == 16 || i == 32 || i == 64))
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.be dst i) sv = (i == 16 || i == 32 || i == 64)
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.alu64 bop dst sop) Solanalib.SBPF.SBPFV.v1 = Solanalib.SBPF.verifyAlu bop sop true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.alu64 bop dst sop) Solanalib.SBPF.SBPFV.v2 = Solanalib.SBPF.verifyAlu bop sop false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.neg64Reg dst) Solanalib.SBPF.SBPFV.v1 = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.neg64Reg dst) Solanalib.SBPF.SBPFV.v2 = false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.hor64Imm dst imm) Solanalib.SBPF.SBPFV.v1 = !true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.hor64Imm dst imm) Solanalib.SBPF.SBPFV.v2 = !false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.pqr pop dst sop) Solanalib.SBPF.SBPFV.v1 = (!true && Solanalib.SBPF.verifyPqr pop sop)
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.pqr pop dst sop) Solanalib.SBPF.SBPFV.v2 = (!false && Solanalib.SBPF.verifyPqr pop sop)
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.pqr64 pop dst sop) Solanalib.SBPF.SBPFV.v1 = (!true && Solanalib.SBPF.verifyPqr pop sop)
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.pqr64 pop dst sop) Solanalib.SBPF.SBPFV.v2 = (!false && Solanalib.SBPF.verifyPqr pop sop)
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.pqr2 op dst src) Solanalib.SBPF.SBPFV.v1 = !true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.pqr2 op dst src) Solanalib.SBPF.SBPFV.v2 = !false
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.ja off) sv = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.jump cond r src off) sv = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.callReg src imm) sv = true
- Solanalib.SBPF.verifyInstr (Solanalib.SBPF.BpfInstruction.callImm src imm) sv = true
- Solanalib.SBPF.verifyInstr Solanalib.SBPF.BpfInstruction.exit sv = true
Instances For
Supporting lemmas #
Sign-extending to 64 bits is zero exactly when the source is.
A non-nok ALU result keeps step out of the err state.
Safety #
Verifier step-safety (Lemma 6.4): if verifyInstr accepts an
instruction, then step on it never returns the err state.