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/syscall.h" | 5 #include "sandbox/linux/seccomp-bpf/syscall.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 "2:ldmfd sp!, {fp, pc}\n" | 183 "2:ldmfd sp!, {fp, pc}\n" |
184 #endif | 184 #endif |
185 #if !defined(__native_client_nonsfi__) | 185 #if !defined(__native_client_nonsfi__) |
186 // Do not use .fnstart and .fnend for PNaCl toolchain. See above comment, | 186 // Do not use .fnstart and .fnend for PNaCl toolchain. See above comment, |
187 // for more details. | 187 // for more details. |
188 ".fnend\n" | 188 ".fnend\n" |
189 #endif | 189 #endif |
190 "9:.size SyscallAsm, 9b-SyscallAsm\n" | 190 "9:.size SyscallAsm, 9b-SyscallAsm\n" |
191 #elif defined(__mips__) | 191 #elif defined(__mips__) |
192 ".text\n" | 192 ".text\n" |
193 ".option pic2\n" | |
193 ".align 4\n" | 194 ".align 4\n" |
195 ".global SyscallAsm\n" | |
194 ".type SyscallAsm, @function\n" | 196 ".type SyscallAsm, @function\n" |
195 "SyscallAsm:.ent SyscallAsm\n" | 197 "SyscallAsm:.ent SyscallAsm\n" |
196 ".frame $sp, 40, $ra\n" | 198 ".frame $sp, 40, $ra\n" |
197 ".set push\n" | 199 ".set push\n" |
198 ".set noreorder\n" | 200 ".set noreorder\n" |
201 ".cpload $t9\n" | |
199 "addiu $sp, $sp, -40\n" | 202 "addiu $sp, $sp, -40\n" |
200 "sw $ra, 36($sp)\n" | 203 "sw $ra, 36($sp)\n" |
201 // Check if "v0" is negative. If so, do not attempt to make a | 204 // Check if "v0" is negative. If so, do not attempt to make a |
202 // system call. Instead, compute the return address that is visible | 205 // system call. Instead, compute the return address that is visible |
203 // to the kernel after we execute "syscall". This address can be | 206 // to the kernel after we execute "syscall". This address can be |
204 // used as a marker that BPF code inspects. | 207 // used as a marker that BPF code inspects. |
205 "bgez $v0, 1f\n" | 208 "bgez $v0, 1f\n" |
206 " nop\n" | 209 " nop\n" |
207 "la $v0, 2f\n" | 210 "lw $v0, %got(2f)($gp)\n" |
mdempsky
2016/04/28 16:02:13
Please add a comment so someone doesn't come along
lmilko
2016/05/04 15:13:05
Done.
| |
211 "addiu $v0, $v0, %lo(2f)\n" | |
208 "b 2f\n" | 212 "b 2f\n" |
209 " nop\n" | 213 " nop\n" |
210 // On MIPS first four arguments go to registers a0 - a3 and any | 214 // On MIPS first four arguments go to registers a0 - a3 and any |
211 // argument after that goes to stack. We can go ahead and directly | 215 // argument after that goes to stack. We can go ahead and directly |
212 // copy the entries from the arguments array into the appropriate | 216 // copy the entries from the arguments array into the appropriate |
213 // CPU registers and on the stack. | 217 // CPU registers and on the stack. |
214 "1:lw $a3, 28($a0)\n" | 218 "1:lw $a3, 28($a0)\n" |
215 "lw $a2, 24($a0)\n" | 219 "lw $a2, 24($a0)\n" |
216 "lw $a1, 20($a0)\n" | 220 "lw $a1, 20($a0)\n" |
217 "lw $t0, 16($a0)\n" | 221 "lw $t0, 16($a0)\n" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 "2:ret\n" | 259 "2:ret\n" |
256 ".cfi_endproc\n" | 260 ".cfi_endproc\n" |
257 ".size SyscallAsm, .-SyscallAsm\n" | 261 ".size SyscallAsm, .-SyscallAsm\n" |
258 #endif | 262 #endif |
259 ); // asm | 263 ); // asm |
260 | 264 |
261 #if defined(__x86_64__) | 265 #if defined(__x86_64__) |
262 extern "C" { | 266 extern "C" { |
263 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[6]); | 267 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[6]); |
264 } | 268 } |
269 #elif defined(__mips__) | |
270 extern "C" { | |
271 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[8]); | |
272 } | |
265 #endif | 273 #endif |
266 | 274 |
267 } // namespace | 275 } // namespace |
268 | 276 |
269 intptr_t Syscall::InvalidCall() { | 277 intptr_t Syscall::InvalidCall() { |
270 // Explicitly pass eight zero arguments just in case. | 278 // Explicitly pass eight zero arguments just in case. |
271 return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); | 279 return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); |
272 } | 280 } |
273 | 281 |
274 intptr_t Syscall::Call(int nr, | 282 intptr_t Syscall::Call(int nr, |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 SECCOMP_PARM4(ctx) = 0; | 396 SECCOMP_PARM4(ctx) = 0; |
389 #endif | 397 #endif |
390 SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val); | 398 SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val); |
391 } | 399 } |
392 | 400 |
393 #if defined(__mips__) | 401 #if defined(__mips__) |
394 intptr_t Syscall::SandboxSyscallRaw(int nr, | 402 intptr_t Syscall::SandboxSyscallRaw(int nr, |
395 const intptr_t* args, | 403 const intptr_t* args, |
396 intptr_t* err_ret) { | 404 intptr_t* err_ret) { |
397 register intptr_t ret __asm__("v0") = nr; | 405 register intptr_t ret __asm__("v0") = nr; |
406 register intptr_t syscallasm __asm__("t9") = (intptr_t) &SyscallAsm; | |
398 // a3 register becomes non zero on error. | 407 // a3 register becomes non zero on error. |
399 register intptr_t err_stat __asm__("a3") = 0; | 408 register intptr_t err_stat __asm__("a3") = 0; |
400 { | 409 { |
401 register const intptr_t* data __asm__("a0") = args; | 410 register const intptr_t* data __asm__("a0") = args; |
402 asm volatile( | 411 asm volatile( |
403 "la $t9, SyscallAsm\n" | |
404 "jalr $t9\n" | 412 "jalr $t9\n" |
405 " nop\n" | 413 " nop\n" |
406 : "=r"(ret), "=r"(err_stat) | 414 : "=r"(ret), "=r"(err_stat) |
407 : "0"(ret), | 415 : "0"(ret), |
408 "r"(data) | 416 "r"(data), |
417 "r"(syscallasm) | |
409 // a2 is in the clober list so inline assembly can not change its | 418 // a2 is in the clober list so inline assembly can not change its |
410 // value. | 419 // value. |
411 : "memory", "ra", "t9", "a2"); | 420 : "memory", "ra", "a2"); |
412 } | 421 } |
413 | 422 |
414 // Set an error status so it can be used outside of this function | 423 // Set an error status so it can be used outside of this function |
415 *err_ret = err_stat; | 424 *err_ret = err_stat; |
416 | 425 |
417 return ret; | 426 return ret; |
418 } | 427 } |
419 #endif // defined(__mips__) | 428 #endif // defined(__mips__) |
420 | 429 |
421 } // namespace sandbox | 430 } // namespace sandbox |
OLD | NEW |