Chromium Code Reviews| Index: sandbox/linux/seccomp-bpf/verifier.cc |
| diff --git a/sandbox/linux/seccomp-bpf/verifier.cc b/sandbox/linux/seccomp-bpf/verifier.cc |
| index 40a1aa20be7a8fcd196a7e89e3f72128c6aeb9ee..d40a79a9d2f2581353aae4901d2a870102561234 100644 |
| --- a/sandbox/linux/seccomp-bpf/verifier.cc |
| +++ b/sandbox/linux/seccomp-bpf/verifier.cc |
| @@ -42,13 +42,48 @@ bool Verifier::VerifyBPF(const std::vector<struct sock_filter>& program, |
| #endif |
| #endif |
| ErrorCode code = evaluate_syscall(sysnum, aux); |
| - uint32_t computed_ret = EvaluateBPF(program, data, err); |
| + if (!VerifyErrorCode(program, &data, code, err)) { |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +bool Verifier::VerifyErrorCode(const std::vector<struct sock_filter>& program, |
| + struct arch_seccomp_data *data, |
| + const ErrorCode& code, const char **err) { |
| + if (code.error_type_ == ErrorCode::ET_SIMPLE || |
| + code.error_type_ == ErrorCode::ET_TRAP) { |
| + uint32_t computed_ret = EvaluateBPF(program, *data, err); |
| if (*err) { |
| return false; |
| } else if (computed_ret != code.err()) { |
| *err = "Exit code from BPF program doesn't match"; |
| return false; |
| } |
| + } else if (code.error_type_ == ErrorCode::ET_COND) { |
| + if (code.argno_ < 0 || code.argno_ >= 6) { |
| + *err = "Invalid argument number in error code"; |
| + return false; |
| + } |
| + switch (code.op_) { |
| + case ErrorCode::OP_EQUAL: |
| + data->args[code.argno_] = code.value_; |
| + if (!VerifyErrorCode(program, data, *code.passed_, err)) { |
| + return false; |
| + } |
| + data->args[code.argno_] = code.value_ ^ 0x55AA55AA; |
|
jln (very slow on Chromium)
2012/12/06 00:35:00
I most definitely need a comment here :)
Markus (顧孟勤)
2012/12/12 20:54:35
Done.
|
| + if (!VerifyErrorCode(program, data, *code.failed_, err)) { |
| + return false; |
| + } |
| + break; |
| + default: // TODO(markus): Additional ops, and checks for 32/64bit |
| + *err = "Unsupported operation in conditional error code"; |
| + return false; |
| + } |
| + } else { |
| + *err = "Attempting to return invalid error code from BPF program"; |
| + return false; |
| } |
| return true; |
| } |
| @@ -74,8 +109,21 @@ uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program, |
| case BPF_JMP: |
| Jmp(&state, insn, err); |
| break; |
| - case BPF_RET: |
| - return Ret(&state, insn, err); |
| + case BPF_RET: { |
| + uint32_t r = Ret(&state, insn, err); |
| + switch (r & SECCOMP_RET_ACTION) { |
| + case SECCOMP_RET_TRAP: |
| + case SECCOMP_RET_ERRNO: |
| + case SECCOMP_RET_ALLOW: |
| + break; |
| + case SECCOMP_RET_KILL: // We don't ever generate this |
| + case SECCOMP_RET_TRACE: // We don't ever generate this |
| + case SECCOMP_RET_INVALID: // Should never show up in BPF program |
| + default: |
| + *err = "Unexpected return code found in BPF program"; |
| + return 0; |
| + } |
| + return r; } |
| default: |
| *err = "Unexpected instruction in BPF program"; |
| break; |