| 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 |