Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(529)

Side by Side Diff: ipc/attachment_broker_privileged_win_unittest.cc

Issue 1493413004: ipc: Allow attachment brokering for shared memory handles. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@temp1
Patch Set: Fix more tests. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h" 11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/shared_memory.h"
14 #include "base/memory/shared_memory_handle.h"
15 #include "base/win/scoped_handle.h"
13 #include "ipc/attachment_broker_privileged_win.h" 16 #include "ipc/attachment_broker_privileged_win.h"
14 #include "ipc/attachment_broker_unprivileged_win.h" 17 #include "ipc/attachment_broker_unprivileged_win.h"
15 #include "ipc/handle_attachment_win.h" 18 #include "ipc/handle_attachment_win.h"
16 #include "ipc/handle_win.h" 19 #include "ipc/handle_win.h"
17 #include "ipc/ipc_listener.h" 20 #include "ipc/ipc_listener.h"
18 #include "ipc/ipc_message.h" 21 #include "ipc/ipc_message.h"
19 #include "ipc/ipc_test_base.h" 22 #include "ipc/ipc_test_base.h"
20 #include "ipc/ipc_test_messages.h" 23 #include "ipc/ipc_test_messages.h"
21 24
22 namespace { 25 namespace {
23 26
27 using base::win::ScopedHandle;
28
24 const char kDataBuffer[] = "This is some test data to write to the file."; 29 const char kDataBuffer[] = "This is some test data to write to the file.";
30 const size_t kSharedMemorySize = 20000;
25 31
26 // Returns the contents of the file represented by |h| as a std::string. 32 // Returns the contents of the file represented by |h| as a std::string.
27 std::string ReadFromFile(HANDLE h) { 33 std::string ReadFromFile(HANDLE h) {
28 SetFilePointer(h, 0, nullptr, FILE_BEGIN); 34 SetFilePointer(h, 0, nullptr, FILE_BEGIN);
29 char buffer[100]; 35 char buffer[100];
30 DWORD bytes_read; 36 DWORD bytes_read;
31 BOOL success = ::ReadFile(h, buffer, static_cast<DWORD>(strlen(kDataBuffer)), 37 BOOL success = ::ReadFile(h, buffer, static_cast<DWORD>(strlen(kDataBuffer)),
32 &bytes_read, nullptr); 38 &bytes_read, nullptr);
33 return success ? std::string(buffer, bytes_read) : std::string(); 39 return success ? std::string(buffer, bytes_read) : std::string();
34 } 40 }
35 41
36 HANDLE GetHandleFromBrokeredAttachment( 42 ScopedHandle GetHandleFromBrokeredAttachment(
37 const scoped_refptr<IPC::BrokerableAttachment>& attachment) { 43 const scoped_refptr<IPC::BrokerableAttachment>& attachment) {
38 if (attachment->GetType() != 44 if (attachment->GetType() !=
39 IPC::BrokerableAttachment::TYPE_BROKERABLE_ATTACHMENT) { 45 IPC::BrokerableAttachment::TYPE_BROKERABLE_ATTACHMENT) {
40 LOG(INFO) << "Attachment type not TYPE_BROKERABLE_ATTACHMENT."; 46 LOG(INFO) << "Attachment type not TYPE_BROKERABLE_ATTACHMENT.";
41 return nullptr; 47 return ScopedHandle(nullptr);
42 } 48 }
43 49
44 if (attachment->GetBrokerableType() != 50 if (attachment->GetBrokerableType() !=
45 IPC::BrokerableAttachment::WIN_HANDLE) { 51 IPC::BrokerableAttachment::WIN_HANDLE) {
46 LOG(INFO) << "Brokerable type not WIN_HANDLE."; 52 LOG(INFO) << "Brokerable type not WIN_HANDLE.";
47 return nullptr; 53 return ScopedHandle(nullptr);
48 } 54 }
49 55
50 IPC::internal::HandleAttachmentWin* received_handle_attachment = 56 IPC::internal::HandleAttachmentWin* received_handle_attachment =
51 static_cast<IPC::internal::HandleAttachmentWin*>(attachment.get()); 57 static_cast<IPC::internal::HandleAttachmentWin*>(attachment.get());
52 return received_handle_attachment->get_handle(); 58 ScopedHandle h(received_handle_attachment->get_handle());
59 received_handle_attachment->reset_handle_ownership();
60 return h;
53 } 61 }
54 62
55 // |message| must be deserializable as a TestHandleWinMsg. Returns the HANDLE, 63 // |message| must be deserializable as a TestHandleWinMsg. Returns the HANDLE,
56 // or nullptr if deserialization failed. 64 // or nullptr if deserialization failed.
57 HANDLE GetHandleFromTestHandleWinMsg(const IPC::Message& message) { 65 ScopedHandle GetHandleFromTestHandleWinMsg(const IPC::Message& message) {
66 // Expect a message with a brokered attachment.
67 if (!message.HasBrokerableAttachments()) {
68 LOG(INFO) << "Message missing brokerable attachment.";
69 return ScopedHandle(nullptr);
70 }
71
72 TestHandleWinMsg::Schema::Param p;
73 bool success = TestHandleWinMsg::Read(&message, &p);
74 if (!success) {
75 LOG(INFO) << "Failed to deserialize message.";
76 return ScopedHandle(nullptr);
77 }
78
79 IPC::HandleWin handle_win = base::get<1>(p);
80 return ScopedHandle(handle_win.get_handle());
81 }
82
83 // Returns a mapped, shared memory region based on the handle in |message|.
84 scoped_ptr<base::SharedMemory> GetSharedMemoryFromSharedMemoryHandleMsg1(
85 const IPC::Message& message,
86 size_t size) {
58 // Expect a message with a brokered attachment. 87 // Expect a message with a brokered attachment.
59 if (!message.HasBrokerableAttachments()) { 88 if (!message.HasBrokerableAttachments()) {
60 LOG(INFO) << "Message missing brokerable attachment."; 89 LOG(INFO) << "Message missing brokerable attachment.";
61 return nullptr; 90 return nullptr;
62 } 91 }
63 92
64 TestHandleWinMsg::Schema::Param p; 93 TestSharedMemoryHandleMsg1::Schema::Param p;
65 bool success = TestHandleWinMsg::Read(&message, &p); 94 bool success = TestSharedMemoryHandleMsg1::Read(&message, &p);
66 if (!success) { 95 if (!success) {
67 LOG(INFO) << "Failed to deserialize message."; 96 LOG(INFO) << "Failed to deserialize message.";
68 return nullptr; 97 return nullptr;
69 } 98 }
70 99
71 IPC::HandleWin handle_win = base::get<1>(p); 100 base::SharedMemoryHandle handle = base::get<0>(p);
72 return handle_win.get_handle(); 101 scoped_ptr<base::SharedMemory> shared_memory(
102 new base::SharedMemory(handle, false));
103
104 shared_memory->Map(size);
105 return std::move(shared_memory);
73 } 106 }
74 107
75 // |message| must be deserializable as a TestTwoHandleWinMsg. Returns the 108 // |message| must be deserializable as a TestTwoHandleWinMsg. Returns the
76 // HANDLE, or nullptr if deserialization failed. 109 // HANDLE, or nullptr if deserialization failed.
77 HANDLE GetHandleFromTestTwoHandleWinMsg(const IPC::Message& message, 110 bool GetHandleFromTestTwoHandleWinMsg(const IPC::Message& message,
78 int index) { 111 HANDLE* h1,
112 HANDLE* h2) {
79 // Expect a message with a brokered attachment. 113 // Expect a message with a brokered attachment.
80 if (!message.HasBrokerableAttachments()) { 114 if (!message.HasBrokerableAttachments()) {
81 LOG(INFO) << "Message missing brokerable attachment."; 115 LOG(INFO) << "Message missing brokerable attachment.";
82 return nullptr; 116 return false;
83 } 117 }
84 118
85 TestTwoHandleWinMsg::Schema::Param p; 119 TestTwoHandleWinMsg::Schema::Param p;
86 bool success = TestTwoHandleWinMsg::Read(&message, &p); 120 bool success = TestTwoHandleWinMsg::Read(&message, &p);
87 if (!success) { 121 if (!success) {
88 LOG(INFO) << "Failed to deserialize message."; 122 LOG(INFO) << "Failed to deserialize message.";
89 return nullptr; 123 return false;
90 } 124 }
91 125
92 IPC::HandleWin handle_win; 126 IPC::HandleWin handle_win = base::get<0>(p);
93 if (index == 0) 127 *h1 = handle_win.get_handle();
94 handle_win = base::get<0>(p); 128 handle_win = base::get<1>(p);
95 else if (index == 1) 129 *h2 = handle_win.get_handle();
96 handle_win = base::get<1>(p); 130 return true;
97 return handle_win.get_handle();
98 } 131 }
99 132
100 // |message| must be deserializable as a TestHandleWinMsg. Returns true if the 133 // |message| must be deserializable as a TestHandleWinMsg. Returns true if the
101 // attached file HANDLE has contents |kDataBuffer|. 134 // attached file HANDLE has contents |kDataBuffer|.
102 bool CheckContentsOfTestMessage(const IPC::Message& message) { 135 bool CheckContentsOfTestMessage(const IPC::Message& message) {
103 HANDLE h = GetHandleFromTestHandleWinMsg(message); 136 ScopedHandle h(GetHandleFromTestHandleWinMsg(message));
104 if (h == nullptr) { 137 if (h.Get() == nullptr) {
105 LOG(INFO) << "Failed to get handle from TestHandleWinMsg."; 138 LOG(INFO) << "Failed to get handle from TestHandleWinMsg.";
106 return false; 139 return false;
107 } 140 }
108 141
109 std::string contents = ReadFromFile(h); 142 std::string contents = ReadFromFile(h.Get());
110 bool success = (contents == std::string(kDataBuffer)); 143 bool success = (contents == std::string(kDataBuffer));
111 if (!success) { 144 if (!success) {
112 LOG(INFO) << "Expected contents: " << std::string(kDataBuffer); 145 LOG(INFO) << "Expected contents: " << std::string(kDataBuffer);
113 LOG(INFO) << "Read contents: " << contents; 146 LOG(INFO) << "Read contents: " << contents;
114 } 147 }
115 return success; 148 return success;
116 } 149 }
117 150
118 // Returns 0 on error. 151 // Returns 0 on error.
119 DWORD GetCurrentProcessHandleCount() { 152 DWORD GetCurrentProcessHandleCount() {
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 HANDLE h = CreateTempFile(); 397 HANDLE h = CreateTempFile();
365 SendMessageWithAttachment(h); 398 SendMessageWithAttachment(h);
366 base::MessageLoop::current()->Run(); 399 base::MessageLoop::current()->Run();
367 400
368 // Get the received attachment. 401 // Get the received attachment.
369 IPC::BrokerableAttachment::AttachmentId* id = get_observer()->get_id(); 402 IPC::BrokerableAttachment::AttachmentId* id = get_observer()->get_id();
370 scoped_refptr<IPC::BrokerableAttachment> received_attachment; 403 scoped_refptr<IPC::BrokerableAttachment> received_attachment;
371 get_broker()->GetAttachmentWithId(*id, &received_attachment); 404 get_broker()->GetAttachmentWithId(*id, &received_attachment);
372 ASSERT_NE(received_attachment.get(), nullptr); 405 ASSERT_NE(received_attachment.get(), nullptr);
373 406
374 // Check that it's the same entry in the HANDLE table. 407 // Check that it's a different entry in the HANDLE table.
375 HANDLE h2 = GetHandleFromBrokeredAttachment(received_attachment); 408 ScopedHandle h2(GetHandleFromBrokeredAttachment(received_attachment));
376 EXPECT_EQ(h2, h); 409 EXPECT_NE(h2.Get(), h);
377 410
378 // And still points to the same file. 411 // But still points to the same file.
379 std::string contents = ReadFromFile(h); 412 std::string contents = ReadFromFile(h2.Get());
380 EXPECT_EQ(contents, std::string(kDataBuffer)); 413 EXPECT_EQ(contents, std::string(kDataBuffer));
381 414
382 CommonTearDown(); 415 CommonTearDown();
383 } 416 }
384 417
385 // Similar to SendHandle, but sends a message with two instances of the same 418 // Similar to SendHandle, but sends a message with two instances of the same
386 // handle. 419 // handle.
387 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendTwoHandles) { 420 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendTwoHandles) {
388 Init("SendTwoHandles"); 421 Init("SendTwoHandles");
389 422
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 base::MessageLoop::current()->Run(); 461 base::MessageLoop::current()->Run();
429 462
430 // Check the result. 463 // Check the result.
431 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED, 464 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
432 get_proxy_listener()->get_reason()); 465 get_proxy_listener()->get_reason());
433 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS); 466 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
434 467
435 CommonTearDown(); 468 CommonTearDown();
436 } 469 }
437 470
471 // An unprivileged process makes a shared memory region and sends it to the
472 // privileged process.
473 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, DISABLED_SendSharedMemoryHandle) {
474 Init("SendSharedMemoryHandle");
475
476 CommonSetUp();
477 ResultListener result_listener;
478 get_proxy_listener()->set_listener(&result_listener);
479
480 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
481 shared_memory->CreateAndMapAnonymous(kSharedMemorySize);
482 memcpy(shared_memory->memory(), kDataBuffer, strlen(kDataBuffer));
483 sender()->Send(new TestSharedMemoryHandleMsg1(shared_memory->handle()));
484 base::MessageLoop::current()->Run();
485
486 // Check the result.
487 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
488 get_proxy_listener()->get_reason());
489 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
490
491 CommonTearDown();
492 }
493
438 using OnMessageReceivedCallback = void (*)(IPC::Sender* sender, 494 using OnMessageReceivedCallback = void (*)(IPC::Sender* sender,
439 const IPC::Message& message); 495 const IPC::Message& message);
440 496
441 int CommonPrivilegedProcessMain(OnMessageReceivedCallback callback, 497 int CommonPrivilegedProcessMain(OnMessageReceivedCallback callback,
442 const char* channel_name) { 498 const char* channel_name) {
443 LOG(INFO) << "Privileged process start."; 499 LOG(INFO) << "Privileged process start.";
444 base::MessageLoopForIO main_message_loop; 500 base::MessageLoopForIO main_message_loop;
445 ProxyListener listener; 501 ProxyListener listener;
446 502
447 // Set up IPC channel. 503 // Set up IPC channel.
(...skipping 26 matching lines...) Expand all
474 bool success = CheckContentsOfTestMessage(message); 530 bool success = CheckContentsOfTestMessage(message);
475 SendControlMessage(sender, success); 531 SendControlMessage(sender, success);
476 } 532 }
477 533
478 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandle) { 534 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandle) {
479 return CommonPrivilegedProcessMain(&SendHandleCallback, "SendHandle"); 535 return CommonPrivilegedProcessMain(&SendHandleCallback, "SendHandle");
480 } 536 }
481 537
482 void SendHandleWithoutPermissionsCallback(IPC::Sender* sender, 538 void SendHandleWithoutPermissionsCallback(IPC::Sender* sender,
483 const IPC::Message& message) { 539 const IPC::Message& message) {
484 HANDLE h = GetHandleFromTestHandleWinMsg(message); 540 ScopedHandle h(GetHandleFromTestHandleWinMsg(message));
485 if (h != nullptr) { 541 if (h.Get() != nullptr) {
486 SetFilePointer(h, 0, nullptr, FILE_BEGIN); 542 SetFilePointer(h.Get(), 0, nullptr, FILE_BEGIN);
487 543
488 char buffer[100]; 544 char buffer[100];
489 DWORD bytes_read; 545 DWORD bytes_read;
490 BOOL success = 546 BOOL success =
491 ::ReadFile(h, buffer, static_cast<DWORD>(strlen(kDataBuffer)), 547 ::ReadFile(h.Get(), buffer, static_cast<DWORD>(strlen(kDataBuffer)),
492 &bytes_read, nullptr); 548 &bytes_read, nullptr);
493 if (!success && GetLastError() == ERROR_ACCESS_DENIED) { 549 if (!success && GetLastError() == ERROR_ACCESS_DENIED) {
494 SendControlMessage(sender, true); 550 SendControlMessage(sender, true);
495 return; 551 return;
496 } 552 }
497 } 553 }
498 554
499 SendControlMessage(sender, false); 555 SendControlMessage(sender, false);
500 } 556 }
501 557
502 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleWithoutPermissions) { 558 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleWithoutPermissions) {
503 return CommonPrivilegedProcessMain(&SendHandleWithoutPermissionsCallback, 559 return CommonPrivilegedProcessMain(&SendHandleWithoutPermissionsCallback,
504 "SendHandleWithoutPermissions"); 560 "SendHandleWithoutPermissions");
505 } 561 }
506 562
507 void SendHandleToSelfCallback(IPC::Sender* sender, const IPC::Message&) { 563 void SendHandleToSelfCallback(IPC::Sender* sender, const IPC::Message&) {
508 // Do nothing special. The default behavior already runs the 564 // Do nothing special. The default behavior already runs the
509 // AttachmentBrokerPrivilegedWin. 565 // AttachmentBrokerPrivilegedWin.
510 } 566 }
511 567
512 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleToSelf) { 568 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleToSelf) {
513 return CommonPrivilegedProcessMain(&SendHandleToSelfCallback, 569 return CommonPrivilegedProcessMain(&SendHandleToSelfCallback,
514 "SendHandleToSelf"); 570 "SendHandleToSelf");
515 } 571 }
516 572
517 void SendTwoHandlesCallback(IPC::Sender* sender, const IPC::Message& message) { 573 void SendTwoHandlesCallback(IPC::Sender* sender, const IPC::Message& message) {
518 // Check for two handles. 574 // Check for two handles.
519 HANDLE h1 = GetHandleFromTestTwoHandleWinMsg(message, 0); 575 HANDLE h1, h2;
520 HANDLE h2 = GetHandleFromTestTwoHandleWinMsg(message, 1); 576 EXPECT_TRUE(GetHandleFromTestTwoHandleWinMsg(message, &h1, &h2));
521 if (h1 == nullptr || h2 == nullptr) { 577 if (h1 == nullptr || h2 == nullptr) {
522 SendControlMessage(sender, false); 578 SendControlMessage(sender, false);
523 return; 579 return;
524 } 580 }
525 581
526 // Check that their contents are correct. 582 // Check that their contents are correct.
527 std::string contents1 = ReadFromFile(h1); 583 std::string contents1 = ReadFromFile(h1);
528 std::string contents2 = ReadFromFile(h2); 584 std::string contents2 = ReadFromFile(h2);
529 if (contents1 != std::string(kDataBuffer) || 585 if (contents1 != std::string(kDataBuffer) ||
530 contents2 != std::string(kDataBuffer)) { 586 contents2 != std::string(kDataBuffer)) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 LOG(INFO) << "Received second message."; 628 LOG(INFO) << "Received second message.";
573 SendControlMessage(sender, success); 629 SendControlMessage(sender, success);
574 } 630 }
575 } 631 }
576 632
577 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleTwice) { 633 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleTwice) {
578 return CommonPrivilegedProcessMain(&SendHandleTwiceCallback, 634 return CommonPrivilegedProcessMain(&SendHandleTwiceCallback,
579 "SendHandleTwice"); 635 "SendHandleTwice");
580 } 636 }
581 637
638 void SendSharedMemoryHandleCallback(IPC::Sender* sender,
639 const IPC::Message& message) {
640 scoped_ptr<base::SharedMemory> shared_memory =
641 GetSharedMemoryFromSharedMemoryHandleMsg1(message, kSharedMemorySize);
642 bool success =
643 memcmp(shared_memory->memory(), kDataBuffer, strlen(kDataBuffer)) == 0;
644 SendControlMessage(sender, success);
645 }
646
647 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendSharedMemoryHandle) {
648 return CommonPrivilegedProcessMain(&SendSharedMemoryHandleCallback,
649 "SendSharedMemoryHandle");
650 }
651
582 } // namespace 652 } // namespace
OLDNEW
« no previous file with comments | « ipc/attachment_broker_privileged_win.cc ('k') | ipc/attachment_broker_unprivileged_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698