blob: 5dfddbac2be3d335dc205e474c82105dc235d08c [file] [log] [blame]
[email protected]b5393332012-01-13 00:11:011// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
initial.commit09911bf2008-07-26 23:55:295#include <stdio.h>
initial.commit09911bf2008-07-26 23:55:296#include <string>
7#include <sstream>
8
[email protected]2a9ec0e2013-07-17 23:00:309#include "base/message_loop/message_loop.h"
thestigf84f17f2015-03-11 20:41:5510#include "base/strings/string16.h"
11#include "base/strings/utf_string_conversions.h"
[email protected]f214f8792011-01-01 02:17:0812#include "base/threading/platform_thread.h"
[email protected]0cb7d8c82013-01-11 15:13:3713#include "ipc/ipc_test_base.h"
initial.commit09911bf2008-07-26 23:55:2914#include "testing/gtest/include/gtest/gtest.h"
15
[email protected]2a3aa7b52013-01-11 20:56:2216// IPC messages for testing ----------------------------------------------------
[email protected]1d4ecf42011-08-26 21:27:3017
18#define IPC_MESSAGE_IMPL
19#include "ipc/ipc_message_macros.h"
20
21#define IPC_MESSAGE_START TestMsgStart
22
thestigf84f17f2015-03-11 20:41:5523// Generic message class that is an int followed by a string16.
24IPC_MESSAGE_CONTROL2(MsgClassIS, int, base::string16)
[email protected]1d4ecf42011-08-26 21:27:3025
thestigf84f17f2015-03-11 20:41:5526// Generic message class that is a string16 followed by an int.
27IPC_MESSAGE_CONTROL2(MsgClassSI, base::string16, int)
[email protected]1d4ecf42011-08-26 21:27:3028
29// Message to create a mutex in the IPC server, using the received name.
thestigf84f17f2015-03-11 20:41:5530IPC_MESSAGE_CONTROL2(MsgDoMutex, base::string16, int)
[email protected]1d4ecf42011-08-26 21:27:3031
32// Used to generate an ID for a message that should not exist.
33IPC_MESSAGE_CONTROL0(MsgUnhandled)
34
[email protected]2a3aa7b52013-01-11 20:56:2235// -----------------------------------------------------------------------------
36
37namespace {
[email protected]1d4ecf42011-08-26 21:27:3038
initial.commit09911bf2008-07-26 23:55:2939TEST(IPCMessageIntegrity, ReadBeyondBufferStr) {
thestigf84f17f2015-03-11 20:41:5540 // This was BUG 984408.
initial.commit09911bf2008-07-26 23:55:2941 uint32 v1 = kuint32max - 1;
42 int v2 = 666;
[email protected]753bb252013-11-04 22:28:1243 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2944 EXPECT_TRUE(m.WriteInt(v1));
45 EXPECT_TRUE(m.WriteInt(v2));
46
brettwbd4d7112015-06-03 04:29:2547 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:2948 std::string vs;
avi48fc13b2014-12-28 23:31:4849 EXPECT_FALSE(iter.ReadString(&vs));
initial.commit09911bf2008-07-26 23:55:2950}
51
thestigf84f17f2015-03-11 20:41:5552TEST(IPCMessageIntegrity, ReadBeyondBufferStr16) {
53 // This was BUG 984408.
initial.commit09911bf2008-07-26 23:55:2954 uint32 v1 = kuint32max - 1;
55 int v2 = 777;
[email protected]753bb252013-11-04 22:28:1256 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2957 EXPECT_TRUE(m.WriteInt(v1));
58 EXPECT_TRUE(m.WriteInt(v2));
59
brettwbd4d7112015-06-03 04:29:2560 base::PickleIterator iter(m);
thestigf84f17f2015-03-11 20:41:5561 base::string16 vs;
62 EXPECT_FALSE(iter.ReadString16(&vs));
initial.commit09911bf2008-07-26 23:55:2963}
64
65TEST(IPCMessageIntegrity, ReadBytesBadIterator) {
66 // This was BUG 1035467.
[email protected]753bb252013-11-04 22:28:1267 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2968 EXPECT_TRUE(m.WriteInt(1));
69 EXPECT_TRUE(m.WriteInt(2));
70
brettwbd4d7112015-06-03 04:29:2571 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:2972 const char* data = NULL;
avi48fc13b2014-12-28 23:31:4873 EXPECT_TRUE(iter.ReadBytes(&data, sizeof(int)));
initial.commit09911bf2008-07-26 23:55:2974}
75
76TEST(IPCMessageIntegrity, ReadVectorNegativeSize) {
77 // A slight variation of BUG 984408. Note that the pickling of vector<char>
78 // has a specialized template which is not vulnerable to this bug. So here
79 // try to hit the non-specialized case vector<P>.
[email protected]753bb252013-11-04 22:28:1280 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2981 EXPECT_TRUE(m.WriteInt(-1)); // This is the count of elements.
82 EXPECT_TRUE(m.WriteInt(1));
83 EXPECT_TRUE(m.WriteInt(2));
84 EXPECT_TRUE(m.WriteInt(3));
85
86 std::vector<double> vec;
brettwbd4d7112015-06-03 04:29:2587 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:2988 EXPECT_FALSE(ReadParam(&m, &iter, &vec));
89}
90
tfarina8514f0d2015-07-28 14:41:4791#if defined(OS_ANDROID)
92#define MAYBE_ReadVectorTooLarge1 DISABLED_ReadVectorTooLarge1
93#else
94#define MAYBE_ReadVectorTooLarge1 ReadVectorTooLarge1
95#endif
96TEST(IPCMessageIntegrity, MAYBE_ReadVectorTooLarge1) {
initial.commit09911bf2008-07-26 23:55:2997 // This was BUG 1006367. This is the large but positive length case. Again
98 // we try to hit the non-specialized case vector<P>.
[email protected]753bb252013-11-04 22:28:1299 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29100 EXPECT_TRUE(m.WriteInt(0x21000003)); // This is the count of elements.
101 EXPECT_TRUE(m.WriteInt64(1));
102 EXPECT_TRUE(m.WriteInt64(2));
103
104 std::vector<int64> vec;
brettwbd4d7112015-06-03 04:29:25105 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:29106 EXPECT_FALSE(ReadParam(&m, &iter, &vec));
107}
108
109TEST(IPCMessageIntegrity, ReadVectorTooLarge2) {
110 // This was BUG 1006367. This is the large but positive with an additional
111 // integer overflow when computing the actual byte size. Again we try to hit
112 // the non-specialized case vector<P>.
[email protected]753bb252013-11-04 22:28:12113 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29114 EXPECT_TRUE(m.WriteInt(0x71000000)); // This is the count of elements.
115 EXPECT_TRUE(m.WriteInt64(1));
116 EXPECT_TRUE(m.WriteInt64(2));
117
118 std::vector<int64> vec;
brettwbd4d7112015-06-03 04:29:25119 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:29120 EXPECT_FALSE(ReadParam(&m, &iter, &vec));
121}
122
[email protected]57319ce2012-06-11 22:35:26123class SimpleListener : public IPC::Listener {
initial.commit09911bf2008-07-26 23:55:29124 public:
125 SimpleListener() : other_(NULL) {
126 }
[email protected]57319ce2012-06-11 22:35:26127 void Init(IPC::Sender* s) {
initial.commit09911bf2008-07-26 23:55:29128 other_ = s;
129 }
130 protected:
[email protected]57319ce2012-06-11 22:35:26131 IPC::Sender* other_;
initial.commit09911bf2008-07-26 23:55:29132};
133
134enum {
135 FUZZER_ROUTING_ID = 5
136};
137
138// The fuzzer server class. It runs in a child process and expects
139// only two IPC calls; after that it exits the message loop which
140// terminates the child process.
141class FuzzerServerListener : public SimpleListener {
142 public:
143 FuzzerServerListener() : message_count_(2), pending_messages_(0) {
144 }
dchengfe61fca2014-10-22 02:29:52145 bool OnMessageReceived(const IPC::Message& msg) override {
initial.commit09911bf2008-07-26 23:55:29146 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
147 ++pending_messages_;
148 IPC_BEGIN_MESSAGE_MAP(FuzzerServerListener, msg)
149 IPC_MESSAGE_HANDLER(MsgClassIS, OnMsgClassISMessage)
150 IPC_MESSAGE_HANDLER(MsgClassSI, OnMsgClassSIMessage)
151 IPC_END_MESSAGE_MAP()
152 if (pending_messages_) {
153 // Probably a problem de-serializing the message.
154 ReplyMsgNotHandled(msg.type());
155 }
156 }
[email protected]a95986a82010-12-24 06:19:28157 return true;
initial.commit09911bf2008-07-26 23:55:29158 }
159
160 private:
thestigf84f17f2015-03-11 20:41:55161 void OnMsgClassISMessage(int value, const base::string16& text) {
initial.commit09911bf2008-07-26 23:55:29162 UseData(MsgClassIS::ID, value, text);
163 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassIS::ID, value);
164 Cleanup();
165 }
166
thestigf84f17f2015-03-11 20:41:55167 void OnMsgClassSIMessage(const base::string16& text, int value) {
initial.commit09911bf2008-07-26 23:55:29168 UseData(MsgClassSI::ID, value, text);
169 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassSI::ID, value);
170 Cleanup();
171 }
172
[email protected]7ee1a44c2010-07-23 14:18:59173 bool RoundtripAckReply(int routing, uint32 type_id, int reply) {
[email protected]753bb252013-11-04 22:28:12174 IPC::Message* message = new IPC::Message(routing, type_id,
175 IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29176 message->WriteInt(reply + 1);
177 message->WriteInt(reply);
178 return other_->Send(message);
179 }
180
181 void Cleanup() {
182 --message_count_;
183 --pending_messages_;
184 if (0 == message_count_)
[email protected]fd0a773a2013-04-30 20:55:03185 base::MessageLoop::current()->Quit();
initial.commit09911bf2008-07-26 23:55:29186 }
187
[email protected]7ee1a44c2010-07-23 14:18:59188 void ReplyMsgNotHandled(uint32 type_id) {
[email protected]1d4ecf42011-08-26 21:27:30189 RoundtripAckReply(FUZZER_ROUTING_ID, MsgUnhandled::ID, type_id);
initial.commit09911bf2008-07-26 23:55:29190 Cleanup();
191 }
192
thestigf84f17f2015-03-11 20:41:55193 void UseData(int caller, int value, const base::string16& text) {
194 std::ostringstream os;
195 os << "IPC fuzzer:" << caller << " [" << value << " "
196 << base::UTF16ToUTF8(text) << "]\n";
197 std::string output = os.str();
198 LOG(WARNING) << output;
199 }
initial.commit09911bf2008-07-26 23:55:29200
201 int message_count_;
202 int pending_messages_;
203};
204
205class FuzzerClientListener : public SimpleListener {
206 public:
207 FuzzerClientListener() : last_msg_(NULL) {
208 }
209
dchengfe61fca2014-10-22 02:29:52210 bool OnMessageReceived(const IPC::Message& msg) override {
initial.commit09911bf2008-07-26 23:55:29211 last_msg_ = new IPC::Message(msg);
[email protected]fd0a773a2013-04-30 20:55:03212 base::MessageLoop::current()->Quit();
[email protected]a95986a82010-12-24 06:19:28213 return true;
initial.commit09911bf2008-07-26 23:55:29214 }
215
[email protected]7ee1a44c2010-07-23 14:18:59216 bool ExpectMessage(int value, uint32 type_id) {
initial.commit09911bf2008-07-26 23:55:29217 if (!MsgHandlerInternal(type_id))
218 return false;
219 int msg_value1 = 0;
220 int msg_value2 = 0;
brettwbd4d7112015-06-03 04:29:25221 base::PickleIterator iter(*last_msg_);
avi48fc13b2014-12-28 23:31:48222 if (!iter.ReadInt(&msg_value1))
initial.commit09911bf2008-07-26 23:55:29223 return false;
avi48fc13b2014-12-28 23:31:48224 if (!iter.ReadInt(&msg_value2))
initial.commit09911bf2008-07-26 23:55:29225 return false;
226 if ((msg_value2 + 1) != msg_value1)
227 return false;
228 if (msg_value2 != value)
229 return false;
230
231 delete last_msg_;
232 last_msg_ = NULL;
233 return true;
234 }
235
[email protected]7ee1a44c2010-07-23 14:18:59236 bool ExpectMsgNotHandled(uint32 type_id) {
[email protected]1d4ecf42011-08-26 21:27:30237 return ExpectMessage(type_id, MsgUnhandled::ID);
initial.commit09911bf2008-07-26 23:55:29238 }
239
240 private:
[email protected]7ee1a44c2010-07-23 14:18:59241 bool MsgHandlerInternal(uint32 type_id) {
[email protected]fd0a773a2013-04-30 20:55:03242 base::MessageLoop::current()->Run();
initial.commit09911bf2008-07-26 23:55:29243 if (NULL == last_msg_)
244 return false;
245 if (FUZZER_ROUTING_ID != last_msg_->routing_id())
246 return false;
247 return (type_id == last_msg_->type());
thestigf84f17f2015-03-11 20:41:55248 }
initial.commit09911bf2008-07-26 23:55:29249
250 IPC::Message* last_msg_;
251};
252
[email protected]3c788582013-01-25 21:51:35253// Runs the fuzzing server child mode. Returns when the preset number of
254// messages have been received.
255MULTIPROCESS_IPC_TEST_CLIENT_MAIN(FuzzServerClient) {
[email protected]fd0a773a2013-04-30 20:55:03256 base::MessageLoopForIO main_message_loop;
initial.commit09911bf2008-07-26 23:55:29257 FuzzerServerListener listener;
[email protected]e482111a82014-05-30 03:58:59258 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
erikchen27aa7d82015-06-16 21:21:04259 IPCTestBase::GetChannelName("FuzzServerClient"), &listener, nullptr));
[email protected]e482111a82014-05-30 03:58:59260 CHECK(channel->Connect());
261 listener.Init(channel.get());
[email protected]fd0a773a2013-04-30 20:55:03262 base::MessageLoop::current()->Run();
[email protected]95cb7fb92008-12-09 22:00:47263 return 0;
initial.commit09911bf2008-07-26 23:55:29264}
265
[email protected]0cb7d8c82013-01-11 15:13:37266class IPCFuzzingTest : public IPCTestBase {
[email protected]95cb7fb92008-12-09 22:00:47267};
268
tfarina8514f0d2015-07-28 14:41:47269#if defined(OS_ANDROID)
270#define MAYBE_SanityTest DISABLED_SanityTest
271#else
272#define MAYBE_SanityTest SanityTest
273#endif
initial.commit09911bf2008-07-26 23:55:29274// This test makes sure that the FuzzerClientListener and FuzzerServerListener
275// are working properly by generating two well formed IPC calls.
tfarina8514f0d2015-07-28 14:41:47276TEST_F(IPCFuzzingTest, MAYBE_SanityTest) {
[email protected]3c788582013-01-25 21:51:35277 Init("FuzzServerClient");
278
[email protected]df3c1ca12008-12-19 21:37:01279 FuzzerClientListener listener;
[email protected]3c788582013-01-25 21:51:35280 CreateChannel(&listener);
281 listener.Init(channel());
282 ASSERT_TRUE(ConnectChannel());
283 ASSERT_TRUE(StartClient());
initial.commit09911bf2008-07-26 23:55:29284
285 IPC::Message* msg = NULL;
286 int value = 43;
thestigf84f17f2015-03-11 20:41:55287 msg = new MsgClassIS(value, base::ASCIIToUTF16("expect 43"));
[email protected]3c788582013-01-25 21:51:35288 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29289 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassIS::ID));
290
thestigf84f17f2015-03-11 20:41:55291 msg = new MsgClassSI(base::ASCIIToUTF16("expect 44"), ++value);
[email protected]3c788582013-01-25 21:51:35292 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29293 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassSI::ID));
294
[email protected]3c788582013-01-25 21:51:35295 EXPECT_TRUE(WaitForClientShutdown());
296 DestroyChannel();
initial.commit09911bf2008-07-26 23:55:29297}
298
tfarina8514f0d2015-07-28 14:41:47299#if defined(OS_ANDROID)
300#define MAYBE_MsgBadPayloadShort DISABLED_MsgBadPayloadShort
301#else
302#define MAYBE_MsgBadPayloadShort MsgBadPayloadShort
303#endif
[email protected]3c788582013-01-25 21:51:35304// This test uses a payload that is smaller than expected. This generates an
305// error while unpacking the IPC buffer which in debug trigger an assertion and
306// in release is ignored (!). Right after we generate another valid IPC to make
307// sure framing is working properly.
[email protected]20960e072011-09-20 20:59:01308#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
tfarina8514f0d2015-07-28 14:41:47309TEST_F(IPCFuzzingTest, MAYBE_MsgBadPayloadShort) {
[email protected]3c788582013-01-25 21:51:35310 Init("FuzzServerClient");
311
[email protected]df3c1ca12008-12-19 21:37:01312 FuzzerClientListener listener;
[email protected]3c788582013-01-25 21:51:35313 CreateChannel(&listener);
314 listener.Init(channel());
315 ASSERT_TRUE(ConnectChannel());
316 ASSERT_TRUE(StartClient());
initial.commit09911bf2008-07-26 23:55:29317
[email protected]753bb252013-11-04 22:28:12318 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassIS::ID,
319 IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29320 msg->WriteInt(666);
[email protected]3c788582013-01-25 21:51:35321 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29322 EXPECT_TRUE(listener.ExpectMsgNotHandled(MsgClassIS::ID));
323
thestigf84f17f2015-03-11 20:41:55324 msg = new MsgClassSI(base::ASCIIToUTF16("expect one"), 1);
[email protected]3c788582013-01-25 21:51:35325 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29326 EXPECT_TRUE(listener.ExpectMessage(1, MsgClassSI::ID));
327
[email protected]3c788582013-01-25 21:51:35328 EXPECT_TRUE(WaitForClientShutdown());
329 DestroyChannel();
initial.commit09911bf2008-07-26 23:55:29330}
[email protected]20960e072011-09-20 20:59:01331#endif
initial.commit09911bf2008-07-26 23:55:29332
tfarina8514f0d2015-07-28 14:41:47333#if defined(OS_ANDROID)
334#define MAYBE_MsgBadPayloadArgs DISABLED_MsgBadPayloadArgs
335#else
336#define MAYBE_MsgBadPayloadArgs MsgBadPayloadArgs
337#endif
[email protected]3c788582013-01-25 21:51:35338// This test uses a payload that has too many arguments, but so the payload size
339// is big enough so the unpacking routine does not generate an error as in the
340// case of MsgBadPayloadShort test. This test does not pinpoint a flaw (per se)
341// as by design we don't carry type information on the IPC message.
tfarina8514f0d2015-07-28 14:41:47342TEST_F(IPCFuzzingTest, MAYBE_MsgBadPayloadArgs) {
[email protected]3c788582013-01-25 21:51:35343 Init("FuzzServerClient");
344
[email protected]df3c1ca12008-12-19 21:37:01345 FuzzerClientListener listener;
[email protected]3c788582013-01-25 21:51:35346 CreateChannel(&listener);
347 listener.Init(channel());
348 ASSERT_TRUE(ConnectChannel());
349 ASSERT_TRUE(StartClient());
initial.commit09911bf2008-07-26 23:55:29350
[email protected]753bb252013-11-04 22:28:12351 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassSI::ID,
352 IPC::Message::PRIORITY_NORMAL);
thestigf84f17f2015-03-11 20:41:55353 msg->WriteString16(base::ASCIIToUTF16("d"));
initial.commit09911bf2008-07-26 23:55:29354 msg->WriteInt(0);
[email protected]95cb7fb92008-12-09 22:00:47355 msg->WriteInt(0x65); // Extra argument.
356
[email protected]3c788582013-01-25 21:51:35357 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29358 EXPECT_TRUE(listener.ExpectMessage(0, MsgClassSI::ID));
359
[email protected]95cb7fb92008-12-09 22:00:47360 // Now send a well formed message to make sure the receiver wasn't
361 // thrown out of sync by the extra argument.
thestigf84f17f2015-03-11 20:41:55362 msg = new MsgClassIS(3, base::ASCIIToUTF16("expect three"));
[email protected]3c788582013-01-25 21:51:35363 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29364 EXPECT_TRUE(listener.ExpectMessage(3, MsgClassIS::ID));
365
[email protected]3c788582013-01-25 21:51:35366 EXPECT_TRUE(WaitForClientShutdown());
367 DestroyChannel();
initial.commit09911bf2008-07-26 23:55:29368}
369
[email protected]2a3aa7b52013-01-11 20:56:22370} // namespace