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
20namespace {
21
22class 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.
75TEST_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.
109TEST_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.
175TEST_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.
225TEST_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.
270TEST_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.
313TEST_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