Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: sandbox/linux/seccomp-bpf/verifier.cc

Issue 11411254: SECCOMP-BPF: Added supported for inspection system call arguments from BPF filters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Changelist is ready for initial review; still needs a few TODO()s to be resolved, though. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 5 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
6 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 6 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
7 #include "sandbox/linux/seccomp-bpf/verifier.h" 7 #include "sandbox/linux/seccomp-bpf/verifier.h"
8 8
9 9
10 namespace playground2 { 10 namespace playground2 {
(...skipping 24 matching lines...) Expand all
35 if (!(sysnum & 0x40000000u)) { 35 if (!(sysnum & 0x40000000u)) {
36 continue; 36 continue;
37 } 37 }
38 #else 38 #else
39 if (sysnum & 0x40000000u) { 39 if (sysnum & 0x40000000u) {
40 continue; 40 continue;
41 } 41 }
42 #endif 42 #endif
43 #endif 43 #endif
44 ErrorCode code = evaluate_syscall(sysnum, aux); 44 ErrorCode code = evaluate_syscall(sysnum, aux);
45 uint32_t computed_ret = EvaluateBPF(program, data, err); 45 if (!VerifyErrorCode(program, &data, code, err)) {
46 return false;
47 }
48 }
49 return true;
50 }
51
52 bool Verifier::VerifyErrorCode(const std::vector<struct sock_filter>& program,
53 struct arch_seccomp_data *data,
54 const ErrorCode& code, const char **err) {
55 if (code.error_type_ == ErrorCode::ET_SIMPLE ||
56 code.error_type_ == ErrorCode::ET_TRAP) {
57 uint32_t computed_ret = EvaluateBPF(program, *data, err);
46 if (*err) { 58 if (*err) {
47 return false; 59 return false;
48 } else if (computed_ret != code.err()) { 60 } else if (computed_ret != code.err()) {
49 *err = "Exit code from BPF program doesn't match"; 61 *err = "Exit code from BPF program doesn't match";
50 return false; 62 return false;
51 } 63 }
64 } else if (code.error_type_ == ErrorCode::ET_COND) {
65 if (code.argno_ < 0 || code.argno_ >= 6) {
66 *err = "Invalid argument number in error code";
67 return false;
68 }
69 switch (code.op_) {
70 case ErrorCode::OP_EQUAL:
71 data->args[code.argno_] = code.value_;
72 if (!VerifyErrorCode(program, data, *code.passed_, err)) {
73 return false;
74 }
75 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.
76 if (!VerifyErrorCode(program, data, *code.failed_, err)) {
77 return false;
78 }
79 break;
80 default: // TODO(markus): Additional ops, and checks for 32/64bit
81 *err = "Unsupported operation in conditional error code";
82 return false;
83 }
84 } else {
85 *err = "Attempting to return invalid error code from BPF program";
86 return false;
52 } 87 }
53 return true; 88 return true;
54 } 89 }
55 90
56 uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program, 91 uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program,
57 const struct arch_seccomp_data& data, 92 const struct arch_seccomp_data& data,
58 const char **err) { 93 const char **err) {
59 *err = NULL; 94 *err = NULL;
60 if (program.size() < 1 || program.size() >= SECCOMP_MAX_PROGRAM_SIZE) { 95 if (program.size() < 1 || program.size() >= SECCOMP_MAX_PROGRAM_SIZE) {
61 *err = "Invalid program length"; 96 *err = "Invalid program length";
62 return 0; 97 return 0;
63 } 98 }
64 for (State state(program, data); !*err; ++state.ip) { 99 for (State state(program, data); !*err; ++state.ip) {
65 if (state.ip >= program.size()) { 100 if (state.ip >= program.size()) {
66 *err = "Invalid instruction pointer in BPF program"; 101 *err = "Invalid instruction pointer in BPF program";
67 break; 102 break;
68 } 103 }
69 const struct sock_filter& insn = program[state.ip]; 104 const struct sock_filter& insn = program[state.ip];
70 switch (BPF_CLASS(insn.code)) { 105 switch (BPF_CLASS(insn.code)) {
71 case BPF_LD: 106 case BPF_LD:
72 Ld(&state, insn, err); 107 Ld(&state, insn, err);
73 break; 108 break;
74 case BPF_JMP: 109 case BPF_JMP:
75 Jmp(&state, insn, err); 110 Jmp(&state, insn, err);
76 break; 111 break;
77 case BPF_RET: 112 case BPF_RET: {
78 return Ret(&state, insn, err); 113 uint32_t r = Ret(&state, insn, err);
114 switch (r & SECCOMP_RET_ACTION) {
115 case SECCOMP_RET_TRAP:
116 case SECCOMP_RET_ERRNO:
117 case SECCOMP_RET_ALLOW:
118 break;
119 case SECCOMP_RET_KILL: // We don't ever generate this
120 case SECCOMP_RET_TRACE: // We don't ever generate this
121 case SECCOMP_RET_INVALID: // Should never show up in BPF program
122 default:
123 *err = "Unexpected return code found in BPF program";
124 return 0;
125 }
126 return r; }
79 default: 127 default:
80 *err = "Unexpected instruction in BPF program"; 128 *err = "Unexpected instruction in BPF program";
81 break; 129 break;
82 } 130 }
83 } 131 }
84 return 0; 132 return 0;
85 } 133 }
86 134
87 void Verifier::Ld(State *state, const struct sock_filter& insn, 135 void Verifier::Ld(State *state, const struct sock_filter& insn,
88 const char **err) { 136 const char **err) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 uint32_t Verifier::Ret(State *, const struct sock_filter& insn, 207 uint32_t Verifier::Ret(State *, const struct sock_filter& insn,
160 const char **err) { 208 const char **err) {
161 if (BPF_SRC(insn.code) != BPF_K) { 209 if (BPF_SRC(insn.code) != BPF_K) {
162 *err = "Invalid BPF_RET instruction"; 210 *err = "Invalid BPF_RET instruction";
163 return 0; 211 return 0;
164 } 212 }
165 return insn.k; 213 return insn.k;
166 } 214 }
167 215
168 } // namespace 216 } // namespace
OLDNEW
« sandbox/linux/seccomp-bpf/syscall_iterator.cc ('K') | « sandbox/linux/seccomp-bpf/verifier.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698