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

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>
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // Obtain the signal context. This, most notably, gives us access to 143 // Obtain the signal context. This, most notably, gives us access to
144 // all CPU registers at the time of the signal. 144 // all CPU registers at the time of the signal.
145 ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context); 145 ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context);
146 146
147 // Obtain the siginfo information that is specific to SIGSYS. Unfortunately, 147 // Obtain the siginfo information that is specific to SIGSYS. Unfortunately,
148 // most versions of glibc don't include this information in siginfo_t. So, 148 // 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. 149 // we need to explicitly copy it into a arch_sigsys structure.
150 struct arch_sigsys sigsys; 150 struct arch_sigsys sigsys;
151 memcpy(&sigsys, &info->_sifields, sizeof(sigsys)); 151 memcpy(&sigsys, &info->_sifields, sizeof(sigsys));
152 152
153 #if defined(__mips__)
154 // When indirect syscall (syscall(__NR_foo, ...)) is made on Mips, the
155 // number in register SECCOMP_SYSCALL(ctx) is always __NR_syscall and the
156 // real number of a syscall (__NR_foo) is in SECCOMP_PARM1(ctx)
157 bool sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx))
158 && sigsys.nr != static_cast<int>(SECCOMP_PARM1(ctx));
jln (very slow on Chromium) 2014/06/20 00:37:06 Nit: indent. (please use "git cl format")
nedeljko 2014/06/20 14:09:51 Done.
159 #else
160 bool sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx));
161 #endif
162
153 // Some more sanity checks. 163 // Some more sanity checks.
154 if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) || 164 if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) ||
155 sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) || 165 sigsys_nr_is_bad ||
156 sigsys.arch != SECCOMP_ARCH) { 166 sigsys.arch != SECCOMP_ARCH) {
157 // TODO(markus): 167 // TODO(markus):
158 // SANDBOX_DIE() can call LOG(FATAL). This is not normally async-signal 168 // 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 169 // safe and can lead to bugs. We should eventually implement a different
160 // logging and reporting mechanism that is safe to be called from 170 // logging and reporting mechanism that is safe to be called from
161 // the sigSys() handler. 171 // the sigSys() handler.
162 RAW_SANDBOX_DIE("Sanity checks are failing after receiving SIGSYS."); 172 RAW_SANDBOX_DIE("Sanity checks are failing after receiving SIGSYS.");
163 } 173 }
164 174
165 intptr_t rc; 175 intptr_t rc;
166 if (has_unsafe_traps_ && GetIsInSigHandler(ctx)) { 176 if (has_unsafe_traps_ && GetIsInSigHandler(ctx)) {
167 errno = old_errno; 177 errno = old_errno;
168 if (sigsys.nr == __NR_clone) { 178 if (sigsys.nr == __NR_clone) {
169 RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler."); 179 RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler.");
170 } 180 }
171 rc = Syscall::Call(sigsys.nr, 181 rc = Syscall::Call(SECCOMP_SYSCALL(ctx),
172 SECCOMP_PARM1(ctx), 182 SECCOMP_PARM1(ctx),
173 SECCOMP_PARM2(ctx), 183 SECCOMP_PARM2(ctx),
174 SECCOMP_PARM3(ctx), 184 SECCOMP_PARM3(ctx),
175 SECCOMP_PARM4(ctx), 185 SECCOMP_PARM4(ctx),
176 SECCOMP_PARM5(ctx), 186 SECCOMP_PARM5(ctx),
177 SECCOMP_PARM6(ctx)); 187 SECCOMP_PARM6(ctx));
jln (very slow on Chromium) 2014/06/20 00:37:06 What happens in MIPS if something makes an indirec
nedeljko 2014/06/20 14:09:51 For indirect syscall with 6 parameters MIPS should
jln (very slow on Chromium) 2014/06/20 21:18:18 What is the maximum number of parameters for a Lin
178 } else { 188 } else {
179 const ErrorCode& err = trap_array_[info->si_errno - 1]; 189 const ErrorCode& err = trap_array_[info->si_errno - 1];
180 if (!err.safe_) { 190 if (!err.safe_) {
181 SetIsInSigHandler(); 191 SetIsInSigHandler();
182 } 192 }
183 193
184 // Copy the seccomp-specific data into a arch_seccomp_data structure. This 194 // 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 195 // is what we are showing to TrapFnc callbacks that the system call
186 // evaluator registered with the sandbox. 196 // evaluator registered with the sandbox.
187 struct arch_seccomp_data data = { 197 struct arch_seccomp_data data = {
188 sigsys.nr, SECCOMP_ARCH, reinterpret_cast<uint64_t>(sigsys.ip), 198 static_cast<int> SECCOMP_SYSCALL(ctx),
199 SECCOMP_ARCH,
200 reinterpret_cast<uint64_t>(sigsys.ip),
189 {static_cast<uint64_t>(SECCOMP_PARM1(ctx)), 201 {static_cast<uint64_t>(SECCOMP_PARM1(ctx)),
190 static_cast<uint64_t>(SECCOMP_PARM2(ctx)), 202 static_cast<uint64_t>(SECCOMP_PARM2(ctx)),
191 static_cast<uint64_t>(SECCOMP_PARM3(ctx)), 203 static_cast<uint64_t>(SECCOMP_PARM3(ctx)),
192 static_cast<uint64_t>(SECCOMP_PARM4(ctx)), 204 static_cast<uint64_t>(SECCOMP_PARM4(ctx)),
193 static_cast<uint64_t>(SECCOMP_PARM5(ctx)), 205 static_cast<uint64_t>(SECCOMP_PARM5(ctx)),
194 static_cast<uint64_t>(SECCOMP_PARM6(ctx))}}; 206 static_cast<uint64_t>(SECCOMP_PARM6(ctx))}};
195 207
196 // Now call the TrapFnc callback associated with this particular instance 208 // Now call the TrapFnc callback associated with this particular instance
197 // of SECCOMP_RET_TRAP. 209 // of SECCOMP_RET_TRAP.
198 rc = err.fnc_(data, err.aux_); 210 rc = err.fnc_(data, err.aux_);
199 } 211 }
200 212
201 // Update the CPU register that stores the return code of the system call 213 // 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 214 // that we just handled, and restore "errno" to the value that it had
203 // before entering the signal handler. 215 // before entering the signal handler.
204 SECCOMP_RESULT(ctx) = static_cast<greg_t>(rc); 216 Syscall::PutValueInUcontext(rc, ctx);
205 errno = old_errno; 217 errno = old_errno;
206 218
207 return; 219 return;
208 } 220 }
209 221
210 bool Trap::TrapKey::operator<(const TrapKey& o) const { 222 bool Trap::TrapKey::operator<(const TrapKey& o) const {
211 if (fnc != o.fnc) { 223 if (fnc != o.fnc) {
212 return fnc < o.fnc; 224 return fnc < o.fnc;
213 } else if (aux != o.aux) { 225 } else if (aux != o.aux) {
214 return aux < o.aux; 226 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_) { 360 if (global_trap_ && id > 0 && id <= global_trap_->trap_array_size_) {
349 return global_trap_->trap_array_[id - 1]; 361 return global_trap_->trap_array_[id - 1];
350 } else { 362 } else {
351 return ErrorCode(); 363 return ErrorCode();
352 } 364 }
353 } 365 }
354 366
355 Trap* Trap::global_trap_; 367 Trap* Trap::global_trap_;
356 368
357 } // namespace sandbox 369 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698