| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "debug.h" | |
| 6 #include "mutex.h" | |
| 7 #include "sandbox_impl.h" | |
| 8 #include "securemem.h" | |
| 9 | |
| 10 namespace playground { | |
| 11 | |
| 12 void SecureMem::abandonSystemCall(int fd, int err) { | |
| 13 void* rc = reinterpret_cast<void *>(err); | |
| 14 if (err) { | |
| 15 Debug::message("System call failed\n"); | |
| 16 } | |
| 17 Sandbox::SysCalls sys; | |
| 18 if (Sandbox::write(sys, fd, &rc, sizeof(rc)) != sizeof(rc)) { | |
| 19 Sandbox::die("Failed to send system call"); | |
| 20 } | |
| 21 } | |
| 22 | |
| 23 void SecureMem::dieIfParentDied(int parentMapsFd) { | |
| 24 // The syscall_mutex_ should not be contended. If it is, we are either | |
| 25 // experiencing a very unusual load of system calls that the sandbox is not | |
| 26 // optimized for; or, more likely, the sandboxed process terminated while the | |
| 27 // trusted process was in the middle of waiting for the mutex. We detect | |
| 28 // this situation and terminate the trusted process. | |
| 29 int alive = !lseek(parentMapsFd, 0, SEEK_SET); | |
| 30 if (alive) { | |
| 31 char buf; | |
| 32 do { | |
| 33 alive = read(parentMapsFd, &buf, 1); | |
| 34 } while (alive < 0 && errno == EINTR); | |
| 35 } | |
| 36 if (!alive) { | |
| 37 Sandbox::die(); | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 void SecureMem::lockSystemCall(int parentMapsFd, Args* mem) { | |
| 42 while (!Mutex::lockMutex(&Sandbox::syscall_mutex_, 500)) { | |
| 43 dieIfParentDied(parentMapsFd); | |
| 44 } | |
| 45 asm volatile( | |
| 46 #if defined(__x86_64__) | |
| 47 "lock; incq (%0)\n" | |
| 48 #elif defined(__i386__) | |
| 49 "lock; incl (%0)\n" | |
| 50 #else | |
| 51 #error Unsupported target platform | |
| 52 #endif | |
| 53 : | |
| 54 : "q"(&mem->sequence) | |
| 55 : "memory"); | |
| 56 } | |
| 57 | |
| 58 void SecureMem::sendSystemCallInternal(int fd, bool locked, int parentMapsFd, | |
| 59 Args* mem, int syscallNum, void* arg1, | |
| 60 void* arg2, void* arg3, void* arg4, | |
| 61 void* arg5, void* arg6) { | |
| 62 if (!locked) { | |
| 63 asm volatile( | |
| 64 #if defined(__x86_64__) | |
| 65 "lock; incq (%0)\n" | |
| 66 #elif defined(__i386__) | |
| 67 "lock; incl (%0)\n" | |
| 68 #else | |
| 69 #error Unsupported target platform | |
| 70 #endif | |
| 71 : | |
| 72 : "q"(&mem->sequence) | |
| 73 : "memory"); | |
| 74 } | |
| 75 mem->callType = locked ? -2 : -1; | |
| 76 mem->syscallNum = syscallNum; | |
| 77 mem->arg1 = arg1; | |
| 78 mem->arg2 = arg2; | |
| 79 mem->arg3 = arg3; | |
| 80 mem->arg4 = arg4; | |
| 81 mem->arg5 = arg5; | |
| 82 mem->arg6 = arg6; | |
| 83 asm volatile( | |
| 84 #if defined(__x86_64__) | |
| 85 "lock; incq (%0)\n" | |
| 86 #elif defined(__i386__) | |
| 87 "lock; incl (%0)\n" | |
| 88 #else | |
| 89 #error Unsupported target platform | |
| 90 #endif | |
| 91 : | |
| 92 : "q"(&mem->sequence) | |
| 93 : "memory"); | |
| 94 Sandbox::SysCalls sys; | |
| 95 if (Sandbox::write(sys, fd, &mem->callType, sizeof(int)) != sizeof(int)) { | |
| 96 Sandbox::die("Failed to send system call"); | |
| 97 } | |
| 98 if (parentMapsFd >= 0) { | |
| 99 while (!Mutex::waitForUnlock(&Sandbox::syscall_mutex_, 500)) { | |
| 100 dieIfParentDied(parentMapsFd); | |
| 101 } | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 } // namespace | |
| OLD | NEW |