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

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

Issue 260793003: [MIPS] Add seccomp bpf support (Closed) Base URL: https://git.chromium.org/git/chromium/src.git@master
Patch Set: Update per code review Created 6 years, 6 months 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
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/trap.h" 5 #include "sandbox/linux/seccomp-bpf/trap.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/prctl.h> 10 #include <sys/prctl.h>
11 #include <sys/syscall.h> 11 #include <sys/syscall.h>
12 12
13 #include <limits> 13 #include <limits>
14 14
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "sandbox/linux/seccomp-bpf/codegen.h" 16 #include "sandbox/linux/seccomp-bpf/codegen.h"
17 #include "sandbox/linux/seccomp-bpf/die.h" 17 #include "sandbox/linux/seccomp-bpf/die.h"
18 #include "sandbox/linux/seccomp-bpf/kernel_return_value_helpers.h"
18 #include "sandbox/linux/seccomp-bpf/syscall.h" 19 #include "sandbox/linux/seccomp-bpf/syscall.h"
19 20
20 // Android's signal.h doesn't define ucontext etc. 21 // Android's signal.h doesn't define ucontext etc.
21 #if defined(OS_ANDROID) 22 #if defined(OS_ANDROID)
22 #include "sandbox/linux/services/android_ucontext.h" 23 #include "sandbox/linux/services/android_ucontext.h"
23 #endif 24 #endif
24 25
25 namespace { 26 namespace {
26 27
27 const int kCapacityIncrement = 20; 28 const int kCapacityIncrement = 20;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // Obtain the signal context. This, most notably, gives us access to 144 // Obtain the signal context. This, most notably, gives us access to
144 // all CPU registers at the time of the signal. 145 // all CPU registers at the time of the signal.
145 ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context); 146 ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context);
146 147
147 // Obtain the siginfo information that is specific to SIGSYS. Unfortunately, 148 // Obtain the siginfo information that is specific to SIGSYS. Unfortunately,
148 // most versions of glibc don't include this information in siginfo_t. So, 149 // most versions of glibc don't include this information in siginfo_t. So,
149 // we need to explicitly copy it into a arch_sigsys structure. 150 // we need to explicitly copy it into a arch_sigsys structure.
150 struct arch_sigsys sigsys; 151 struct arch_sigsys sigsys;
151 memcpy(&sigsys, &info->_sifields, sizeof(sigsys)); 152 memcpy(&sigsys, &info->_sifields, sizeof(sigsys));
152 153
154 bool sigsys_nr_is_bad = true;
155 #if defined(__mips__)
156 // When indirect syscall (syscall(__NR_foo, ...)) is made on Mips, the
157 // number in register SECCOMP_SYSCALL(ctx) is always __NR_syscall and the
158 // real number of a syscall (__NR_foo) is in SECCOMP_PARM1(ctx)
159 sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) &&
160 sigsys.nr != static_cast<int>(SECCOMP_PARM1(ctx));
161 #else
162 sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx));
163 #endif
164
153 // Some more sanity checks. 165 // Some more sanity checks.
154 if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) || 166 if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) ||
155 sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) || 167 sigsys_nr_is_bad ||
156 sigsys.arch != SECCOMP_ARCH) { 168 sigsys.arch != SECCOMP_ARCH) {
157 // TODO(markus): 169 // TODO(markus):
158 // SANDBOX_DIE() can call LOG(FATAL). This is not normally async-signal 170 // SANDBOX_DIE() can call LOG(FATAL). This is not normally async-signal
159 // safe and can lead to bugs. We should eventually implement a different 171 // safe and can lead to bugs. We should eventually implement a different
160 // logging and reporting mechanism that is safe to be called from 172 // logging and reporting mechanism that is safe to be called from
161 // the sigSys() handler. 173 // the sigSys() handler.
162 RAW_SANDBOX_DIE("Sanity checks are failing after receiving SIGSYS."); 174 RAW_SANDBOX_DIE("Sanity checks are failing after receiving SIGSYS.");
163 } 175 }
164 176
165 intptr_t rc; 177 intptr_t rc;
166 if (has_unsafe_traps_ && GetIsInSigHandler(ctx)) { 178 if (has_unsafe_traps_ && GetIsInSigHandler(ctx)) {
167 errno = old_errno; 179 errno = old_errno;
168 if (sigsys.nr == __NR_clone) { 180 if (sigsys.nr == __NR_clone) {
169 RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler."); 181 RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler.");
170 } 182 }
171 rc = SandboxSyscall(sigsys.nr, 183 rc = SandboxSyscall(SECCOMP_SYSCALL(ctx),
172 SECCOMP_PARM1(ctx), 184 SECCOMP_PARM1(ctx),
173 SECCOMP_PARM2(ctx), 185 SECCOMP_PARM2(ctx),
174 SECCOMP_PARM3(ctx), 186 SECCOMP_PARM3(ctx),
175 SECCOMP_PARM4(ctx), 187 SECCOMP_PARM4(ctx),
176 SECCOMP_PARM5(ctx), 188 SECCOMP_PARM5(ctx),
177 SECCOMP_PARM6(ctx)); 189 SECCOMP_PARM6(ctx));
178 } else { 190 } else {
179 const ErrorCode& err = trap_array_[info->si_errno - 1]; 191 const ErrorCode& err = trap_array_[info->si_errno - 1];
180 if (!err.safe_) { 192 if (!err.safe_) {
181 SetIsInSigHandler(); 193 SetIsInSigHandler();
182 } 194 }
183 195
184 // Copy the seccomp-specific data into a arch_seccomp_data structure. This 196 // Copy the seccomp-specific data into a arch_seccomp_data structure. This
185 // is what we are showing to TrapFnc callbacks that the system call 197 // is what we are showing to TrapFnc callbacks that the system call
186 // evaluator registered with the sandbox. 198 // evaluator registered with the sandbox.
187 struct arch_seccomp_data data = { 199 struct arch_seccomp_data data = {
188 sigsys.nr, SECCOMP_ARCH, reinterpret_cast<uint64_t>(sigsys.ip), 200 static_cast<int>SECCOMP_SYSCALL(ctx), SECCOMP_ARCH,
201 reinterpret_cast<uint64_t>(sigsys.ip),
189 {static_cast<uint64_t>(SECCOMP_PARM1(ctx)), 202 {static_cast<uint64_t>(SECCOMP_PARM1(ctx)),
190 static_cast<uint64_t>(SECCOMP_PARM2(ctx)), 203 static_cast<uint64_t>(SECCOMP_PARM2(ctx)),
191 static_cast<uint64_t>(SECCOMP_PARM3(ctx)), 204 static_cast<uint64_t>(SECCOMP_PARM3(ctx)),
192 static_cast<uint64_t>(SECCOMP_PARM4(ctx)), 205 static_cast<uint64_t>(SECCOMP_PARM4(ctx)),
193 static_cast<uint64_t>(SECCOMP_PARM5(ctx)), 206 static_cast<uint64_t>(SECCOMP_PARM5(ctx)),
194 static_cast<uint64_t>(SECCOMP_PARM6(ctx))}}; 207 static_cast<uint64_t>(SECCOMP_PARM6(ctx))}};
195 208
196 // Now call the TrapFnc callback associated with this particular instance 209 // Now call the TrapFnc callback associated with this particular instance
197 // of SECCOMP_RET_TRAP. 210 // of SECCOMP_RET_TRAP.
198 rc = err.fnc_(data, err.aux_); 211 rc = err.fnc_(data, err.aux_);
jln (very slow on Chromium) 2014/06/03 01:00:33 I think we'll need to change the interface of the
199 } 212 }
200 213
201 // Update the CPU register that stores the return code of the system call 214 // Update the CPU register that stores the return code of the system call
202 // that we just handled, and restore "errno" to the value that it had 215 // that we just handled, and restore "errno" to the value that it had
203 // before entering the signal handler. 216 // before entering the signal handler.
204 SECCOMP_RESULT(ctx) = static_cast<greg_t>(rc); 217 PutValueInUcontext(static_cast<int>(rc), ctx);
jln (very slow on Chromium) 2014/06/03 01:00:33 You're silently truncating |rc|. This is not corre
nedeljko 2014/06/03 15:32:18 I changed this.
205 errno = old_errno; 218 errno = old_errno;
206 219
207 return; 220 return;
208 } 221 }
209 222
210 bool Trap::TrapKey::operator<(const TrapKey& o) const { 223 bool Trap::TrapKey::operator<(const TrapKey& o) const {
211 if (fnc != o.fnc) { 224 if (fnc != o.fnc) {
212 return fnc < o.fnc; 225 return fnc < o.fnc;
213 } else if (aux != o.aux) { 226 } else if (aux != o.aux) {
214 return aux < o.aux; 227 return aux < o.aux;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 if (global_trap_ && id > 0 && id <= global_trap_->trap_array_size_) { 361 if (global_trap_ && id > 0 && id <= global_trap_->trap_array_size_) {
349 return global_trap_->trap_array_[id - 1]; 362 return global_trap_->trap_array_[id - 1];
350 } else { 363 } else {
351 return ErrorCode(); 364 return ErrorCode();
352 } 365 }
353 } 366 }
354 367
355 Trap* Trap::global_trap_; 368 Trap* Trap::global_trap_;
356 369
357 } // namespace sandbox 370 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698