OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "sandbox/src/crosscall_client.h" | 6 #include "sandbox/src/crosscall_client.h" |
7 #include "sandbox/src/crosscall_server.h" | 7 #include "sandbox/src/crosscall_server.h" |
8 #include "sandbox/src/sharedmem_ipc_client.h" | 8 #include "sandbox/src/sharedmem_ipc_client.h" |
| 9 #include "sandbox/src/sharedmem_ipc_server.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
10 | 11 |
11 | |
12 namespace sandbox { | 12 namespace sandbox { |
13 | 13 |
14 // Helper function to make the fake shared memory with some | 14 // Helper function to make the fake shared memory with some |
15 // basic elements initialized. | 15 // basic elements initialized. |
16 IPCControl* MakeChannels(size_t channel_size, size_t total_shared_size, | 16 IPCControl* MakeChannels(size_t channel_size, size_t total_shared_size, |
17 size_t* base_start) { | 17 size_t* base_start) { |
18 // Allocate memory | 18 // Allocate memory |
19 char* mem = new char[total_shared_size]; | 19 char* mem = new char[total_shared_size]; |
20 memset(mem, 0, total_shared_size); | 20 memset(mem, 0, total_shared_size); |
21 | |
22 // Calculate how many channels we can fit in the shared memory. | 21 // Calculate how many channels we can fit in the shared memory. |
23 total_shared_size -= offsetof(IPCControl, channels); | 22 total_shared_size -= offsetof(IPCControl, channels); |
24 size_t channel_count = | 23 size_t channel_count = |
25 total_shared_size / (sizeof(ChannelControl) + channel_size); | 24 total_shared_size / (sizeof(ChannelControl) + channel_size); |
26 | |
27 // Calculate the start of the first channel. | 25 // Calculate the start of the first channel. |
28 *base_start = (sizeof(ChannelControl)* channel_count) + | 26 *base_start = (sizeof(ChannelControl)* channel_count) + |
29 offsetof(IPCControl, channels); | 27 offsetof(IPCControl, channels); |
30 | |
31 // Setup client structure. | 28 // Setup client structure. |
32 IPCControl* client_control = reinterpret_cast<IPCControl*>(mem); | 29 IPCControl* client_control = reinterpret_cast<IPCControl*>(mem); |
33 client_control->channels_count = channel_count; | 30 client_control->channels_count = channel_count; |
34 | |
35 return client_control; | 31 return client_control; |
36 } | 32 } |
37 | 33 |
| 34 enum TestFixMode { |
| 35 FIX_NO_EVENTS, |
| 36 FIX_PONG_READY, |
| 37 FIX_PONG_NOT_READY |
| 38 }; |
| 39 |
| 40 void FixChannels(IPCControl* client_control, size_t base_start, |
| 41 size_t channel_size, TestFixMode mode) { |
| 42 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { |
| 43 ChannelControl& channel = client_control->channels[ix]; |
| 44 channel.channel_base = base_start; |
| 45 channel.state = kFreeChannel; |
| 46 if (mode != FIX_NO_EVENTS) { |
| 47 BOOL signaled = (FIX_PONG_READY == mode)? TRUE : FALSE; |
| 48 channel.ping_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); |
| 49 channel.pong_event = ::CreateEventW(NULL, FALSE, signaled, NULL); |
| 50 } |
| 51 base_start += channel_size; |
| 52 } |
| 53 } |
| 54 |
| 55 void CloseChannelEvents(IPCControl* client_control) { |
| 56 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { |
| 57 ChannelControl& channel = client_control->channels[ix]; |
| 58 ::CloseHandle(channel.ping_event); |
| 59 ::CloseHandle(channel.pong_event); |
| 60 } |
| 61 } |
| 62 |
38 TEST(IPCTest, ChannelMaker) { | 63 TEST(IPCTest, ChannelMaker) { |
39 size_t channel_start = 0; | |
40 IPCControl* client_control = MakeChannels(12*64, 4096, &channel_start); | |
41 | |
42 // Test that our testing rig is computing offsets properly. We should have | 64 // Test that our testing rig is computing offsets properly. We should have |
43 // 5 channnels and the offset to the first channel is 108 bytes in 32 bits | 65 // 5 channnels and the offset to the first channel is 108 bytes in 32 bits |
44 // and 216 in 64 bits. | 66 // and 216 in 64 bits. |
| 67 size_t channel_start = 0; |
| 68 IPCControl* client_control = MakeChannels(12 * 64, 4096, &channel_start); |
45 ASSERT_TRUE(NULL != client_control); | 69 ASSERT_TRUE(NULL != client_control); |
46 EXPECT_EQ(5, client_control->channels_count); | 70 EXPECT_EQ(5, client_control->channels_count); |
47 #if defined(_WIN64) | 71 #if defined(_WIN64) |
48 EXPECT_EQ(216, channel_start); | 72 EXPECT_EQ(216, channel_start); |
49 #else | 73 #else |
50 EXPECT_EQ(108, channel_start); | 74 EXPECT_EQ(108, channel_start); |
51 #endif | 75 #endif |
52 | 76 delete[] reinterpret_cast<char*>(client_control); |
53 delete [] reinterpret_cast<char*>(client_control); | |
54 } | 77 } |
55 | 78 |
56 TEST(IPCTest, ClientLockUnlock) { | 79 TEST(IPCTest, ClientLockUnlock) { |
57 // Make 7 channels of kIPCChannelSize (1kb) each. Test that we lock and | 80 // Make 7 channels of kIPCChannelSize (1kb) each. Test that we lock and |
58 // unlock channels properly. | 81 // unlock channels properly. |
59 const size_t channel_size = kIPCChannelSize; | |
60 size_t base_start = 0; | 82 size_t base_start = 0; |
61 IPCControl* client_control = MakeChannels(channel_size, 4096*2, &base_start); | 83 IPCControl* client_control = |
62 | 84 MakeChannels(kIPCChannelSize, 4096 * 2, &base_start); |
63 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 85 FixChannels(client_control, base_start, kIPCChannelSize, FIX_NO_EVENTS); |
64 ChannelControl& channel = client_control->channels[ix]; | |
65 channel.channel_base = base_start; | |
66 channel.state = kFreeChannel; | |
67 base_start += channel_size; | |
68 } | |
69 | 86 |
70 char* mem = reinterpret_cast<char*>(client_control); | 87 char* mem = reinterpret_cast<char*>(client_control); |
71 SharedMemIPCClient client(mem); | 88 SharedMemIPCClient client(mem); |
72 | 89 |
73 // Test that we lock the first 3 channels in sequence. | 90 // Test that we lock the first 3 channels in sequence. |
74 void* buff0 = client.GetBuffer(); | 91 void* buff0 = client.GetBuffer(); |
75 EXPECT_TRUE(mem + client_control->channels[0].channel_base == buff0); | 92 EXPECT_TRUE(mem + client_control->channels[0].channel_base == buff0); |
76 EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 93 EXPECT_EQ(kBusyChannel, client_control->channels[0].state); |
77 EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 94 EXPECT_EQ(kFreeChannel, client_control->channels[1].state); |
78 EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 95 EXPECT_EQ(kFreeChannel, client_control->channels[2].state); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 134 EXPECT_EQ(kFreeChannel, client_control->channels[5].state); |
118 | 135 |
119 client.FreeBuffer(buff0); | 136 client.FreeBuffer(buff0); |
120 EXPECT_EQ(kFreeChannel, client_control->channels[0].state); | 137 EXPECT_EQ(kFreeChannel, client_control->channels[0].state); |
121 EXPECT_EQ(kBusyChannel, client_control->channels[1].state); | 138 EXPECT_EQ(kBusyChannel, client_control->channels[1].state); |
122 EXPECT_EQ(kBusyChannel, client_control->channels[2].state); | 139 EXPECT_EQ(kBusyChannel, client_control->channels[2].state); |
123 EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 140 EXPECT_EQ(kFreeChannel, client_control->channels[3].state); |
124 EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 141 EXPECT_EQ(kFreeChannel, client_control->channels[4].state); |
125 EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 142 EXPECT_EQ(kFreeChannel, client_control->channels[5].state); |
126 | 143 |
127 delete [] reinterpret_cast<char*>(client_control); | 144 delete[] reinterpret_cast<char*>(client_control); |
128 } | 145 } |
129 | 146 |
130 TEST(IPCTest, CrossCallStrPacking) { | 147 TEST(IPCTest, CrossCallStrPacking) { |
131 // This test tries the CrossCall object with null and non-null string | 148 // This test tries the CrossCall object with null and non-null string |
132 // combination of parameters and verifies that the unpacker can read them | 149 // combination of parameters, integer types and verifies that the unpacker |
133 // properly. | 150 // can read them properly. |
134 const size_t channel_size = kIPCChannelSize; | |
135 size_t base_start = 0; | 151 size_t base_start = 0; |
136 IPCControl* client_control = MakeChannels(channel_size, 4096*2, &base_start); | 152 IPCControl* client_control = |
| 153 MakeChannels(kIPCChannelSize, 4096 * 4, &base_start); |
137 client_control->server_alive = HANDLE(1); | 154 client_control->server_alive = HANDLE(1); |
138 | 155 FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); |
139 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | |
140 ChannelControl& channel = client_control->channels[ix]; | |
141 channel.channel_base = base_start; | |
142 channel.state = kFreeChannel; | |
143 channel.ping_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); | |
144 channel.pong_event = ::CreateEventW(NULL, FALSE, TRUE, NULL); | |
145 base_start += channel_size; | |
146 } | |
147 | 156 |
148 char* mem = reinterpret_cast<char*>(client_control); | 157 char* mem = reinterpret_cast<char*>(client_control); |
149 SharedMemIPCClient client(mem); | 158 SharedMemIPCClient client(mem); |
150 | 159 |
151 CrossCallReturn answer; | 160 CrossCallReturn answer; |
152 uint32 tag1 = 666; | 161 uint32 tag1 = 666; |
153 const wchar_t text[] = L"98765 - 43210"; | 162 const wchar_t text[] = L"98765 - 43210"; |
154 std::wstring copied_text; | 163 std::wstring copied_text; |
155 CrossCallParamsEx* actual_params; | 164 CrossCallParamsEx* actual_params; |
156 | 165 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text_p0)); | 214 EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text_p0)); |
206 EXPECT_STREQ(text2, copied_text_p0.c_str()); | 215 EXPECT_STREQ(text2, copied_text_p0.c_str()); |
207 EXPECT_TRUE(actual_params->GetParameterStr(2, &copied_text_p2)); | 216 EXPECT_TRUE(actual_params->GetParameterStr(2, &copied_text_p2)); |
208 EXPECT_STREQ(text, copied_text_p2.c_str()); | 217 EXPECT_STREQ(text, copied_text_p2.c_str()); |
209 type = INVALID_TYPE; | 218 type = INVALID_TYPE; |
210 param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); | 219 param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); |
211 EXPECT_TRUE(NULL != param_addr); | 220 EXPECT_TRUE(NULL != param_addr); |
212 EXPECT_EQ(0, param_size); | 221 EXPECT_EQ(0, param_size); |
213 EXPECT_EQ(WCHAR_TYPE, type); | 222 EXPECT_EQ(WCHAR_TYPE, type); |
214 | 223 |
215 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 224 CloseChannelEvents(client_control); |
216 ChannelControl& channel = client_control->channels[ix]; | 225 delete[] reinterpret_cast<char*>(client_control); |
217 ::CloseHandle(channel.ping_event); | 226 } |
218 ::CloseHandle(channel.pong_event); | 227 |
219 } | 228 TEST(IPCTest, CrossCallIntPacking) { |
220 delete [] reinterpret_cast<char*>(client_control); | 229 // Check handling for regular 32 bit integers used in Windows. |
| 230 size_t base_start = 0; |
| 231 IPCControl* client_control = |
| 232 MakeChannels(kIPCChannelSize, 4096 * 4, &base_start); |
| 233 client_control->server_alive = HANDLE(1); |
| 234 FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); |
| 235 |
| 236 uint32 tag1 = 999; |
| 237 uint32 tag2 = 111; |
| 238 const wchar_t text[] = L"godzilla"; |
| 239 CrossCallParamsEx* actual_params; |
| 240 |
| 241 char* mem = reinterpret_cast<char*>(client_control); |
| 242 SharedMemIPCClient client(mem); |
| 243 |
| 244 CrossCallReturn answer; |
| 245 DWORD dw = 0xE6578; |
| 246 CrossCall(client, tag2, dw, &answer); |
| 247 actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); |
| 248 EXPECT_EQ(1, actual_params->GetParamsCount()); |
| 249 EXPECT_EQ(tag2, actual_params->GetTag()); |
| 250 ArgType type = INVALID_TYPE; |
| 251 size_t param_size = 1; |
| 252 void* param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); |
| 253 ASSERT_EQ(sizeof(dw), param_size); |
| 254 EXPECT_EQ(ULONG_TYPE, type); |
| 255 ASSERT_TRUE(NULL != param_addr); |
| 256 EXPECT_EQ(0, memcmp(&dw, param_addr, param_size)); |
| 257 |
| 258 // Check handling for windows HANDLES. |
| 259 HANDLE h = HANDLE(0x70000500); |
| 260 CrossCall(client, tag1, text, h, &answer); |
| 261 actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); |
| 262 EXPECT_EQ(2, actual_params->GetParamsCount()); |
| 263 EXPECT_EQ(tag1, actual_params->GetTag()); |
| 264 type = INVALID_TYPE; |
| 265 param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); |
| 266 ASSERT_EQ(sizeof(h), param_size); |
| 267 EXPECT_EQ(VOIDPTR_TYPE, type); |
| 268 ASSERT_TRUE(NULL != param_addr); |
| 269 EXPECT_EQ(0, memcmp(&h, param_addr, param_size)); |
| 270 |
| 271 // Check combination of 32 and 64 bits. |
| 272 CrossCall(client, tag2, h, dw, h, &answer); |
| 273 actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); |
| 274 EXPECT_EQ(3, actual_params->GetParamsCount()); |
| 275 EXPECT_EQ(tag2, actual_params->GetTag()); |
| 276 type = INVALID_TYPE; |
| 277 param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); |
| 278 ASSERT_EQ(sizeof(h), param_size); |
| 279 EXPECT_EQ(VOIDPTR_TYPE, type); |
| 280 ASSERT_TRUE(NULL != param_addr); |
| 281 EXPECT_EQ(0, memcmp(&h, param_addr, param_size)); |
| 282 type = INVALID_TYPE; |
| 283 param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); |
| 284 ASSERT_EQ(sizeof(dw), param_size); |
| 285 EXPECT_EQ(ULONG_TYPE, type); |
| 286 ASSERT_TRUE(NULL != param_addr); |
| 287 EXPECT_EQ(0, memcmp(&dw, param_addr, param_size)); |
| 288 type = INVALID_TYPE; |
| 289 param_addr = actual_params->GetRawParameter(2, ¶m_size, &type); |
| 290 ASSERT_EQ(sizeof(h), param_size); |
| 291 EXPECT_EQ(VOIDPTR_TYPE, type); |
| 292 ASSERT_TRUE(NULL != param_addr); |
| 293 EXPECT_EQ(0, memcmp(&h, param_addr, param_size)); |
| 294 |
| 295 CloseChannelEvents(client_control); |
| 296 delete[] reinterpret_cast<char*>(client_control); |
221 } | 297 } |
222 | 298 |
223 TEST(IPCTest, CrossCallValidation) { | 299 TEST(IPCTest, CrossCallValidation) { |
224 // First a sanity test with a well formed parameter object. | 300 // First a sanity test with a well formed parameter object. |
225 unsigned long value = 124816; | 301 unsigned long value = 124816; |
226 const uint32 kTag = 33; | 302 const uint32 kTag = 33; |
227 ActualCallParams<1, 256> params_1(kTag); | 303 ActualCallParams<1, 256> params_1(kTag); |
228 params_1.CopyParamIn(0, &value, sizeof(value), false, ULONG_TYPE); | 304 params_1.CopyParamIn(0, &value, sizeof(value), false, ULONG_TYPE); |
229 void* buffer = const_cast<void*>(params_1.GetBuffer()); | 305 void* buffer = const_cast<void*>(params_1.GetBuffer()); |
230 | 306 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 CrossCallReturn* answer = reinterpret_cast<CrossCallReturn*>(channel); | 366 CrossCallReturn* answer = reinterpret_cast<CrossCallReturn*>(channel); |
291 answer->call_outcome = SBOX_ALL_OK; | 367 answer->call_outcome = SBOX_ALL_OK; |
292 } | 368 } |
293 | 369 |
294 // Create two threads that will quickly answer IPCs; the first one | 370 // Create two threads that will quickly answer IPCs; the first one |
295 // using channel 1 (channel 0 is busy) and one using channel 0. No time-out | 371 // using channel 1 (channel 0 is busy) and one using channel 0. No time-out |
296 // should occur. | 372 // should occur. |
297 TEST(IPCTest, ClientFastServer) { | 373 TEST(IPCTest, ClientFastServer) { |
298 const size_t channel_size = kIPCChannelSize; | 374 const size_t channel_size = kIPCChannelSize; |
299 size_t base_start = 0; | 375 size_t base_start = 0; |
300 IPCControl* client_control = MakeChannels(channel_size, 4096*2, &base_start); | 376 IPCControl* client_control = |
301 | 377 MakeChannels(channel_size, 4096 * 2, &base_start); |
302 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 378 FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_NOT_READY); |
303 ChannelControl& channel = client_control->channels[ix]; | |
304 channel.channel_base = base_start; | |
305 channel.state = kFreeChannel; | |
306 channel.ping_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); | |
307 channel.pong_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); | |
308 base_start += channel_size; | |
309 } | |
310 | |
311 client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL); | 379 client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL); |
312 | 380 |
313 char* mem = reinterpret_cast<char*>(client_control); | 381 char* mem = reinterpret_cast<char*>(client_control); |
314 SharedMemIPCClient client(mem); | 382 SharedMemIPCClient client(mem); |
315 | 383 |
316 ServerEvents events = {0}; | 384 ServerEvents events = {0}; |
317 events.ping = client_control->channels[1].ping_event; | 385 events.ping = client_control->channels[1].ping_event; |
318 events.pong = client_control->channels[1].pong_event; | 386 events.pong = client_control->channels[1].pong_event; |
319 events.state = &client_control->channels[1].state; | 387 events.state = &client_control->channels[1].state; |
320 | 388 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 result = client.DoCall(params2, &answer); | 435 result = client.DoCall(params2, &answer); |
368 if (SBOX_ERROR_CHANNEL_ERROR != result) | 436 if (SBOX_ERROR_CHANNEL_ERROR != result) |
369 client.FreeBuffer(buff0); | 437 client.FreeBuffer(buff0); |
370 | 438 |
371 EXPECT_TRUE(SBOX_ALL_OK == result); | 439 EXPECT_TRUE(SBOX_ALL_OK == result); |
372 EXPECT_EQ(tag, client_control->channels[0].ipc_tag); | 440 EXPECT_EQ(tag, client_control->channels[0].ipc_tag); |
373 EXPECT_EQ(kFreeChannel, client_control->channels[0].state); | 441 EXPECT_EQ(kFreeChannel, client_control->channels[0].state); |
374 EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 442 EXPECT_EQ(kFreeChannel, client_control->channels[1].state); |
375 EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 443 EXPECT_EQ(kFreeChannel, client_control->channels[2].state); |
376 | 444 |
377 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 445 CloseChannelEvents(client_control); |
378 ChannelControl& channel = client_control->channels[ix]; | 446 ::CloseHandle(client_control->server_alive); |
379 ::CloseHandle(channel.ping_event); | |
380 ::CloseHandle(channel.pong_event); | |
381 } | |
382 | 447 |
383 ::CloseHandle(client_control->server_alive); | 448 delete[] reinterpret_cast<char*>(client_control); |
384 delete [] reinterpret_cast<char*>(client_control); | |
385 } | 449 } |
386 | 450 |
387 // This is the server thread that very slowly answers an IPC and exits. Note | 451 // This is the server thread that very slowly answers an IPC and exits. Note |
388 // that the pong event needs to be signaled twice. | 452 // that the pong event needs to be signaled twice. |
389 DWORD WINAPI SlowResponseServer(PVOID param) { | 453 DWORD WINAPI SlowResponseServer(PVOID param) { |
390 ServerEvents* events = reinterpret_cast<ServerEvents*>(param); | 454 ServerEvents* events = reinterpret_cast<ServerEvents*>(param); |
391 DWORD wait_result = 0; | 455 DWORD wait_result = 0; |
392 wait_result = ::WaitForSingleObject(events->ping, INFINITE); | 456 wait_result = ::WaitForSingleObject(events->ping, INFINITE); |
393 ::Sleep(kIPCWaitTimeOut1 + kIPCWaitTimeOut2 + 200); | 457 ::Sleep(kIPCWaitTimeOut1 + kIPCWaitTimeOut2 + 200); |
394 ::InterlockedExchange(events->state, kAckChannel); | 458 ::InterlockedExchange(events->state, kAckChannel); |
395 ::SetEvent(events->pong); | 459 ::SetEvent(events->pong); |
396 return wait_result; | 460 return wait_result; |
397 } | 461 } |
398 | 462 |
399 // This thread's job is to keep the mutex locked. | 463 // This thread's job is to keep the mutex locked. |
400 DWORD WINAPI MainServerThread(PVOID param) { | 464 DWORD WINAPI MainServerThread(PVOID param) { |
401 ServerEvents* events = reinterpret_cast<ServerEvents*>(param); | 465 ServerEvents* events = reinterpret_cast<ServerEvents*>(param); |
402 DWORD wait_result = 0; | 466 DWORD wait_result = 0; |
403 wait_result = ::WaitForSingleObject(events->mutex, INFINITE); | 467 wait_result = ::WaitForSingleObject(events->mutex, INFINITE); |
404 Sleep(kIPCWaitTimeOut1 * 20); | 468 Sleep(kIPCWaitTimeOut1 * 20); |
405 return wait_result; | 469 return wait_result; |
406 } | 470 } |
407 | 471 |
408 // Creates a server thread that answers the IPC so slow that is guaranteed to | 472 // Creates a server thread that answers the IPC so slow that is guaranteed to |
409 // trigger the time-out code path in the client. A second thread is created | 473 // trigger the time-out code path in the client. A second thread is created |
410 // to hold locked the server_alive mutex: this signals the client that the | 474 // to hold locked the server_alive mutex: this signals the client that the |
411 // server is not dead and it retries the wait. | 475 // server is not dead and it retries the wait. |
412 TEST(IPCTest, ClientSlowServer) { | 476 TEST(IPCTest, ClientSlowServer) { |
413 const size_t channel_size = kIPCChannelSize; | |
414 size_t base_start = 0; | 477 size_t base_start = 0; |
415 IPCControl* client_control = MakeChannels(channel_size, 4096*2, &base_start); | 478 IPCControl* client_control = |
416 | 479 MakeChannels(kIPCChannelSize, 4096*2, &base_start); |
417 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 480 FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_NOT_READY); |
418 ChannelControl& channel = client_control->channels[ix]; | |
419 channel.channel_base = base_start; | |
420 channel.state = kFreeChannel; | |
421 channel.ping_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); | |
422 channel.pong_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); | |
423 base_start += channel_size; | |
424 } | |
425 | |
426 client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL); | 481 client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL); |
427 | 482 |
428 char* mem = reinterpret_cast<char*>(client_control); | 483 char* mem = reinterpret_cast<char*>(client_control); |
429 SharedMemIPCClient client(mem); | 484 SharedMemIPCClient client(mem); |
430 | 485 |
431 ServerEvents events = {0}; | 486 ServerEvents events = {0}; |
432 events.ping = client_control->channels[0].ping_event; | 487 events.ping = client_control->channels[0].ping_event; |
433 events.pong = client_control->channels[0].pong_event; | 488 events.pong = client_control->channels[0].pong_event; |
434 events.state = &client_control->channels[0].state; | 489 events.state = &client_control->channels[0].state; |
435 | 490 |
(...skipping 18 matching lines...) Expand all Loading... |
454 FakeOkAnswerInChannel(buff0); | 509 FakeOkAnswerInChannel(buff0); |
455 | 510 |
456 ResultCode result = client.DoCall(params1, &answer); | 511 ResultCode result = client.DoCall(params1, &answer); |
457 if (SBOX_ERROR_CHANNEL_ERROR != result) | 512 if (SBOX_ERROR_CHANNEL_ERROR != result) |
458 client.FreeBuffer(buff0); | 513 client.FreeBuffer(buff0); |
459 | 514 |
460 EXPECT_TRUE(SBOX_ALL_OK == result); | 515 EXPECT_TRUE(SBOX_ALL_OK == result); |
461 EXPECT_EQ(tag, client_control->channels[0].ipc_tag); | 516 EXPECT_EQ(tag, client_control->channels[0].ipc_tag); |
462 EXPECT_EQ(kFreeChannel, client_control->channels[0].state); | 517 EXPECT_EQ(kFreeChannel, client_control->channels[0].state); |
463 | 518 |
464 for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 519 CloseChannelEvents(client_control); |
465 ChannelControl& channel = client_control->channels[ix]; | 520 ::CloseHandle(client_control->server_alive); |
466 ::CloseHandle(channel.ping_event); | 521 delete[] reinterpret_cast<char*>(client_control); |
467 ::CloseHandle(channel.pong_event); | 522 } |
| 523 |
| 524 // This test-only IPC dispatcher has two handlers with the same signature |
| 525 // but only CallOneHandler should be used. |
| 526 class UnitTestIPCDispatcher : public Dispatcher { |
| 527 public: |
| 528 enum { |
| 529 CALL_ONE_TAG = 78, |
| 530 CALL_TWO_TAG = 87 |
| 531 }; |
| 532 |
| 533 UnitTestIPCDispatcher(); |
| 534 ~UnitTestIPCDispatcher() {}; |
| 535 |
| 536 virtual bool SetupService(InterceptionManager* manager, int service) { |
| 537 return true; |
468 } | 538 } |
469 ::CloseHandle(client_control->server_alive); | 539 |
470 delete [] reinterpret_cast<char*>(client_control); | 540 private: |
| 541 bool CallOneHandler(IPCInfo* ipc, HANDLE p1, DWORD p2) { |
| 542 ipc->return_info.extended[0].handle = p1; |
| 543 ipc->return_info.extended[1].unsigned_int = p2; |
| 544 return true; |
| 545 } |
| 546 |
| 547 bool CallTwoHandler(IPCInfo* ipc, HANDLE p1, DWORD p2) { |
| 548 return true; |
| 549 } |
| 550 }; |
| 551 |
| 552 UnitTestIPCDispatcher::UnitTestIPCDispatcher() { |
| 553 static const IPCCall call_one = { |
| 554 {CALL_ONE_TAG, VOIDPTR_TYPE, ULONG_TYPE}, |
| 555 reinterpret_cast<CallbackGeneric>( |
| 556 &UnitTestIPCDispatcher::CallOneHandler) |
| 557 }; |
| 558 static const IPCCall call_two = { |
| 559 {CALL_TWO_TAG, VOIDPTR_TYPE, ULONG_TYPE}, |
| 560 reinterpret_cast<CallbackGeneric>( |
| 561 &UnitTestIPCDispatcher::CallTwoHandler) |
| 562 }; |
| 563 ipc_calls_.push_back(call_one); |
| 564 ipc_calls_.push_back(call_two); |
| 565 } |
| 566 |
| 567 // This test does most of the shared memory IPC client-server roundtrip |
| 568 // and tests the packing, unpacking and call dispatching. |
| 569 TEST(IPCTest, SharedMemServerTests) { |
| 570 size_t base_start = 0; |
| 571 IPCControl* client_control = |
| 572 MakeChannels(kIPCChannelSize, 4096, &base_start); |
| 573 client_control->server_alive = HANDLE(1); |
| 574 FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); |
| 575 |
| 576 char* mem = reinterpret_cast<char*>(client_control); |
| 577 SharedMemIPCClient client(mem); |
| 578 |
| 579 CrossCallReturn answer; |
| 580 HANDLE bar = HANDLE(191919); |
| 581 DWORD foo = 6767676; |
| 582 CrossCall(client, UnitTestIPCDispatcher::CALL_ONE_TAG, bar, foo, &answer); |
| 583 void* buff = client.GetBuffer(); |
| 584 ASSERT_TRUE(NULL != buff); |
| 585 |
| 586 UnitTestIPCDispatcher dispatcher; |
| 587 // Since we are directly calling InvokeCallback, most of this structure |
| 588 // can be set to NULL. |
| 589 sandbox::SharedMemIPCServer::ServerControl srv_control = { |
| 590 NULL, NULL, kIPCChannelSize, NULL, |
| 591 reinterpret_cast<char*>(client_control), |
| 592 NULL, &dispatcher, {0} }; |
| 593 |
| 594 sandbox::CrossCallReturn call_return = {0}; |
| 595 EXPECT_TRUE(SharedMemIPCServer::InvokeCallback(&srv_control, buff, |
| 596 &call_return)); |
| 597 EXPECT_EQ(SBOX_ALL_OK, call_return.call_outcome); |
| 598 EXPECT_TRUE(bar == call_return.extended[0].handle); |
| 599 EXPECT_EQ(foo, call_return.extended[1].unsigned_int); |
| 600 |
| 601 CloseChannelEvents(client_control); |
| 602 delete[] reinterpret_cast<char*>(client_control); |
471 } | 603 } |
472 | 604 |
473 } // namespace sandbox | 605 } // namespace sandbox |
OLD | NEW |