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 |