Commit d2283ac2 authored by mdempsky's avatar mdempsky Committed by Commit bot

Split AssembleFilter into comprehensible chunks

Previously SandboxBPF constructed the CodeGen Instruction sequence
primarily in one large, complex function.  Additionally, it made
extensive use of the CodeGen::JoinInstructions() function to
conditionally arrange various bits of instructions, which made it
harder to follow.

This CL splits the Instruction assembly code into 5 mostly distinct
functions and eliminates all use of JoinInstruction() in favor of
function composition.  E.g., instead of

    foo = gen->MakeInstruction(...);
    bar = gen->MakeInstruction(...);
    gen->JoinInstructions(foo, bar);

this CL favors writing

    MakeFoo(MakeBar())

with the convention that Instruction-constructing functions should
arrange for control to transfer to the Instruction sequence argument
when complete.  (I.e., "continuation-passing style":
http://en.wikipedia.org/wiki/Continuation-passing_style)

BUG=414363

Review URL: https://codereview.chromium.org/568053005

Cr-Commit-Position: refs/heads/master@{#295015}
parent 31e9fd65
This diff is collapsed.
...@@ -246,6 +246,37 @@ class SANDBOX_EXPORT SandboxBPF { ...@@ -246,6 +246,37 @@ class SANDBOX_EXPORT SandboxBPF {
// been configured with SetSandboxPolicy(). // been configured with SetSandboxPolicy().
void InstallFilter(bool must_sync_threads); void InstallFilter(bool must_sync_threads);
// Compile the configured policy into a complete instruction sequence.
// (See MaybeAddEscapeHatch for |has_unsafe_traps|.)
Instruction* CompilePolicy(CodeGen* gen, bool* has_unsafe_traps);
// Return an instruction sequence that checks the
// arch_seccomp_data's "arch" field is valid, and then passes
// control to |passed| if so.
Instruction* CheckArch(CodeGen* gen, Instruction* passed);
// If the |rest| instruction sequence contains any unsafe traps,
// then sets |*has_unsafe_traps| to true and returns an instruction
// sequence that allows all system calls from Syscall::Call(), and
// otherwise passes control to |rest|.
//
// If |rest| contains no unsafe traps, then |rest| is returned
// directly and |*has_unsafe_traps| is set to false.
Instruction* MaybeAddEscapeHatch(CodeGen* gen,
bool* has_unsafe_traps,
Instruction* rest);
// Return an instruction sequence that loads and checks the system
// call number, performs a binary search, and then dispatches to an
// appropriate instruction sequence compiled from the current
// policy.
Instruction* DispatchSyscall(CodeGen* gen);
// Return an instruction sequence that checks the system call number
// (expected to be loaded in register A) and if valid, passes
// control to |passed| (with register A still valid).
Instruction* CheckSyscallNumber(CodeGen* gen, Instruction* passed);
// Verify the correctness of a compiled program by comparing it against the // Verify the correctness of a compiled program by comparing it against the
// current policy. This function should only ever be called by unit tests and // current policy. This function should only ever be called by unit tests and
// by the sandbox internals. It should not be used by production code. // by the sandbox internals. It should not be used by production code.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment