Home | History | Annotate | Download | only in loader
      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