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

Side by Side Diff: sandbox/linux/seccomp-bpf/syscall.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, 5 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
« no previous file with comments | « sandbox/linux/seccomp-bpf/syscall.h ('k') | sandbox/linux/seccomp-bpf/syscall_iterator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/syscall.h" 5 #include "sandbox/linux/seccomp-bpf/syscall.h"
6 6
7 #include <asm/unistd.h> 7 #include <asm/unistd.h>
8 #include <errno.h> 8 #include <errno.h>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
12 13
13 namespace sandbox { 14 namespace sandbox {
14 15
15 namespace { 16 namespace {
16 17
17 asm(// We need to be able to tell the kernel exactly where we made a 18 asm(// We need to be able to tell the kernel exactly where we made a
18 // system call. The C++ compiler likes to sometimes clone or 19 // system call. The C++ compiler likes to sometimes clone or
19 // inline code, which would inadvertently end up duplicating 20 // inline code, which would inadvertently end up duplicating
20 // the entry point. 21 // the entry point.
21 // "gcc" can suppress code duplication with suitable function 22 // "gcc" can suppress code duplication with suitable function
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 // Restore the frame pointer. Also restore the program counter from 165 // Restore the frame pointer. Also restore the program counter from
165 // the link register; this makes us return to the caller. 166 // the link register; this makes us return to the caller.
166 #if defined(__thumb__) 167 #if defined(__thumb__)
167 "2:pop {r7, pc}\n" 168 "2:pop {r7, pc}\n"
168 ".cfi_endproc\n" 169 ".cfi_endproc\n"
169 #else 170 #else
170 "2:ldmfd sp!, {fp, pc}\n" 171 "2:ldmfd sp!, {fp, pc}\n"
171 #endif 172 #endif
172 ".fnend\n" 173 ".fnend\n"
173 "9:.size SyscallAsm, 9b-SyscallAsm\n" 174 "9:.size SyscallAsm, 9b-SyscallAsm\n"
175 #elif defined(__mips__)
176 ".text\n"
177 ".align 4\n"
178 ".type SyscallAsm, @function\n"
179 "SyscallAsm:.ent SyscallAsm\n"
180 ".frame $sp, 40, $ra\n"
181 ".set push\n"
182 ".set noreorder\n"
183 "addiu $sp, $sp, -40\n"
184 "sw $ra, 36($sp)\n"
185 // Check if "v0" is negative. If so, do not attempt to make a
186 // system call. Instead, compute the return address that is visible
187 // to the kernel after we execute "syscall". This address can be
188 // used as a marker that BPF code inspects.
189 "bgez $v0, 1f\n"
190 " nop\n"
191 "la $v0, 2f\n"
192 "b 2f\n"
193 " nop\n"
194 // On MIPS first four arguments go to registers a0 - a3 and any
195 // argument after that goes to stack. We can go ahead and directly
196 // copy the entries from the arguments array into the appropriate
197 // CPU registers and on the stack.
198 "1:lw $a3, 28($a0)\n"
199 "lw $a2, 24($a0)\n"
200 "lw $a1, 20($a0)\n"
201 "lw $t0, 16($a0)\n"
202 "sw $a3, 28($sp)\n"
203 "sw $a2, 24($sp)\n"
204 "sw $a1, 20($sp)\n"
205 "sw $t0, 16($sp)\n"
206 "lw $a3, 12($a0)\n"
207 "lw $a2, 8($a0)\n"
208 "lw $a1, 4($a0)\n"
209 "lw $a0, 0($a0)\n"
210 // Enter the kernel
211 "syscall\n"
212 // This is our "magic" return address that the BPF filter sees.
213 // Restore the return address from the stack.
214 "2:lw $ra, 36($sp)\n"
215 "jr $ra\n"
216 " addiu $sp, $sp, 40\n"
217 ".set pop\n"
218 ".end SyscallAsm\n"
219 ".size SyscallAsm,.-SyscallAsm\n"
174 #endif 220 #endif
175 ); // asm 221 ); // asm
176 222
177 } // namespace 223 } // namespace
178 224
179 intptr_t Syscall::Call(int nr, 225 intptr_t Syscall::Call(int nr,
180 intptr_t p0, 226 intptr_t p0,
181 intptr_t p1, 227 intptr_t p1,
182 intptr_t p2, 228 intptr_t p2,
183 intptr_t p3, 229 intptr_t p3,
184 intptr_t p4, 230 intptr_t p4,
185 intptr_t p5, 231 intptr_t p5,
186 intptr_t p6, 232 intptr_t p6,
187 intptr_t p7) { 233 intptr_t p7) {
188 // We rely on "intptr_t" to be the exact size as a "void *". This is 234 // We rely on "intptr_t" to be the exact size as a "void *". This is
189 // typically true, but just in case, we add a check. The language 235 // typically true, but just in case, we add a check. The language
190 // specification allows platforms some leeway in cases, where 236 // specification allows platforms some leeway in cases, where
191 // "sizeof(void *)" is not the same as "sizeof(void (*)())". We expect 237 // "sizeof(void *)" is not the same as "sizeof(void (*)())". We expect
192 // that this would only be an issue for IA64, which we are currently not 238 // that this would only be an issue for IA64, which we are currently not
193 // planning on supporting. And it is even possible that this would work 239 // planning on supporting. And it is even possible that this would work
194 // on IA64, but for lack of actual hardware, I cannot test. 240 // on IA64, but for lack of actual hardware, I cannot test.
195 COMPILE_ASSERT(sizeof(void*) == sizeof(intptr_t), 241 COMPILE_ASSERT(sizeof(void*) == sizeof(intptr_t),
196 pointer_types_and_intptr_must_be_exactly_the_same_size); 242 pointer_types_and_intptr_must_be_exactly_the_same_size);
197 243
198 // TODO(nedeljko): Enable use of more than six parameters on architectures 244 // TODO(nedeljko): Enable use of more than six parameters on architectures
199 // where that makes sense. 245 // where that makes sense.
246 #if defined(__mips__)
247 const intptr_t args[8] = {p0, p1, p2, p3, p4, p5, p6, p7};
248 #else
200 DCHECK_EQ(p6, 0) << " Support for syscalls with more than six arguments not " 249 DCHECK_EQ(p6, 0) << " Support for syscalls with more than six arguments not "
201 "added for this architecture"; 250 "added for this architecture";
202 DCHECK_EQ(p7, 0) << " Support for syscalls with more than six arguments not " 251 DCHECK_EQ(p7, 0) << " Support for syscalls with more than six arguments not "
203 "added for this architecture"; 252 "added for this architecture";
204 const intptr_t args[6] = {p0, p1, p2, p3, p4, p5}; 253 const intptr_t args[6] = {p0, p1, p2, p3, p4, p5};
254 #endif // defined(__mips__)
205 255
206 // Invoke our file-scope assembly code. The constraints have been picked 256 // Invoke our file-scope assembly code. The constraints have been picked
207 // carefully to match what the rest of the assembly code expects in input, 257 // carefully to match what the rest of the assembly code expects in input,
208 // output, and clobbered registers. 258 // output, and clobbered registers.
209 #if defined(__i386__) 259 #if defined(__i386__)
210 intptr_t ret = nr; 260 intptr_t ret = nr;
211 asm volatile( 261 asm volatile(
212 "call SyscallAsm\n" 262 "call SyscallAsm\n"
213 // N.B. These are not the calling conventions normally used by the ABI. 263 // N.B. These are not the calling conventions normally used by the ABI.
214 : "=a"(ret) 264 : "=a"(ret)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // it. 311 // it.
262 // In ARM mode, we have a dedicated frame pointer register and "r7" is 312 // In ARM mode, we have a dedicated frame pointer register and "r7" is
263 // thus available as a general purpose register. We don't preserve it, 313 // thus available as a general purpose register. We don't preserve it,
264 // but instead mark it as clobbered. 314 // but instead mark it as clobbered.
265 , 315 ,
266 "r7" 316 "r7"
267 #endif // !defined(__thumb__) 317 #endif // !defined(__thumb__)
268 ); 318 );
269 ret = inout; 319 ret = inout;
270 } 320 }
321 #elif defined(__mips__)
322 int err_status;
323 intptr_t ret = Syscall::SandboxSyscallRaw(nr, args, &err_status);
324
325 if (err_status) {
326 // On error, MIPS returns errno from syscall instead of -errno.
327 // The purpose of this negation is for SandboxSyscall() to behave
328 // more like it would on other architectures.
329 ret = -ret;
330 }
271 #else 331 #else
272 #error "Unimplemented architecture" 332 #error "Unimplemented architecture"
273 #endif 333 #endif
274 return ret; 334 return ret;
275 } 335 }
276 336
337 void Syscall::PutValueInUcontext(intptr_t ret_val, ucontext_t* ctx) {
338 #if defined(__mips__)
339 // Mips ABI states that on error a3 CPU register has non zero value and if
340 // there is no error, it should be zero.
341 if (ret_val <= -1 && ret_val >= -4095) {
342 // |ret_val| followes the Syscall::Call() convention of being -errno on
343 // errors. In order to write correct value to return register this sign
344 // needs to be changed back.
345 ret_val = -ret_val;
346 SECCOMP_PARM4(ctx) = 1;
347 } else
348 SECCOMP_PARM4(ctx) = 0;
349 #endif
350 SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val);
351 }
352
353 #if defined(__mips__)
354 intptr_t Syscall::SandboxSyscallRaw(int nr,
355 const intptr_t* args,
356 intptr_t* err_ret) {
357 register intptr_t ret __asm__("v0") = nr;
358 // a3 register becomes non zero on error.
359 register intptr_t err_stat __asm__("a3") = 0;
360 {
361 register const intptr_t* data __asm__("a0") = args;
362 asm volatile(
363 "la $t9, SyscallAsm\n"
364 "jalr $t9\n"
365 " nop\n"
366 : "=r"(ret), "=r"(err_stat)
367 : "0"(ret),
368 "r"(data)
369 // a2 is in the clober list so inline assembly can not change its
370 // value.
371 : "memory", "ra", "t9", "a2");
372 }
373
374 // Set an error status so it can be used outside of this function
375 *err_ret = err_stat;
376
377 return ret;
378 }
379 #endif // defined(__mips__)
380
277 } // namespace sandbox 381 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/syscall.h ('k') | sandbox/linux/seccomp-bpf/syscall_iterator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698