OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 | 7 |
8 // NaCl inter-module communication primitives. | 8 // NaCl inter-module communication primitives. |
9 | 9 |
10 #ifndef NOMINMAX | 10 #ifndef NOMINMAX |
11 #define NOMINMAX // Disables the generation of the min and max macro in | 11 #define NOMINMAX // Disables the generation of the min and max macro in |
12 // <windows.h>. | 12 // <windows.h>. |
13 #endif | 13 #endif |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <ctype.h> | 16 #include <ctype.h> |
17 #include <limits.h> | 17 #include <limits.h> |
18 #include <stdio.h> | 18 #include <stdio.h> |
19 #include <string> | 19 #include <string> |
20 #include <windows.h> | 20 #include <windows.h> |
21 #include <sys/types.h> | 21 #include <sys/types.h> |
22 | 22 |
23 #include "native_client/src/include/atomic_ops.h" | 23 #include "native_client/src/include/atomic_ops.h" |
24 #include "native_client/src/include/portability.h" | 24 #include "native_client/src/include/portability.h" |
25 #include "native_client/src/shared/imc/nacl_imc.h" | 25 #include "native_client/src/shared/imc/nacl_imc.h" |
26 #include "native_client/src/shared/imc/nacl_imc_c.h" | 26 #include "native_client/src/shared/imc/nacl_imc_c.h" |
27 #include "native_client/src/trusted/handle_pass/handle_lookup.h" | 27 #include "native_client/src/trusted/handle_pass/handle_lookup.h" |
28 | 28 |
29 // Duplicate a Windows HANDLE. | 29 |
| 30 namespace { |
| 31 NaClBrokerDuplicateHandleFunc g_broker_duplicate_handle_func; |
| 32 } |
| 33 |
| 34 void NaClSetBrokerDuplicateHandleFunc(NaClBrokerDuplicateHandleFunc func) { |
| 35 g_broker_duplicate_handle_func = func; |
| 36 } |
| 37 |
| 38 // Duplicate a Windows HANDLE within the current process. |
30 NaClHandle NaClDuplicateNaClHandle(NaClHandle handle) { | 39 NaClHandle NaClDuplicateNaClHandle(NaClHandle handle) { |
31 NaClHandle dup_handle; | 40 NaClHandle dup_handle; |
32 if (DuplicateHandle(GetCurrentProcess(), | 41 if (DuplicateHandle(GetCurrentProcess(), |
33 handle, | 42 handle, |
34 GetCurrentProcess(), | 43 GetCurrentProcess(), |
35 &dup_handle, | 44 &dup_handle, |
36 0, | 45 0, |
37 FALSE, | 46 FALSE, |
38 DUPLICATE_SAME_ACCESS)) { | 47 DUPLICATE_SAME_ACCESS)) { |
39 return dup_handle; | 48 return dup_handle; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 265 } |
257 if (0 < message->handle_count && message->handles) { | 266 if (0 < message->handle_count && message->handles) { |
258 // TODO(shiki): On Windows Vista, we can use GetNamedPipeClientProcessId() | 267 // TODO(shiki): On Windows Vista, we can use GetNamedPipeClientProcessId() |
259 // and GetNamedPipeServerProcessId() and probably we can remove | 268 // and GetNamedPipeServerProcessId() and probably we can remove |
260 // kEchoRequest and kEchoResponse completely. | 269 // kEchoRequest and kEchoResponse completely. |
261 if (WriteAll(handle, &header, sizeof header) != sizeof header || | 270 if (WriteAll(handle, &header, sizeof header) != sizeof header || |
262 ReadAll(handle, &header, sizeof header) != sizeof header || | 271 ReadAll(handle, &header, sizeof header) != sizeof header || |
263 header.command != kEchoResponse) { | 272 header.command != kEchoResponse) { |
264 return -1; | 273 return -1; |
265 } | 274 } |
| 275 HANDLE target; |
| 276 if (g_broker_duplicate_handle_func == NULL) { |
| 277 // TODO(mseaborn): Remove these non-NACL_STANDALONE cases. |
| 278 // Chromium is being changed to supply g_broker_duplicate_handle_func. |
266 #ifdef NACL_STANDALONE // not in Chrome | 279 #ifdef NACL_STANDALONE // not in Chrome |
267 HANDLE target = OpenProcess(PROCESS_DUP_HANDLE, FALSE, header.pid); | 280 target = OpenProcess(PROCESS_DUP_HANDLE, FALSE, header.pid); |
268 #else | 281 #else |
269 HANDLE target = NaClHandlePassLookupHandle(header.pid); | 282 target = NaClHandlePassLookupHandle(header.pid); |
270 #endif | 283 #endif |
271 if (target == NULL) { | 284 if (target == NULL) { |
272 return -1; | 285 return -1; |
| 286 } |
273 } | 287 } |
274 for (uint32_t i = 0; i < message->handle_count; ++i) { | 288 for (uint32_t i = 0; i < message->handle_count; ++i) { |
275 HANDLE temp_remote_handle; | 289 HANDLE temp_remote_handle; |
276 if (DuplicateHandle(GetCurrentProcess(), message->handles[i], | 290 bool success; |
277 target, &temp_remote_handle, | 291 if (g_broker_duplicate_handle_func != NULL) { |
278 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) { | 292 success = g_broker_duplicate_handle_func(message->handles[i], |
| 293 header.pid, |
| 294 &temp_remote_handle, |
| 295 0, DUPLICATE_SAME_ACCESS); |
| 296 } else { |
| 297 success = DuplicateHandle(GetCurrentProcess(), message->handles[i], |
| 298 target, &temp_remote_handle, |
| 299 0, FALSE, DUPLICATE_SAME_ACCESS); |
| 300 } |
| 301 if (!success) { |
279 // Send the kCancel message to revoke the handles duplicated | 302 // Send the kCancel message to revoke the handles duplicated |
280 // so far in the remote peer. | 303 // so far in the remote peer. |
281 header.command = kCancel; | 304 header.command = kCancel; |
282 header.handle_count = i; | 305 header.handle_count = i; |
283 if (0 < i) { | 306 if (0 < i) { |
284 WriteAll(handle, &header, sizeof header); | 307 WriteAll(handle, &header, sizeof header); |
285 WriteAll(handle, remote_handles, sizeof(uint64_t) * i); | 308 WriteAll(handle, remote_handles, sizeof(uint64_t) * i); |
286 } | 309 } |
| 310 if (g_broker_duplicate_handle_func == NULL) { |
287 #ifdef NACL_STANDALONE | 311 #ifdef NACL_STANDALONE |
288 CloseHandle(target); | 312 CloseHandle(target); |
289 #endif | 313 #endif |
| 314 } |
290 return -1; | 315 return -1; |
291 } | 316 } |
292 remote_handles[i] = reinterpret_cast<uint64_t>(temp_remote_handle); | 317 remote_handles[i] = reinterpret_cast<uint64_t>(temp_remote_handle); |
293 } | 318 } |
| 319 if (g_broker_duplicate_handle_func == NULL) { |
294 #ifdef NACL_STANDALONE | 320 #ifdef NACL_STANDALONE |
295 CloseHandle(target); | 321 CloseHandle(target); |
296 #endif | 322 #endif |
| 323 } |
297 } | 324 } |
298 header.command = kMessage; | 325 header.command = kMessage; |
299 header.handle_count = message->handle_count; | 326 header.handle_count = message->handle_count; |
300 for (uint32_t i = 0; i < message->iov_length; ++i) { | 327 for (uint32_t i = 0; i < message->iov_length; ++i) { |
301 if (UINT32_MAX - header.message_length < message->iov[i].length) { | 328 if (UINT32_MAX - header.message_length < message->iov[i].length) { |
302 return -1; | 329 return -1; |
303 } | 330 } |
304 header.message_length += static_cast<uint32_t>(message->iov[i].length); | 331 header.message_length += static_cast<uint32_t>(message->iov[i].length); |
305 } | 332 } |
306 if (WriteAll(handle, &header, sizeof header) != sizeof header) { | 333 if (WriteAll(handle, &header, sizeof header) != sizeof header) { |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 break; | 608 break; |
582 } | 609 } |
583 default: | 610 default: |
584 return -1; | 611 return -1; |
585 break; | 612 break; |
586 } | 613 } |
587 } | 614 } |
588 } | 615 } |
589 | 616 |
590 } // namespace nacl | 617 } // namespace nacl |
OLD | NEW |