1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sandbox/mac/dispatch_source_mach.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <mach/mach.h> 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/mac/scoped_mach_port.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_ptr.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/test/test_timeouts.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gtest/include/gtest/gtest.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace sandbox { 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass DispatchSourceMachTest : public testing::Test { 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void SetUp() OVERRIDE { 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_port_t port = MACH_PORT_NULL; 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(mach_task_self(), 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MACH_PORT_RIGHT_RECEIVE, &port)); 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch receive_right_.reset(port); 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(mach_task_self(), port, 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch port, MACH_MSG_TYPE_MAKE_SEND)); 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch send_right_.reset(port); 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_port_t port() { return receive_right_.get(); } 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void WaitForSemaphore(dispatch_semaphore_t semaphore) { 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_semaphore_wait(semaphore, dispatch_time( 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DISPATCH_TIME_NOW, 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TestTimeouts::action_timeout().InSeconds() * NSEC_PER_SEC)); 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::mac::ScopedMachReceiveRight receive_right_; 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::mac::ScopedMachSendRight send_right_; 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 43116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(DispatchSourceMachTest, ReceiveAfterResume) { 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_semaphore_t signal = dispatch_semaphore_create(0); 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool __block did_receive = false; 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DispatchSourceMach source("org.chromium.sandbox.test.ReceiveAfterResume", 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch port(), ^{ 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_empty_rcv_t msg = {{0}}; 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_size = sizeof(msg); 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_local_port = port(); 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_receive(&msg.header); 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch did_receive = true; 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_semaphore_signal(signal); 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }); 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_empty_send_t msg = {{0}}; 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_size = sizeof(msg); 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_remote_port = port(); 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND); 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(KERN_SUCCESS, mach_msg_send(&msg.header)); 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(did_receive); 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch source.Resume(); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch WaitForSemaphore(signal); 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(did_receive); 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 73116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(DispatchSourceMachTest, NoMessagesAfterDestruction) { 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<int> count(new int(0)); 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int* __block count_ptr = count.get(); 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<DispatchSourceMach> source(new DispatchSourceMach( 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "org.chromium.sandbox.test.NoMessagesAfterDestruction", 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch port(), ^{ 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_empty_rcv_t msg = {{0}}; 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_size = sizeof(msg); 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_local_port = port(); 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_receive(&msg.header); 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Receieve " << *count_ptr; 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++(*count_ptr); 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch })); 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch source->Resume(); 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_queue_t queue = 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_queue_create("org.chromium.sandbox.test.MessageSend", NULL); 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_semaphore_t signal = dispatch_semaphore_create(0); 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (int i = 0; i < 30; ++i) { 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_async(queue, ^{ 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_empty_send_t msg = {{0}}; 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_size = sizeof(msg); 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_remote_port = port(); 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch msg.header.msgh_bits = 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND); 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mach_msg_send(&msg.header); 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }); 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // After sending five messages, shut down the source and taint the 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // pointer the handler dereferences. The test will crash if |count_ptr| 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // is being used after "free". 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i == 5) { 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<DispatchSourceMach>* source_ptr = &source; 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_async(queue, ^{ 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch source_ptr->reset(); 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch count_ptr = reinterpret_cast<int*>(0xdeaddead); 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_semaphore_signal(signal); 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }); 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch WaitForSemaphore(signal); 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dispatch_release(queue); 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace sandbox 120