| 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 |