OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stdio.h> | 5 #include <stdio.h> |
6 #include <string> | 6 #include <string> |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/string16.h" |
| 11 #include "base/strings/utf_string_conversions.h" |
10 #include "base/threading/platform_thread.h" | 12 #include "base/threading/platform_thread.h" |
11 #include "ipc/ipc_test_base.h" | 13 #include "ipc/ipc_test_base.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
13 | 15 |
14 // IPC messages for testing ---------------------------------------------------- | 16 // IPC messages for testing ---------------------------------------------------- |
15 | 17 |
16 #define IPC_MESSAGE_IMPL | 18 #define IPC_MESSAGE_IMPL |
17 #include "ipc/ipc_message_macros.h" | 19 #include "ipc/ipc_message_macros.h" |
18 | 20 |
19 #define IPC_MESSAGE_START TestMsgStart | 21 #define IPC_MESSAGE_START TestMsgStart |
20 | 22 |
21 // Generic message class that is an int followed by a wstring. | 23 // Generic message class that is an int followed by a string16. |
22 IPC_MESSAGE_CONTROL2(MsgClassIS, int, std::wstring) | 24 IPC_MESSAGE_CONTROL2(MsgClassIS, int, base::string16) |
23 | 25 |
24 // Generic message class that is a wstring followed by an int. | 26 // Generic message class that is a string16 followed by an int. |
25 IPC_MESSAGE_CONTROL2(MsgClassSI, std::wstring, int) | 27 IPC_MESSAGE_CONTROL2(MsgClassSI, base::string16, int) |
26 | 28 |
27 // Message to create a mutex in the IPC server, using the received name. | 29 // Message to create a mutex in the IPC server, using the received name. |
28 IPC_MESSAGE_CONTROL2(MsgDoMutex, std::wstring, int) | 30 IPC_MESSAGE_CONTROL2(MsgDoMutex, base::string16, int) |
29 | 31 |
30 // Used to generate an ID for a message that should not exist. | 32 // Used to generate an ID for a message that should not exist. |
31 IPC_MESSAGE_CONTROL0(MsgUnhandled) | 33 IPC_MESSAGE_CONTROL0(MsgUnhandled) |
32 | 34 |
33 // ----------------------------------------------------------------------------- | 35 // ----------------------------------------------------------------------------- |
34 | 36 |
35 namespace { | 37 namespace { |
36 | 38 |
37 TEST(IPCMessageIntegrity, ReadBeyondBufferStr) { | 39 TEST(IPCMessageIntegrity, ReadBeyondBufferStr) { |
38 //This was BUG 984408. | 40 // This was BUG 984408. |
39 uint32 v1 = kuint32max - 1; | 41 uint32 v1 = kuint32max - 1; |
40 int v2 = 666; | 42 int v2 = 666; |
41 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); | 43 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); |
42 EXPECT_TRUE(m.WriteInt(v1)); | 44 EXPECT_TRUE(m.WriteInt(v1)); |
43 EXPECT_TRUE(m.WriteInt(v2)); | 45 EXPECT_TRUE(m.WriteInt(v2)); |
44 | 46 |
45 PickleIterator iter(m); | 47 PickleIterator iter(m); |
46 std::string vs; | 48 std::string vs; |
47 EXPECT_FALSE(iter.ReadString(&vs)); | 49 EXPECT_FALSE(iter.ReadString(&vs)); |
48 } | 50 } |
49 | 51 |
50 TEST(IPCMessageIntegrity, ReadBeyondBufferWStr) { | 52 TEST(IPCMessageIntegrity, ReadBeyondBufferStr16) { |
51 //This was BUG 984408. | 53 // This was BUG 984408. |
52 uint32 v1 = kuint32max - 1; | 54 uint32 v1 = kuint32max - 1; |
53 int v2 = 777; | 55 int v2 = 777; |
54 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); | 56 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); |
55 EXPECT_TRUE(m.WriteInt(v1)); | 57 EXPECT_TRUE(m.WriteInt(v1)); |
56 EXPECT_TRUE(m.WriteInt(v2)); | 58 EXPECT_TRUE(m.WriteInt(v2)); |
57 | 59 |
58 PickleIterator iter(m); | 60 PickleIterator iter(m); |
59 std::wstring vs; | 61 base::string16 vs; |
60 EXPECT_FALSE(iter.ReadWString(&vs)); | 62 EXPECT_FALSE(iter.ReadString16(&vs)); |
61 } | 63 } |
62 | 64 |
63 TEST(IPCMessageIntegrity, ReadBytesBadIterator) { | 65 TEST(IPCMessageIntegrity, ReadBytesBadIterator) { |
64 // This was BUG 1035467. | 66 // This was BUG 1035467. |
65 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); | 67 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); |
66 EXPECT_TRUE(m.WriteInt(1)); | 68 EXPECT_TRUE(m.WriteInt(1)); |
67 EXPECT_TRUE(m.WriteInt(2)); | 69 EXPECT_TRUE(m.WriteInt(2)); |
68 | 70 |
69 PickleIterator iter(m); | 71 PickleIterator iter(m); |
70 const char* data = NULL; | 72 const char* data = NULL; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 IPC_END_MESSAGE_MAP() | 146 IPC_END_MESSAGE_MAP() |
145 if (pending_messages_) { | 147 if (pending_messages_) { |
146 // Probably a problem de-serializing the message. | 148 // Probably a problem de-serializing the message. |
147 ReplyMsgNotHandled(msg.type()); | 149 ReplyMsgNotHandled(msg.type()); |
148 } | 150 } |
149 } | 151 } |
150 return true; | 152 return true; |
151 } | 153 } |
152 | 154 |
153 private: | 155 private: |
154 void OnMsgClassISMessage(int value, const std::wstring& text) { | 156 void OnMsgClassISMessage(int value, const base::string16& text) { |
155 UseData(MsgClassIS::ID, value, text); | 157 UseData(MsgClassIS::ID, value, text); |
156 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassIS::ID, value); | 158 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassIS::ID, value); |
157 Cleanup(); | 159 Cleanup(); |
158 } | 160 } |
159 | 161 |
160 void OnMsgClassSIMessage(const std::wstring& text, int value) { | 162 void OnMsgClassSIMessage(const base::string16& text, int value) { |
161 UseData(MsgClassSI::ID, value, text); | 163 UseData(MsgClassSI::ID, value, text); |
162 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassSI::ID, value); | 164 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassSI::ID, value); |
163 Cleanup(); | 165 Cleanup(); |
164 } | 166 } |
165 | 167 |
166 bool RoundtripAckReply(int routing, uint32 type_id, int reply) { | 168 bool RoundtripAckReply(int routing, uint32 type_id, int reply) { |
167 IPC::Message* message = new IPC::Message(routing, type_id, | 169 IPC::Message* message = new IPC::Message(routing, type_id, |
168 IPC::Message::PRIORITY_NORMAL); | 170 IPC::Message::PRIORITY_NORMAL); |
169 message->WriteInt(reply + 1); | 171 message->WriteInt(reply + 1); |
170 message->WriteInt(reply); | 172 message->WriteInt(reply); |
171 return other_->Send(message); | 173 return other_->Send(message); |
172 } | 174 } |
173 | 175 |
174 void Cleanup() { | 176 void Cleanup() { |
175 --message_count_; | 177 --message_count_; |
176 --pending_messages_; | 178 --pending_messages_; |
177 if (0 == message_count_) | 179 if (0 == message_count_) |
178 base::MessageLoop::current()->Quit(); | 180 base::MessageLoop::current()->Quit(); |
179 } | 181 } |
180 | 182 |
181 void ReplyMsgNotHandled(uint32 type_id) { | 183 void ReplyMsgNotHandled(uint32 type_id) { |
182 RoundtripAckReply(FUZZER_ROUTING_ID, MsgUnhandled::ID, type_id); | 184 RoundtripAckReply(FUZZER_ROUTING_ID, MsgUnhandled::ID, type_id); |
183 Cleanup(); | 185 Cleanup(); |
184 } | 186 } |
185 | 187 |
186 void UseData(int caller, int value, const std::wstring& text) { | 188 void UseData(int caller, int value, const base::string16& text) { |
187 std::wostringstream wos; | 189 std::ostringstream os; |
188 wos << L"IPC fuzzer:" << caller << " [" << value << L" " << text << L"]\n"; | 190 os << "IPC fuzzer:" << caller << " [" << value << " " |
189 std::wstring output = wos.str(); | 191 << base::UTF16ToUTF8(text) << "]\n"; |
190 LOG(WARNING) << output.c_str(); | 192 std::string output = os.str(); |
191 }; | 193 LOG(WARNING) << output; |
| 194 } |
192 | 195 |
193 int message_count_; | 196 int message_count_; |
194 int pending_messages_; | 197 int pending_messages_; |
195 }; | 198 }; |
196 | 199 |
197 class FuzzerClientListener : public SimpleListener { | 200 class FuzzerClientListener : public SimpleListener { |
198 public: | 201 public: |
199 FuzzerClientListener() : last_msg_(NULL) { | 202 FuzzerClientListener() : last_msg_(NULL) { |
200 } | 203 } |
201 | 204 |
(...skipping 28 matching lines...) Expand all Loading... |
230 } | 233 } |
231 | 234 |
232 private: | 235 private: |
233 bool MsgHandlerInternal(uint32 type_id) { | 236 bool MsgHandlerInternal(uint32 type_id) { |
234 base::MessageLoop::current()->Run(); | 237 base::MessageLoop::current()->Run(); |
235 if (NULL == last_msg_) | 238 if (NULL == last_msg_) |
236 return false; | 239 return false; |
237 if (FUZZER_ROUTING_ID != last_msg_->routing_id()) | 240 if (FUZZER_ROUTING_ID != last_msg_->routing_id()) |
238 return false; | 241 return false; |
239 return (type_id == last_msg_->type()); | 242 return (type_id == last_msg_->type()); |
240 }; | 243 } |
241 | 244 |
242 IPC::Message* last_msg_; | 245 IPC::Message* last_msg_; |
243 }; | 246 }; |
244 | 247 |
245 // Runs the fuzzing server child mode. Returns when the preset number of | 248 // Runs the fuzzing server child mode. Returns when the preset number of |
246 // messages have been received. | 249 // messages have been received. |
247 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(FuzzServerClient) { | 250 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(FuzzServerClient) { |
248 base::MessageLoopForIO main_message_loop; | 251 base::MessageLoopForIO main_message_loop; |
249 FuzzerServerListener listener; | 252 FuzzerServerListener listener; |
250 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( | 253 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( |
(...skipping 14 matching lines...) Expand all Loading... |
265 Init("FuzzServerClient"); | 268 Init("FuzzServerClient"); |
266 | 269 |
267 FuzzerClientListener listener; | 270 FuzzerClientListener listener; |
268 CreateChannel(&listener); | 271 CreateChannel(&listener); |
269 listener.Init(channel()); | 272 listener.Init(channel()); |
270 ASSERT_TRUE(ConnectChannel()); | 273 ASSERT_TRUE(ConnectChannel()); |
271 ASSERT_TRUE(StartClient()); | 274 ASSERT_TRUE(StartClient()); |
272 | 275 |
273 IPC::Message* msg = NULL; | 276 IPC::Message* msg = NULL; |
274 int value = 43; | 277 int value = 43; |
275 msg = new MsgClassIS(value, L"expect 43"); | 278 msg = new MsgClassIS(value, base::ASCIIToUTF16("expect 43")); |
276 sender()->Send(msg); | 279 sender()->Send(msg); |
277 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassIS::ID)); | 280 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassIS::ID)); |
278 | 281 |
279 msg = new MsgClassSI(L"expect 44", ++value); | 282 msg = new MsgClassSI(base::ASCIIToUTF16("expect 44"), ++value); |
280 sender()->Send(msg); | 283 sender()->Send(msg); |
281 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassSI::ID)); | 284 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassSI::ID)); |
282 | 285 |
283 EXPECT_TRUE(WaitForClientShutdown()); | 286 EXPECT_TRUE(WaitForClientShutdown()); |
284 DestroyChannel(); | 287 DestroyChannel(); |
285 } | 288 } |
286 | 289 |
287 // This test uses a payload that is smaller than expected. This generates an | 290 // This test uses a payload that is smaller than expected. This generates an |
288 // error while unpacking the IPC buffer which in debug trigger an assertion and | 291 // error while unpacking the IPC buffer which in debug trigger an assertion and |
289 // in release is ignored (!). Right after we generate another valid IPC to make | 292 // in release is ignored (!). Right after we generate another valid IPC to make |
290 // sure framing is working properly. | 293 // sure framing is working properly. |
291 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) | 294 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) |
292 TEST_F(IPCFuzzingTest, MsgBadPayloadShort) { | 295 TEST_F(IPCFuzzingTest, MsgBadPayloadShort) { |
293 Init("FuzzServerClient"); | 296 Init("FuzzServerClient"); |
294 | 297 |
295 FuzzerClientListener listener; | 298 FuzzerClientListener listener; |
296 CreateChannel(&listener); | 299 CreateChannel(&listener); |
297 listener.Init(channel()); | 300 listener.Init(channel()); |
298 ASSERT_TRUE(ConnectChannel()); | 301 ASSERT_TRUE(ConnectChannel()); |
299 ASSERT_TRUE(StartClient()); | 302 ASSERT_TRUE(StartClient()); |
300 | 303 |
301 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassIS::ID, | 304 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassIS::ID, |
302 IPC::Message::PRIORITY_NORMAL); | 305 IPC::Message::PRIORITY_NORMAL); |
303 msg->WriteInt(666); | 306 msg->WriteInt(666); |
304 sender()->Send(msg); | 307 sender()->Send(msg); |
305 EXPECT_TRUE(listener.ExpectMsgNotHandled(MsgClassIS::ID)); | 308 EXPECT_TRUE(listener.ExpectMsgNotHandled(MsgClassIS::ID)); |
306 | 309 |
307 msg = new MsgClassSI(L"expect one", 1); | 310 msg = new MsgClassSI(base::ASCIIToUTF16("expect one"), 1); |
308 sender()->Send(msg); | 311 sender()->Send(msg); |
309 EXPECT_TRUE(listener.ExpectMessage(1, MsgClassSI::ID)); | 312 EXPECT_TRUE(listener.ExpectMessage(1, MsgClassSI::ID)); |
310 | 313 |
311 EXPECT_TRUE(WaitForClientShutdown()); | 314 EXPECT_TRUE(WaitForClientShutdown()); |
312 DestroyChannel(); | 315 DestroyChannel(); |
313 } | 316 } |
314 #endif | 317 #endif |
315 | 318 |
316 // This test uses a payload that has too many arguments, but so the payload size | 319 // This test uses a payload that has too many arguments, but so the payload size |
317 // is big enough so the unpacking routine does not generate an error as in the | 320 // is big enough so the unpacking routine does not generate an error as in the |
318 // case of MsgBadPayloadShort test. This test does not pinpoint a flaw (per se) | 321 // case of MsgBadPayloadShort test. This test does not pinpoint a flaw (per se) |
319 // as by design we don't carry type information on the IPC message. | 322 // as by design we don't carry type information on the IPC message. |
320 TEST_F(IPCFuzzingTest, MsgBadPayloadArgs) { | 323 TEST_F(IPCFuzzingTest, MsgBadPayloadArgs) { |
321 Init("FuzzServerClient"); | 324 Init("FuzzServerClient"); |
322 | 325 |
323 FuzzerClientListener listener; | 326 FuzzerClientListener listener; |
324 CreateChannel(&listener); | 327 CreateChannel(&listener); |
325 listener.Init(channel()); | 328 listener.Init(channel()); |
326 ASSERT_TRUE(ConnectChannel()); | 329 ASSERT_TRUE(ConnectChannel()); |
327 ASSERT_TRUE(StartClient()); | 330 ASSERT_TRUE(StartClient()); |
328 | 331 |
329 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassSI::ID, | 332 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassSI::ID, |
330 IPC::Message::PRIORITY_NORMAL); | 333 IPC::Message::PRIORITY_NORMAL); |
331 msg->WriteWString(L"d"); | 334 msg->WriteString16(base::ASCIIToUTF16("d")); |
332 msg->WriteInt(0); | 335 msg->WriteInt(0); |
333 msg->WriteInt(0x65); // Extra argument. | 336 msg->WriteInt(0x65); // Extra argument. |
334 | 337 |
335 sender()->Send(msg); | 338 sender()->Send(msg); |
336 EXPECT_TRUE(listener.ExpectMessage(0, MsgClassSI::ID)); | 339 EXPECT_TRUE(listener.ExpectMessage(0, MsgClassSI::ID)); |
337 | 340 |
338 // Now send a well formed message to make sure the receiver wasn't | 341 // Now send a well formed message to make sure the receiver wasn't |
339 // thrown out of sync by the extra argument. | 342 // thrown out of sync by the extra argument. |
340 msg = new MsgClassIS(3, L"expect three"); | 343 msg = new MsgClassIS(3, base::ASCIIToUTF16("expect three")); |
341 sender()->Send(msg); | 344 sender()->Send(msg); |
342 EXPECT_TRUE(listener.ExpectMessage(3, MsgClassIS::ID)); | 345 EXPECT_TRUE(listener.ExpectMessage(3, MsgClassIS::ID)); |
343 | 346 |
344 EXPECT_TRUE(WaitForClientShutdown()); | 347 EXPECT_TRUE(WaitForClientShutdown()); |
345 DestroyChannel(); | 348 DestroyChannel(); |
346 } | 349 } |
347 | 350 |
348 } // namespace | 351 } // namespace |
OLD | NEW |