| Index: ipc/attachment_broker_privileged_win_unittest.cc
|
| diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc
|
| index 583050cba5e288a6cb8a51347d379f2b4fed4fa7..7a2be3b00c0c6432c28410a291678cbfe8f03428 100644
|
| --- a/ipc/attachment_broker_privileged_win_unittest.cc
|
| +++ b/ipc/attachment_broker_privileged_win_unittest.cc
|
| @@ -10,6 +10,9 @@
|
| #include "base/files/file_util.h"
|
| #include "base/files/scoped_temp_dir.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/shared_memory.h"
|
| +#include "base/memory/shared_memory_handle.h"
|
| +#include "base/win/scoped_handle.h"
|
| #include "ipc/attachment_broker_privileged_win.h"
|
| #include "ipc/attachment_broker_unprivileged_win.h"
|
| #include "ipc/handle_attachment_win.h"
|
| @@ -21,7 +24,10 @@
|
|
|
| namespace {
|
|
|
| +using base::win::ScopedHandle;
|
| +
|
| const char kDataBuffer[] = "This is some test data to write to the file.";
|
| +const size_t kSharedMemorySize = 20000;
|
|
|
| // Returns the contents of the file represented by |h| as a std::string.
|
| std::string ReadFromFile(HANDLE h) {
|
| @@ -33,80 +39,107 @@ std::string ReadFromFile(HANDLE h) {
|
| return success ? std::string(buffer, bytes_read) : std::string();
|
| }
|
|
|
| -HANDLE GetHandleFromBrokeredAttachment(
|
| +ScopedHandle GetHandleFromBrokeredAttachment(
|
| const scoped_refptr<IPC::BrokerableAttachment>& attachment) {
|
| if (attachment->GetType() !=
|
| IPC::BrokerableAttachment::TYPE_BROKERABLE_ATTACHMENT) {
|
| LOG(INFO) << "Attachment type not TYPE_BROKERABLE_ATTACHMENT.";
|
| - return nullptr;
|
| + return ScopedHandle(nullptr);
|
| }
|
|
|
| if (attachment->GetBrokerableType() !=
|
| IPC::BrokerableAttachment::WIN_HANDLE) {
|
| LOG(INFO) << "Brokerable type not WIN_HANDLE.";
|
| - return nullptr;
|
| + return ScopedHandle(nullptr);
|
| }
|
|
|
| IPC::internal::HandleAttachmentWin* received_handle_attachment =
|
| static_cast<IPC::internal::HandleAttachmentWin*>(attachment.get());
|
| - return received_handle_attachment->get_handle();
|
| + ScopedHandle h(received_handle_attachment->get_handle());
|
| + received_handle_attachment->reset_handle_ownership();
|
| + return h;
|
| }
|
|
|
| // |message| must be deserializable as a TestHandleWinMsg. Returns the HANDLE,
|
| // or nullptr if deserialization failed.
|
| -HANDLE GetHandleFromTestHandleWinMsg(const IPC::Message& message) {
|
| +ScopedHandle GetHandleFromTestHandleWinMsg(const IPC::Message& message) {
|
| // Expect a message with a brokered attachment.
|
| if (!message.HasBrokerableAttachments()) {
|
| LOG(INFO) << "Message missing brokerable attachment.";
|
| - return nullptr;
|
| + return ScopedHandle(nullptr);
|
| }
|
|
|
| TestHandleWinMsg::Schema::Param p;
|
| bool success = TestHandleWinMsg::Read(&message, &p);
|
| if (!success) {
|
| LOG(INFO) << "Failed to deserialize message.";
|
| - return nullptr;
|
| + return ScopedHandle(nullptr);
|
| }
|
|
|
| IPC::HandleWin handle_win = base::get<1>(p);
|
| - return handle_win.get_handle();
|
| + return ScopedHandle(handle_win.get_handle());
|
| +}
|
| +
|
| +// Returns a mapped, shared memory region based on the handle in |message|.
|
| +scoped_ptr<base::SharedMemory> GetSharedMemoryFromSharedMemoryHandleMsg1(
|
| + const IPC::Message& message,
|
| + size_t size) {
|
| + // Expect a message with a brokered attachment.
|
| + if (!message.HasBrokerableAttachments()) {
|
| + LOG(INFO) << "Message missing brokerable attachment.";
|
| + return nullptr;
|
| + }
|
| +
|
| + TestSharedMemoryHandleMsg1::Schema::Param p;
|
| + bool success = TestSharedMemoryHandleMsg1::Read(&message, &p);
|
| + if (!success) {
|
| + LOG(INFO) << "Failed to deserialize message.";
|
| + return nullptr;
|
| + }
|
| +
|
| + base::SharedMemoryHandle handle = base::get<0>(p);
|
| + scoped_ptr<base::SharedMemory> shared_memory(
|
| + new base::SharedMemory(handle, false));
|
| +
|
| + shared_memory->Map(size);
|
| + return std::move(shared_memory);
|
| }
|
|
|
| // |message| must be deserializable as a TestTwoHandleWinMsg. Returns the
|
| // HANDLE, or nullptr if deserialization failed.
|
| -HANDLE GetHandleFromTestTwoHandleWinMsg(const IPC::Message& message,
|
| - int index) {
|
| +bool GetHandleFromTestTwoHandleWinMsg(const IPC::Message& message,
|
| + HANDLE* h1,
|
| + HANDLE* h2) {
|
| // Expect a message with a brokered attachment.
|
| if (!message.HasBrokerableAttachments()) {
|
| LOG(INFO) << "Message missing brokerable attachment.";
|
| - return nullptr;
|
| + return false;
|
| }
|
|
|
| TestTwoHandleWinMsg::Schema::Param p;
|
| bool success = TestTwoHandleWinMsg::Read(&message, &p);
|
| if (!success) {
|
| LOG(INFO) << "Failed to deserialize message.";
|
| - return nullptr;
|
| + return false;
|
| }
|
|
|
| - IPC::HandleWin handle_win;
|
| - if (index == 0)
|
| - handle_win = base::get<0>(p);
|
| - else if (index == 1)
|
| - handle_win = base::get<1>(p);
|
| - return handle_win.get_handle();
|
| + IPC::HandleWin handle_win = base::get<0>(p);
|
| + *h1 = handle_win.get_handle();
|
| + handle_win = base::get<1>(p);
|
| + *h2 = handle_win.get_handle();
|
| + return true;
|
| }
|
|
|
| // |message| must be deserializable as a TestHandleWinMsg. Returns true if the
|
| // attached file HANDLE has contents |kDataBuffer|.
|
| bool CheckContentsOfTestMessage(const IPC::Message& message) {
|
| - HANDLE h = GetHandleFromTestHandleWinMsg(message);
|
| - if (h == nullptr) {
|
| + ScopedHandle h(GetHandleFromTestHandleWinMsg(message));
|
| + if (h.Get() == nullptr) {
|
| LOG(INFO) << "Failed to get handle from TestHandleWinMsg.";
|
| return false;
|
| }
|
|
|
| - std::string contents = ReadFromFile(h);
|
| + std::string contents = ReadFromFile(h.Get());
|
| bool success = (contents == std::string(kDataBuffer));
|
| if (!success) {
|
| LOG(INFO) << "Expected contents: " << std::string(kDataBuffer);
|
| @@ -371,12 +404,12 @@ TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleToSelf) {
|
| get_broker()->GetAttachmentWithId(*id, &received_attachment);
|
| ASSERT_NE(received_attachment.get(), nullptr);
|
|
|
| - // Check that it's the same entry in the HANDLE table.
|
| - HANDLE h2 = GetHandleFromBrokeredAttachment(received_attachment);
|
| - EXPECT_EQ(h2, h);
|
| + // Check that it's a different entry in the HANDLE table.
|
| + ScopedHandle h2(GetHandleFromBrokeredAttachment(received_attachment));
|
| + EXPECT_NE(h2.Get(), h);
|
|
|
| - // And still points to the same file.
|
| - std::string contents = ReadFromFile(h);
|
| + // But still points to the same file.
|
| + std::string contents = ReadFromFile(h2.Get());
|
| EXPECT_EQ(contents, std::string(kDataBuffer));
|
|
|
| CommonTearDown();
|
| @@ -435,6 +468,29 @@ TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleTwice) {
|
| CommonTearDown();
|
| }
|
|
|
| +// An unprivileged process makes a shared memory region and sends it to the
|
| +// privileged process.
|
| +TEST_F(IPCAttachmentBrokerPrivilegedWinTest, DISABLED_SendSharedMemoryHandle) {
|
| + Init("SendSharedMemoryHandle");
|
| +
|
| + CommonSetUp();
|
| + ResultListener result_listener;
|
| + get_proxy_listener()->set_listener(&result_listener);
|
| +
|
| + scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
|
| + shared_memory->CreateAndMapAnonymous(kSharedMemorySize);
|
| + memcpy(shared_memory->memory(), kDataBuffer, strlen(kDataBuffer));
|
| + sender()->Send(new TestSharedMemoryHandleMsg1(shared_memory->handle()));
|
| + base::MessageLoop::current()->Run();
|
| +
|
| + // Check the result.
|
| + ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
|
| + get_proxy_listener()->get_reason());
|
| + ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
|
| +
|
| + CommonTearDown();
|
| +}
|
| +
|
| using OnMessageReceivedCallback = void (*)(IPC::Sender* sender,
|
| const IPC::Message& message);
|
|
|
| @@ -481,14 +537,14 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandle) {
|
|
|
| void SendHandleWithoutPermissionsCallback(IPC::Sender* sender,
|
| const IPC::Message& message) {
|
| - HANDLE h = GetHandleFromTestHandleWinMsg(message);
|
| - if (h != nullptr) {
|
| - SetFilePointer(h, 0, nullptr, FILE_BEGIN);
|
| + ScopedHandle h(GetHandleFromTestHandleWinMsg(message));
|
| + if (h.Get() != nullptr) {
|
| + SetFilePointer(h.Get(), 0, nullptr, FILE_BEGIN);
|
|
|
| char buffer[100];
|
| DWORD bytes_read;
|
| BOOL success =
|
| - ::ReadFile(h, buffer, static_cast<DWORD>(strlen(kDataBuffer)),
|
| + ::ReadFile(h.Get(), buffer, static_cast<DWORD>(strlen(kDataBuffer)),
|
| &bytes_read, nullptr);
|
| if (!success && GetLastError() == ERROR_ACCESS_DENIED) {
|
| SendControlMessage(sender, true);
|
| @@ -516,8 +572,8 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleToSelf) {
|
|
|
| void SendTwoHandlesCallback(IPC::Sender* sender, const IPC::Message& message) {
|
| // Check for two handles.
|
| - HANDLE h1 = GetHandleFromTestTwoHandleWinMsg(message, 0);
|
| - HANDLE h2 = GetHandleFromTestTwoHandleWinMsg(message, 1);
|
| + HANDLE h1, h2;
|
| + EXPECT_TRUE(GetHandleFromTestTwoHandleWinMsg(message, &h1, &h2));
|
| if (h1 == nullptr || h2 == nullptr) {
|
| SendControlMessage(sender, false);
|
| return;
|
| @@ -579,4 +635,18 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleTwice) {
|
| "SendHandleTwice");
|
| }
|
|
|
| +void SendSharedMemoryHandleCallback(IPC::Sender* sender,
|
| + const IPC::Message& message) {
|
| + scoped_ptr<base::SharedMemory> shared_memory =
|
| + GetSharedMemoryFromSharedMemoryHandleMsg1(message, kSharedMemorySize);
|
| + bool success =
|
| + memcmp(shared_memory->memory(), kDataBuffer, strlen(kDataBuffer)) == 0;
|
| + SendControlMessage(sender, success);
|
| +}
|
| +
|
| +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendSharedMemoryHandle) {
|
| + return CommonPrivilegedProcessMain(&SendSharedMemoryHandleCallback,
|
| + "SendSharedMemoryHandle");
|
| +}
|
| +
|
| } // namespace
|
|
|