OLD | NEW |
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 | 6 |
7 // Some headers on Android are missing cdefs: crbug.com/172337. | 7 // Some headers on Android are missing cdefs: crbug.com/172337. |
8 // (We can't use OS_ANDROID here since build_config.h is not included). | 8 // (We can't use OS_ANDROID here since build_config.h is not included). |
9 #if defined(ANDROID) | 9 #if defined(ANDROID) |
10 #include <sys/cdefs.h> | 10 #include <sys/cdefs.h> |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 explicit RedirectToUserSpacePolicyWrapper( | 192 explicit RedirectToUserSpacePolicyWrapper( |
193 const SandboxBPFPolicy* wrapped_policy) | 193 const SandboxBPFPolicy* wrapped_policy) |
194 : wrapped_policy_(wrapped_policy) { | 194 : wrapped_policy_(wrapped_policy) { |
195 DCHECK(wrapped_policy_); | 195 DCHECK(wrapped_policy_); |
196 } | 196 } |
197 | 197 |
198 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 198 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
199 int system_call_number) const OVERRIDE { | 199 int system_call_number) const OVERRIDE { |
200 ErrorCode err = | 200 ErrorCode err = |
201 wrapped_policy_->EvaluateSyscall(sandbox_compiler, system_call_number); | 201 wrapped_policy_->EvaluateSyscall(sandbox_compiler, system_call_number); |
202 if ((err.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) { | 202 ChangeErrnoToTraps(&err, sandbox_compiler); |
203 return ReturnErrnoViaTrap(sandbox_compiler, err.err() & SECCOMP_RET_DATA); | |
204 } | |
205 return err; | 203 return err; |
206 } | 204 } |
207 | 205 |
208 virtual ErrorCode InvalidSyscall( | 206 virtual ErrorCode InvalidSyscall( |
209 SandboxBPF* sandbox_compiler) const OVERRIDE { | 207 SandboxBPF* sandbox_compiler) const OVERRIDE { |
210 return ReturnErrnoViaTrap(sandbox_compiler, ENOSYS); | 208 return ReturnErrnoViaTrap(sandbox_compiler, ENOSYS); |
211 } | 209 } |
212 | 210 |
213 private: | 211 private: |
214 ErrorCode ReturnErrnoViaTrap(SandboxBPF* sandbox_compiler, int err) const { | 212 ErrorCode ReturnErrnoViaTrap(SandboxBPF* sandbox_compiler, int err) const { |
215 return sandbox_compiler->Trap(ReturnErrno, reinterpret_cast<void*>(err)); | 213 return sandbox_compiler->Trap(ReturnErrno, reinterpret_cast<void*>(err)); |
216 } | 214 } |
217 | 215 |
| 216 // ChangeErrnoToTraps recursivly iterates through the ErrorCode |
| 217 // converting any ERRNO to a userspace trap |
| 218 void ChangeErrnoToTraps(ErrorCode* err, SandboxBPF* sandbox_compiler) const { |
| 219 if (err->error_type() == ErrorCode::ET_SIMPLE && |
| 220 (err->err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) { |
| 221 // Have an errno, need to change this to a trap |
| 222 *err = |
| 223 ReturnErrnoViaTrap(sandbox_compiler, err->err() & SECCOMP_RET_DATA); |
| 224 return; |
| 225 } else if (err->error_type() == ErrorCode::ET_COND) { |
| 226 // Need to explore both paths |
| 227 ChangeErrnoToTraps((ErrorCode*)err->passed(), sandbox_compiler); |
| 228 ChangeErrnoToTraps((ErrorCode*)err->failed(), sandbox_compiler); |
| 229 return; |
| 230 } else if (err->error_type() == ErrorCode::ET_TRAP) { |
| 231 return; |
| 232 } else if (err->error_type() == ErrorCode::ET_SIMPLE && |
| 233 (err->err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ALLOW) { |
| 234 return; |
| 235 } |
| 236 NOTREACHED(); |
| 237 } |
| 238 |
218 const SandboxBPFPolicy* wrapped_policy_; | 239 const SandboxBPFPolicy* wrapped_policy_; |
219 DISALLOW_COPY_AND_ASSIGN(RedirectToUserSpacePolicyWrapper); | 240 DISALLOW_COPY_AND_ASSIGN(RedirectToUserSpacePolicyWrapper); |
220 }; | 241 }; |
221 | 242 |
222 intptr_t BPFFailure(const struct arch_seccomp_data&, void* aux) { | 243 intptr_t BPFFailure(const struct arch_seccomp_data&, void* aux) { |
223 SANDBOX_DIE(static_cast<char*>(aux)); | 244 SANDBOX_DIE(static_cast<char*>(aux)); |
224 } | 245 } |
225 | 246 |
226 } // namespace | 247 } // namespace |
227 | 248 |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 } | 1049 } |
1029 | 1050 |
1030 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { | 1051 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { |
1031 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); | 1052 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); |
1032 } | 1053 } |
1033 | 1054 |
1034 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { | 1055 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { |
1035 return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */); | 1056 return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */); |
1036 } | 1057 } |
1037 | 1058 |
| 1059 bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) { |
| 1060 return (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
| 1061 #if defined(__NR_sigprocmask) |
| 1062 || |
| 1063 sysno == __NR_sigprocmask |
| 1064 #endif |
| 1065 #if defined(__NR_sigreturn) |
| 1066 || |
| 1067 sysno == __NR_sigreturn |
| 1068 #endif |
| 1069 ); |
| 1070 } |
| 1071 |
1038 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { | 1072 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { |
1039 return Syscall::Call(args.nr, | 1073 return Syscall::Call(args.nr, |
1040 static_cast<intptr_t>(args.args[0]), | 1074 static_cast<intptr_t>(args.args[0]), |
1041 static_cast<intptr_t>(args.args[1]), | 1075 static_cast<intptr_t>(args.args[1]), |
1042 static_cast<intptr_t>(args.args[2]), | 1076 static_cast<intptr_t>(args.args[2]), |
1043 static_cast<intptr_t>(args.args[3]), | 1077 static_cast<intptr_t>(args.args[3]), |
1044 static_cast<intptr_t>(args.args[4]), | 1078 static_cast<intptr_t>(args.args[4]), |
1045 static_cast<intptr_t>(args.args[5])); | 1079 static_cast<intptr_t>(args.args[5])); |
1046 } | 1080 } |
1047 | 1081 |
(...skipping 11 matching lines...) Expand all Loading... |
1059 &*conds_->insert(failed).first); | 1093 &*conds_->insert(failed).first); |
1060 } | 1094 } |
1061 | 1095 |
1062 ErrorCode SandboxBPF::Kill(const char* msg) { | 1096 ErrorCode SandboxBPF::Kill(const char* msg) { |
1063 return Trap(BPFFailure, const_cast<char*>(msg)); | 1097 return Trap(BPFFailure, const_cast<char*>(msg)); |
1064 } | 1098 } |
1065 | 1099 |
1066 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; | 1100 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; |
1067 | 1101 |
1068 } // namespace sandbox | 1102 } // namespace sandbox |
OLD | NEW |