1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "components/nacl/loader/nacl_ipc_adapter.h" 6 7 #include <string.h> 8 9 #include "base/memory/scoped_ptr.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop_proxy.h" 12 #include "base/threading/platform_thread.h" 13 #include "base/threading/simple_thread.h" 14 #include "ipc/ipc_test_sink.h" 15 #include "native_client/src/trusted/desc/nacl_desc_custom.h" 16 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" 17 #include "ppapi/c/ppb_file_io.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace { 21 22 class NaClIPCAdapterTest : public testing::Test { 23 public: 24 NaClIPCAdapterTest() {} 25 26 // testing::Test implementation. 27 virtual void SetUp() OVERRIDE { 28 sink_ = new IPC::TestSink; 29 30 // Takes ownership of the sink_ pointer. Note we provide the current message 31 // loop instead of using a real IO thread. This should work OK since we do 32 // not need real IPC for the tests. 33 adapter_ = new NaClIPCAdapter(scoped_ptr<IPC::Channel>(sink_), 34 base::MessageLoopProxy::current().get()); 35 } 36 virtual void TearDown() OVERRIDE { 37 sink_ = NULL; // This pointer is actually owned by the IPCAdapter. 38 adapter_ = NULL; 39 // The adapter destructor has to post a task to destroy the Channel on the 40 // IO thread. For the purposes of the test, we just need to make sure that 41 // task gets run, or it will appear as a leak. 42 message_loop_.RunUntilIdle(); 43 } 44 45 protected: 46 int BlockingReceive(void* buf, size_t buf_size) { 47 NaClImcMsgIoVec iov = {buf, buf_size}; 48 NaClImcTypedMsgHdr msg = {&iov, 1}; 49 return adapter_->BlockingReceive(&msg); 50 } 51 52 int Send(void* buf, size_t buf_size) { 53 NaClImcMsgIoVec iov = {buf, buf_size}; 54 NaClImcTypedMsgHdr msg = {&iov, 1}; 55 return adapter_->Send(&msg); 56 } 57 58 base::MessageLoop message_loop_; 59 60 scoped_refptr<NaClIPCAdapter> adapter_; 61 62 // Messages sent from nacl to the adapter end up here. Note that we create 63 // this pointer and pass ownership of it to the IPC adapter, who will keep 64 // it alive as long as the adapter is alive. This means that when the 65 // adapter goes away, this pointer will become invalid. 66 // 67 // In real life the adapter needs to take ownership so the channel can be 68 // destroyed on the right thread. 69 IPC::TestSink* sink_; 70 }; 71 72 } // namespace 73 74 // Tests a simple message getting rewritten sent from native code to NaCl. 75 TEST_F(NaClIPCAdapterTest, SimpleReceiveRewriting) { 76 int routing_id = 0x89898989; 77 uint32 type = 0x55555555; 78 IPC::Message input(routing_id, type, IPC::Message::PRIORITY_NORMAL); 79 uint32 flags = input.flags(); 80 81 int value = 0x12345678; 82 input.WriteInt(value); 83 adapter_->OnMessageReceived(input); 84 85 // Buffer just need to be big enough for our message with one int. 86 const int kBufSize = 64; 87 char buf[kBufSize]; 88 89 int bytes_read = BlockingReceive(buf, kBufSize); 90 EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int), 91 static_cast<size_t>(bytes_read)); 92 93 const NaClIPCAdapter::NaClMessageHeader* output_header = 94 reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf); 95 EXPECT_EQ(sizeof(int), output_header->payload_size); 96 EXPECT_EQ(routing_id, output_header->routing); 97 EXPECT_EQ(type, output_header->type); 98 EXPECT_EQ(flags, output_header->flags); 99 EXPECT_EQ(0u, output_header->num_fds); 100 EXPECT_EQ(0u, output_header->pad); 101 102 // Validate the payload. 103 EXPECT_EQ(value, 104 *reinterpret_cast<const int*>(&buf[ 105 sizeof(NaClIPCAdapter::NaClMessageHeader)])); 106 } 107 108 // Tests a simple message getting rewritten sent from NaCl to native code. 109 TEST_F(NaClIPCAdapterTest, SendRewriting) { 110 int routing_id = 0x89898989; 111 uint32 type = 0x55555555; 112 int value = 0x12345678; 113 114 // Send a message with one int inside it. 115 const int buf_size = sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int); 116 char buf[buf_size] = {0}; 117 118 NaClIPCAdapter::NaClMessageHeader* header = 119 reinterpret_cast<NaClIPCAdapter::NaClMessageHeader*>(buf); 120 header->payload_size = sizeof(int); 121 header->routing = routing_id; 122 header->type = type; 123 header->flags = 0; 124 header->num_fds = 0; 125 *reinterpret_cast<int*>( 126 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value; 127 128 int result = Send(buf, buf_size); 129 EXPECT_EQ(buf_size, result); 130 131 // Check that the message came out the other end in the test sink 132 // (messages are posted, so we have to pump). 133 message_loop_.RunUntilIdle(); 134 ASSERT_EQ(1u, sink_->message_count()); 135 const IPC::Message* msg = sink_->GetMessageAt(0); 136 137 EXPECT_EQ(sizeof(int), msg->payload_size()); 138 EXPECT_EQ(header->routing, msg->routing_id()); 139 EXPECT_EQ(header->type, msg->type()); 140 141 // Now test the partial send case. We should be able to break the message 142 // into two parts and it should still work. 143 sink_->ClearMessages(); 144 int first_chunk_size = 7; 145 result = Send(buf, first_chunk_size); 146 EXPECT_EQ(first_chunk_size, result); 147 148 // First partial send should not have made any messages. 149 message_loop_.RunUntilIdle(); 150 ASSERT_EQ(0u, sink_->message_count()); 151 152 // Second partial send should do the same. 153 int second_chunk_size = 2; 154 result = Send(&buf[first_chunk_size], second_chunk_size); 155 EXPECT_EQ(second_chunk_size, result); 156 message_loop_.RunUntilIdle(); 157 ASSERT_EQ(0u, sink_->message_count()); 158 159 // Send the rest of the message in a third chunk. 160 int third_chunk_size = buf_size - first_chunk_size - second_chunk_size; 161 result = Send(&buf[first_chunk_size + second_chunk_size], 162 third_chunk_size); 163 EXPECT_EQ(third_chunk_size, result); 164 165 // Last send should have generated one message. 166 message_loop_.RunUntilIdle(); 167 ASSERT_EQ(1u, sink_->message_count()); 168 msg = sink_->GetMessageAt(0); 169 EXPECT_EQ(sizeof(int), msg->payload_size()); 170 EXPECT_EQ(header->routing, msg->routing_id()); 171 EXPECT_EQ(header->type, msg->type()); 172 } 173 174 // Tests when a buffer is too small to receive the entire message. 175 TEST_F(NaClIPCAdapterTest, PartialReceive) { 176 int routing_id_1 = 0x89898989; 177 uint32 type_1 = 0x55555555; 178 IPC::Message input_1(routing_id_1, type_1, IPC::Message::PRIORITY_NORMAL); 179 int value_1 = 0x12121212; 180 input_1.WriteInt(value_1); 181 adapter_->OnMessageReceived(input_1); 182 183 int routing_id_2 = 0x90909090; 184 uint32 type_2 = 0x66666666; 185 IPC::Message input_2(routing_id_2, type_2, IPC::Message::PRIORITY_NORMAL); 186 int value_2 = 0x23232323; 187 input_2.WriteInt(value_2); 188 adapter_->OnMessageReceived(input_2); 189 190 const int kBufSize = 64; 191 char buf[kBufSize]; 192 193 // Read part of the first message. 194 int bytes_requested = 7; 195 int bytes_read = BlockingReceive(buf, bytes_requested); 196 ASSERT_EQ(bytes_requested, bytes_read); 197 198 // Read the rest, this should give us the rest of the first message only. 199 bytes_read += BlockingReceive(&buf[bytes_requested], 200 kBufSize - bytes_requested); 201 EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int), 202 static_cast<size_t>(bytes_read)); 203 204 // Make sure we got the right message. 205 const NaClIPCAdapter::NaClMessageHeader* output_header = 206 reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf); 207 EXPECT_EQ(sizeof(int), output_header->payload_size); 208 EXPECT_EQ(routing_id_1, output_header->routing); 209 EXPECT_EQ(type_1, output_header->type); 210 211 // Read the second message to make sure we went on to it. 212 bytes_read = BlockingReceive(buf, kBufSize); 213 EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int), 214 static_cast<size_t>(bytes_read)); 215 output_header = 216 reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf); 217 EXPECT_EQ(sizeof(int), output_header->payload_size); 218 EXPECT_EQ(routing_id_2, output_header->routing); 219 EXPECT_EQ(type_2, output_header->type); 220 } 221 222 // Tests sending messages that are too large. We test sends that are too 223 // small implicitly here and in the success case because in that case it 224 // succeeds and buffers the data. 225 TEST_F(NaClIPCAdapterTest, SendOverflow) { 226 int routing_id = 0x89898989; 227 uint32 type = 0x55555555; 228 int value = 0x12345678; 229 230 // Make a message with one int inside it. Reserve some extra space so 231 // we can test what happens when we send too much data. 232 const int buf_size = sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int); 233 const int big_buf_size = buf_size + 4; 234 char buf[big_buf_size] = {0}; 235 236 NaClIPCAdapter::NaClMessageHeader* header = 237 reinterpret_cast<NaClIPCAdapter::NaClMessageHeader*>(buf); 238 header->payload_size = sizeof(int); 239 header->routing = routing_id; 240 header->type = type; 241 header->flags = 0; 242 header->num_fds = 0; 243 *reinterpret_cast<int*>( 244 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value; 245 246 // Send too much data and make sure that the send fails. 247 int result = Send(buf, big_buf_size); 248 EXPECT_EQ(-1, result); 249 message_loop_.RunUntilIdle(); 250 ASSERT_EQ(0u, sink_->message_count()); 251 252 // Send too much data in two chunks and make sure that the send fails. 253 int first_chunk_size = 7; 254 result = Send(buf, first_chunk_size); 255 EXPECT_EQ(first_chunk_size, result); 256 257 // First partial send should not have made any messages. 258 message_loop_.RunUntilIdle(); 259 ASSERT_EQ(0u, sink_->message_count()); 260 261 int second_chunk_size = big_buf_size - first_chunk_size; 262 result = Send(&buf[first_chunk_size], second_chunk_size); 263 EXPECT_EQ(-1, result); 264 message_loop_.RunUntilIdle(); 265 ASSERT_EQ(0u, sink_->message_count()); 266 } 267 268 // Tests that when the IPC channel reports an error, that waiting reads are 269 // unblocked and return a -1 error code. 270 TEST_F(NaClIPCAdapterTest, ReadWithChannelError) { 271 // Have a background thread that waits a bit and calls the channel error 272 // handler. This should wake up any waiting threads and immediately return 273 // -1. There is an inherent race condition in that we can't be sure if the 274 // other thread is actually waiting when this happens. This is OK, since the 275 // behavior (which we also explicitly test later) is to return -1 if the 276 // channel has already had an error when you start waiting. 277 class MyThread : public base::SimpleThread { 278 public: 279 explicit MyThread(NaClIPCAdapter* adapter) 280 : SimpleThread("NaClIPCAdapterThread"), 281 adapter_(adapter) {} 282 virtual void Run() OVERRIDE { 283 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); 284 adapter_->OnChannelError(); 285 } 286 private: 287 scoped_refptr<NaClIPCAdapter> adapter_; 288 }; 289 MyThread thread(adapter_.get()); 290 291 // IMPORTANT: do not return early from here down (including ASSERT_*) because 292 // the thread needs to joined or it will assert. 293 thread.Start(); 294 295 // Request data. This will normally (modulo races) block until data is 296 // received or there is an error, and the thread above will wake us up 297 // after 1s. 298 const int kBufSize = 64; 299 char buf[kBufSize]; 300 int result = BlockingReceive(buf, kBufSize); 301 EXPECT_EQ(-1, result); 302 303 // Test the "previously had an error" case. BlockingReceive should return 304 // immediately if there was an error. 305 result = BlockingReceive(buf, kBufSize); 306 EXPECT_EQ(-1, result); 307 308 thread.Join(); 309 } 310 311 // Tests that TranslatePepperFileOpenFlags translates pepper read/write open 312 // flags into NaCl open flags correctly. 313 TEST_F(NaClIPCAdapterTest, TranslatePepperFileReadWriteOpenFlags) { 314 EXPECT_EQ(NACL_ABI_O_RDONLY, 315 TranslatePepperFileReadWriteOpenFlagsForTesting(PP_FILEOPENFLAG_READ)); 316 EXPECT_EQ(NACL_ABI_O_WRONLY, 317 TranslatePepperFileReadWriteOpenFlagsForTesting(PP_FILEOPENFLAG_WRITE)); 318 EXPECT_EQ(NACL_ABI_O_WRONLY | NACL_ABI_O_APPEND, 319 TranslatePepperFileReadWriteOpenFlagsForTesting( 320 PP_FILEOPENFLAG_APPEND)); 321 EXPECT_EQ(NACL_ABI_O_RDWR, 322 TranslatePepperFileReadWriteOpenFlagsForTesting( 323 PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE)); 324 EXPECT_EQ(NACL_ABI_O_WRONLY | NACL_ABI_O_APPEND, 325 TranslatePepperFileReadWriteOpenFlagsForTesting( 326 PP_FILEOPENFLAG_APPEND)); 327 EXPECT_EQ(NACL_ABI_O_RDWR | NACL_ABI_O_APPEND, 328 TranslatePepperFileReadWriteOpenFlagsForTesting( 329 PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_APPEND)); 330 331 // Flags other than PP_FILEOPENFLAG_READ, PP_FILEOPENFLAG_WRITE, and 332 // PP_FILEOPENFLAG_APPEND are discarded. 333 EXPECT_EQ(NACL_ABI_O_WRONLY, 334 TranslatePepperFileReadWriteOpenFlagsForTesting( 335 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE)); 336 EXPECT_EQ(NACL_ABI_O_WRONLY, 337 TranslatePepperFileReadWriteOpenFlagsForTesting( 338 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_TRUNCATE)); 339 EXPECT_EQ(NACL_ABI_O_WRONLY, 340 TranslatePepperFileReadWriteOpenFlagsForTesting( 341 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE)); 342 343 // If none of PP_FILEOPENFLAG_READ, PP_FILEOPENFLAG_WRITE, and 344 // PP_FILEOPENFLAG_APPEND are set, the result should fall back to 345 // NACL_ABI_O_READONLY. 346 EXPECT_EQ(NACL_ABI_O_RDONLY, 347 TranslatePepperFileReadWriteOpenFlagsForTesting(0)); 348 EXPECT_EQ(NACL_ABI_O_RDONLY, 349 TranslatePepperFileReadWriteOpenFlagsForTesting( 350 PP_FILEOPENFLAG_CREATE)); 351 EXPECT_EQ(NACL_ABI_O_RDONLY, 352 TranslatePepperFileReadWriteOpenFlagsForTesting( 353 PP_FILEOPENFLAG_TRUNCATE)); 354 EXPECT_EQ(NACL_ABI_O_RDONLY, 355 TranslatePepperFileReadWriteOpenFlagsForTesting( 356 PP_FILEOPENFLAG_EXCLUSIVE)); 357 } 358