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

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, 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
5 #include "sandbox/linux/seccomp-bpf/syscall.h" 4 #include "sandbox/linux/seccomp-bpf/syscall.h"
6 5
7 #include <asm/unistd.h> 6 #include <asm/unistd.h>
8 #include <errno.h> 7 #include <errno.h>
9 8
10 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
11 11
12 namespace sandbox { 12 namespace sandbox {
13 13
14 namespace { 14 namespace {
15 15
16 asm(// We need to be able to tell the kernel exactly where we made a 16 asm(// We need to be able to tell the kernel exactly where we made a
17 // system call. The C++ compiler likes to sometimes clone or 17 // system call. The C++ compiler likes to sometimes clone or
18 // inline code, which would inadvertently end up duplicating 18 // inline code, which would inadvertently end up duplicating
19 // the entry point. 19 // the entry point.
20 // "gcc" can suppress code duplication with suitable function 20 // "gcc" can suppress code duplication with suitable function
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // Restore the frame pointer. Also restore the program counter from 163 // Restore the frame pointer. Also restore the program counter from
164 // the link register; this makes us return to the caller. 164 // the link register; this makes us return to the caller.
165 #if defined(__thumb__) 165 #if defined(__thumb__)
166 "2:pop {r7, pc}\n" 166 "2:pop {r7, pc}\n"
167 ".cfi_endproc\n" 167 ".cfi_endproc\n"
168 #else 168 #else
169 "2:ldmfd sp!, {fp, pc}\n" 169 "2:ldmfd sp!, {fp, pc}\n"
170 #endif 170 #endif
171 ".fnend\n" 171 ".fnend\n"
172 "9:.size SyscallAsm, 9b-SyscallAsm\n" 172 "9:.size SyscallAsm, 9b-SyscallAsm\n"
173 #elif defined(__mips__)
174 ".text\n"
175 ".align 4\n"
176 ".type SyscallAsm, @function\n"
177 "SyscallAsm:.ent SyscallAsm\n"
178 ".frame $sp, 32, $ra\n"
179 ".set push\n"
180 ".set noreorder\n"
181 "addiu $sp, $sp, -32\n"
182 "sw $ra, 28($sp)\n"
183 // Check if "v0" is negative. If so, do not attempt to make a
184 // system call. Instead, compute the return address that is visible
185 // to the kernel after we execute "syscall". This address can be
186 // used as a marker that BPF code inspects.
187 "bgez $v0, 1f\n"
188 " nop\n"
189 "la $v0, 2f\n"
190 "b 2f\n"
191 " nop\n"
192 // On MIPS first four arguments go to registers a0 - a3 and any
193 // argument after that goes to stack. We can go ahead and directly
194 // copy the entries from the arguments array into the appropriate
195 // CPU registers and on the stack.
196 "1:lw $t0, 20($a0)\n"
197 "sw $t0, 20($sp)\n"
198 "lw $t0, 16($a0)\n"
199 "sw $t0, 16($sp)\n"
200 "lw $a3, 12($a0)\n"
201 "lw $a2, 8($a0)\n"
202 "lw $a1, 4($a0)\n"
203 "lw $a0, 0($a0)\n"
204 // Enter the kernel
205 "syscall\n"
206 // This is our "magic" return address that the BPF filter sees.
207 // Restore the return address from the stack.
208 "2:lw $ra, 28($sp)\n"
209 "jr $ra\n"
210 " addiu $sp, $sp, 32\n"
211 ".set pop\n"
212 ".end SyscallAsm\n"
213 ".size SyscallAsm,.-SyscallAsm\n"
173 #endif 214 #endif
174 ); // asm 215 ); // asm
175 216
176 } // namespace 217 } // namespace
177 218
178 intptr_t Syscall::Call(int nr, 219 intptr_t Syscall::Call(int nr,
179 intptr_t p0, 220 intptr_t p0,
180 intptr_t p1, 221 intptr_t p1,
181 intptr_t p2, 222 intptr_t p2,
182 intptr_t p3, 223 intptr_t p3,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 // it. 293 // it.
253 // In ARM mode, we have a dedicated frame pointer register and "r7" is 294 // In ARM mode, we have a dedicated frame pointer register and "r7" is
254 // thus available as a general purpose register. We don't preserve it, 295 // thus available as a general purpose register. We don't preserve it,
255 // but instead mark it as clobbered. 296 // but instead mark it as clobbered.
256 , 297 ,
257 "r7" 298 "r7"
258 #endif // !defined(__thumb__) 299 #endif // !defined(__thumb__)
259 ); 300 );
260 ret = inout; 301 ret = inout;
261 } 302 }
303 #elif defined(__mips__)
304 int err_status;
305 intptr_t ret = SandboxSyscallRaw(nr, args, &err_status);
306
307 if (err_status) {
308 // On error, MIPS returns errno from syscall instead of -errno.
309 // The purpose of this negation is for SandboxSyscall() to behave
310 // more like it would on other architectures.
311 ret = -ret;
312 }
262 #else 313 #else
263 #error "Unimplemented architecture" 314 #error "Unimplemented architecture"
264 #endif 315 #endif
265 return ret; 316 return ret;
266 } 317 }
267 318
319 void Syscall::PutValueInUcontext(intptr_t ret_val, ucontext_t* ctx) {
320 #if defined(__mips__)
321 // Mips ABI states that on error a3 CPU register has non zero value and if
322 // there is no error, it should be zero.
323 if (ret_val <= -1 && ret_val >= -4095) {
324 // |ret_val| followes the Syscall::Call() convention of being -errno on
325 // errors. In order to write correct value to return register this sign
326 // needs to be changed back.
327 ret_val = -ret_val;
328 SECCOMP_PARM4(ctx) = 1;
329 } else
330 SECCOMP_PARM4(ctx) = 0;
331 #endif
332 SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val);
333 }
334
335 #if defined(__mips__)
336 intptr_t SandboxSyscallRaw(int nr, const intptr_t* args, intptr_t* err_ret) {
337 register intptr_t ret __asm__("v0") = nr;
338 // a3 register becomes non zero on error.
339 register intptr_t err_stat __asm__("a3") = 0;
340 {
341 register const intptr_t* data __asm__("a0") = args;
342 asm volatile(
343 "la $t9, SyscallAsm\n"
344 "jalr $t9\n"
345 " nop\n"
346 : "=r"(ret), "=r"(err_stat)
347 : "0"(ret),
348 "r"(data)
349 // a2 is in the clober list so inline assembly can not change its
350 // value.
351 : "memory", "ra", "t9", "a2");
352 }
353
354 // Set an error status so it can be used outside of this function
355 *err_ret = err_stat;
356
357 return ret;
358 }
359 #endif // defined(__mips__)
360
268 } // namespace sandbox 361 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698