blob: 6eb93054c66cbe441ebb9420b8e253ec2b835801 [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
tfarina10a5c062015-09-04 18:47:575#include <stdint.h>
initial.commit09911bf2008-07-26 23:55:296#include <stdio.h>
tfarina10a5c062015-09-04 18:47:577
tfarina7023f522015-09-11 19:58:488#include <limits>
initial.commit09911bf2008-07-26 23:55:299#include <sstream>
tfarina10a5c062015-09-04 18:47:5710#include <string>
initial.commit09911bf2008-07-26 23:55:2911
[email protected]2a9ec0e2013-07-17 23:00:3012#include "base/message_loop/message_loop.h"
thestigf84f17f2015-03-11 20:41:5513#include "base/strings/string16.h"
14#include "base/strings/utf_string_conversions.h"
[email protected]f214f8792011-01-01 02:17:0815#include "base/threading/platform_thread.h"
avi246998d82015-12-22 02:39:0416#include "build/build_config.h"
[email protected]0cb7d8c82013-01-11 15:13:3717#include "ipc/ipc_test_base.h"
initial.commit09911bf2008-07-26 23:55:2918#include "testing/gtest/include/gtest/gtest.h"
19
[email protected]2a3aa7b52013-01-11 20:56:2220// IPC messages for testing ----------------------------------------------------
[email protected]1d4ecf42011-08-26 21:27:3021
22#define IPC_MESSAGE_IMPL
23#include "ipc/ipc_message_macros.h"
24
25#define IPC_MESSAGE_START TestMsgStart
26
thestigf84f17f2015-03-11 20:41:5527// Generic message class that is an int followed by a string16.
28IPC_MESSAGE_CONTROL2(MsgClassIS, int, base::string16)
[email protected]1d4ecf42011-08-26 21:27:3029
thestigf84f17f2015-03-11 20:41:5530// Generic message class that is a string16 followed by an int.
31IPC_MESSAGE_CONTROL2(MsgClassSI, base::string16, int)
[email protected]1d4ecf42011-08-26 21:27:3032
33// Message to create a mutex in the IPC server, using the received name.
thestigf84f17f2015-03-11 20:41:5534IPC_MESSAGE_CONTROL2(MsgDoMutex, base::string16, int)
[email protected]1d4ecf42011-08-26 21:27:3035
36// Used to generate an ID for a message that should not exist.
37IPC_MESSAGE_CONTROL0(MsgUnhandled)
38
[email protected]2a3aa7b52013-01-11 20:56:2239// -----------------------------------------------------------------------------
40
41namespace {
[email protected]1d4ecf42011-08-26 21:27:3042
initial.commit09911bf2008-07-26 23:55:2943TEST(IPCMessageIntegrity, ReadBeyondBufferStr) {
thestigf84f17f2015-03-11 20:41:5544 // This was BUG 984408.
tfarina7023f522015-09-11 19:58:4845 uint32_t v1 = std::numeric_limits<uint32_t>::max() - 1;
initial.commit09911bf2008-07-26 23:55:2946 int v2 = 666;
[email protected]753bb252013-11-04 22:28:1247 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2948 EXPECT_TRUE(m.WriteInt(v1));
49 EXPECT_TRUE(m.WriteInt(v2));
50
brettwbd4d7112015-06-03 04:29:2551 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:2952 std::string vs;
avi48fc13b2014-12-28 23:31:4853 EXPECT_FALSE(iter.ReadString(&vs));
initial.commit09911bf2008-07-26 23:55:2954}
55
thestigf84f17f2015-03-11 20:41:5556TEST(IPCMessageIntegrity, ReadBeyondBufferStr16) {
57 // This was BUG 984408.
tfarina7023f522015-09-11 19:58:4858 uint32_t v1 = std::numeric_limits<uint32_t>::max() - 1;
initial.commit09911bf2008-07-26 23:55:2959 int v2 = 777;
[email protected]753bb252013-11-04 22:28:1260 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2961 EXPECT_TRUE(m.WriteInt(v1));
62 EXPECT_TRUE(m.WriteInt(v2));
63
brettwbd4d7112015-06-03 04:29:2564 base::PickleIterator iter(m);
thestigf84f17f2015-03-11 20:41:5565 base::string16 vs;
66 EXPECT_FALSE(iter.ReadString16(&vs));
initial.commit09911bf2008-07-26 23:55:2967}
68
69TEST(IPCMessageIntegrity, ReadBytesBadIterator) {
70 // This was BUG 1035467.
[email protected]753bb252013-11-04 22:28:1271 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2972 EXPECT_TRUE(m.WriteInt(1));
73 EXPECT_TRUE(m.WriteInt(2));
74
brettwbd4d7112015-06-03 04:29:2575 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:2976 const char* data = NULL;
avi48fc13b2014-12-28 23:31:4877 EXPECT_TRUE(iter.ReadBytes(&data, sizeof(int)));
initial.commit09911bf2008-07-26 23:55:2978}
79
80TEST(IPCMessageIntegrity, ReadVectorNegativeSize) {
81 // A slight variation of BUG 984408. Note that the pickling of vector<char>
82 // has a specialized template which is not vulnerable to this bug. So here
83 // try to hit the non-specialized case vector<P>.
[email protected]753bb252013-11-04 22:28:1284 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:2985 EXPECT_TRUE(m.WriteInt(-1)); // This is the count of elements.
86 EXPECT_TRUE(m.WriteInt(1));
87 EXPECT_TRUE(m.WriteInt(2));
88 EXPECT_TRUE(m.WriteInt(3));
89
90 std::vector<double> vec;
brettwbd4d7112015-06-03 04:29:2591 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:2992 EXPECT_FALSE(ReadParam(&m, &iter, &vec));
93}
94
tfarina8514f0d2015-07-28 14:41:4795#if defined(OS_ANDROID)
96#define MAYBE_ReadVectorTooLarge1 DISABLED_ReadVectorTooLarge1
97#else
98#define MAYBE_ReadVectorTooLarge1 ReadVectorTooLarge1
99#endif
100TEST(IPCMessageIntegrity, MAYBE_ReadVectorTooLarge1) {
initial.commit09911bf2008-07-26 23:55:29101 // This was BUG 1006367. This is the large but positive length case. Again
102 // we try to hit the non-specialized case vector<P>.
[email protected]753bb252013-11-04 22:28:12103 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29104 EXPECT_TRUE(m.WriteInt(0x21000003)); // This is the count of elements.
105 EXPECT_TRUE(m.WriteInt64(1));
106 EXPECT_TRUE(m.WriteInt64(2));
107
tfarina10a5c062015-09-04 18:47:57108 std::vector<int64_t> vec;
brettwbd4d7112015-06-03 04:29:25109 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:29110 EXPECT_FALSE(ReadParam(&m, &iter, &vec));
111}
112
113TEST(IPCMessageIntegrity, ReadVectorTooLarge2) {
114 // This was BUG 1006367. This is the large but positive with an additional
115 // integer overflow when computing the actual byte size. Again we try to hit
116 // the non-specialized case vector<P>.
[email protected]753bb252013-11-04 22:28:12117 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29118 EXPECT_TRUE(m.WriteInt(0x71000000)); // This is the count of elements.
119 EXPECT_TRUE(m.WriteInt64(1));
120 EXPECT_TRUE(m.WriteInt64(2));
121
tfarina10a5c062015-09-04 18:47:57122 std::vector<int64_t> vec;
brettwbd4d7112015-06-03 04:29:25123 base::PickleIterator iter(m);
initial.commit09911bf2008-07-26 23:55:29124 EXPECT_FALSE(ReadParam(&m, &iter, &vec));
125}
126
[email protected]57319ce2012-06-11 22:35:26127class SimpleListener : public IPC::Listener {
initial.commit09911bf2008-07-26 23:55:29128 public:
129 SimpleListener() : other_(NULL) {
130 }
[email protected]57319ce2012-06-11 22:35:26131 void Init(IPC::Sender* s) {
initial.commit09911bf2008-07-26 23:55:29132 other_ = s;
133 }
134 protected:
[email protected]57319ce2012-06-11 22:35:26135 IPC::Sender* other_;
initial.commit09911bf2008-07-26 23:55:29136};
137
138enum {
139 FUZZER_ROUTING_ID = 5
140};
141
142// The fuzzer server class. It runs in a child process and expects
143// only two IPC calls; after that it exits the message loop which
144// terminates the child process.
145class FuzzerServerListener : public SimpleListener {
146 public:
147 FuzzerServerListener() : message_count_(2), pending_messages_(0) {
148 }
dchengfe61fca2014-10-22 02:29:52149 bool OnMessageReceived(const IPC::Message& msg) override {
initial.commit09911bf2008-07-26 23:55:29150 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
151 ++pending_messages_;
152 IPC_BEGIN_MESSAGE_MAP(FuzzerServerListener, msg)
153 IPC_MESSAGE_HANDLER(MsgClassIS, OnMsgClassISMessage)
154 IPC_MESSAGE_HANDLER(MsgClassSI, OnMsgClassSIMessage)
155 IPC_END_MESSAGE_MAP()
156 if (pending_messages_) {
157 // Probably a problem de-serializing the message.
158 ReplyMsgNotHandled(msg.type());
159 }
160 }
[email protected]a95986a82010-12-24 06:19:28161 return true;
initial.commit09911bf2008-07-26 23:55:29162 }
163
164 private:
thestigf84f17f2015-03-11 20:41:55165 void OnMsgClassISMessage(int value, const base::string16& text) {
initial.commit09911bf2008-07-26 23:55:29166 UseData(MsgClassIS::ID, value, text);
167 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassIS::ID, value);
168 Cleanup();
169 }
170
thestigf84f17f2015-03-11 20:41:55171 void OnMsgClassSIMessage(const base::string16& text, int value) {
initial.commit09911bf2008-07-26 23:55:29172 UseData(MsgClassSI::ID, value, text);
173 RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassSI::ID, value);
174 Cleanup();
175 }
176
tfarina10a5c062015-09-04 18:47:57177 bool RoundtripAckReply(int routing, uint32_t type_id, int reply) {
[email protected]753bb252013-11-04 22:28:12178 IPC::Message* message = new IPC::Message(routing, type_id,
179 IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29180 message->WriteInt(reply + 1);
181 message->WriteInt(reply);
182 return other_->Send(message);
183 }
184
185 void Cleanup() {
186 --message_count_;
187 --pending_messages_;
188 if (0 == message_count_)
ki.stfua21ed8c2015-10-12 17:26:00189 base::MessageLoop::current()->QuitWhenIdle();
initial.commit09911bf2008-07-26 23:55:29190 }
191
tfarina10a5c062015-09-04 18:47:57192 void ReplyMsgNotHandled(uint32_t type_id) {
[email protected]1d4ecf42011-08-26 21:27:30193 RoundtripAckReply(FUZZER_ROUTING_ID, MsgUnhandled::ID, type_id);
initial.commit09911bf2008-07-26 23:55:29194 Cleanup();
195 }
196
thestigf84f17f2015-03-11 20:41:55197 void UseData(int caller, int value, const base::string16& text) {
198 std::ostringstream os;
199 os << "IPC fuzzer:" << caller << " [" << value << " "
200 << base::UTF16ToUTF8(text) << "]\n";
201 std::string output = os.str();
202 LOG(WARNING) << output;
203 }
initial.commit09911bf2008-07-26 23:55:29204
205 int message_count_;
206 int pending_messages_;
207};
208
209class FuzzerClientListener : public SimpleListener {
210 public:
211 FuzzerClientListener() : last_msg_(NULL) {
212 }
213
dchengfe61fca2014-10-22 02:29:52214 bool OnMessageReceived(const IPC::Message& msg) override {
initial.commit09911bf2008-07-26 23:55:29215 last_msg_ = new IPC::Message(msg);
ki.stfua21ed8c2015-10-12 17:26:00216 base::MessageLoop::current()->QuitWhenIdle();
[email protected]a95986a82010-12-24 06:19:28217 return true;
initial.commit09911bf2008-07-26 23:55:29218 }
219
tfarina10a5c062015-09-04 18:47:57220 bool ExpectMessage(int value, uint32_t type_id) {
initial.commit09911bf2008-07-26 23:55:29221 if (!MsgHandlerInternal(type_id))
222 return false;
223 int msg_value1 = 0;
224 int msg_value2 = 0;
brettwbd4d7112015-06-03 04:29:25225 base::PickleIterator iter(*last_msg_);
avi48fc13b2014-12-28 23:31:48226 if (!iter.ReadInt(&msg_value1))
initial.commit09911bf2008-07-26 23:55:29227 return false;
avi48fc13b2014-12-28 23:31:48228 if (!iter.ReadInt(&msg_value2))
initial.commit09911bf2008-07-26 23:55:29229 return false;
230 if ((msg_value2 + 1) != msg_value1)
231 return false;
232 if (msg_value2 != value)
233 return false;
234
235 delete last_msg_;
236 last_msg_ = NULL;
237 return true;
238 }
239
tfarina10a5c062015-09-04 18:47:57240 bool ExpectMsgNotHandled(uint32_t type_id) {
[email protected]1d4ecf42011-08-26 21:27:30241 return ExpectMessage(type_id, MsgUnhandled::ID);
initial.commit09911bf2008-07-26 23:55:29242 }
243
244 private:
tfarina10a5c062015-09-04 18:47:57245 bool MsgHandlerInternal(uint32_t type_id) {
[email protected]fd0a773a2013-04-30 20:55:03246 base::MessageLoop::current()->Run();
initial.commit09911bf2008-07-26 23:55:29247 if (NULL == last_msg_)
248 return false;
249 if (FUZZER_ROUTING_ID != last_msg_->routing_id())
250 return false;
251 return (type_id == last_msg_->type());
thestigf84f17f2015-03-11 20:41:55252 }
initial.commit09911bf2008-07-26 23:55:29253
254 IPC::Message* last_msg_;
255};
256
[email protected]3c788582013-01-25 21:51:35257// Runs the fuzzing server child mode. Returns when the preset number of
258// messages have been received.
259MULTIPROCESS_IPC_TEST_CLIENT_MAIN(FuzzServerClient) {
[email protected]fd0a773a2013-04-30 20:55:03260 base::MessageLoopForIO main_message_loop;
initial.commit09911bf2008-07-26 23:55:29261 FuzzerServerListener listener;
[email protected]e482111a82014-05-30 03:58:59262 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
erikchen30dc2812015-09-24 03:26:38263 IPCTestBase::GetChannelName("FuzzServerClient"), &listener));
[email protected]e482111a82014-05-30 03:58:59264 CHECK(channel->Connect());
265 listener.Init(channel.get());
[email protected]fd0a773a2013-04-30 20:55:03266 base::MessageLoop::current()->Run();
[email protected]95cb7fb92008-12-09 22:00:47267 return 0;
initial.commit09911bf2008-07-26 23:55:29268}
269
[email protected]0cb7d8c82013-01-11 15:13:37270class IPCFuzzingTest : public IPCTestBase {
[email protected]95cb7fb92008-12-09 22:00:47271};
272
tfarina8514f0d2015-07-28 14:41:47273#if defined(OS_ANDROID)
274#define MAYBE_SanityTest DISABLED_SanityTest
275#else
276#define MAYBE_SanityTest SanityTest
277#endif
initial.commit09911bf2008-07-26 23:55:29278// This test makes sure that the FuzzerClientListener and FuzzerServerListener
279// are working properly by generating two well formed IPC calls.
tfarina8514f0d2015-07-28 14:41:47280TEST_F(IPCFuzzingTest, MAYBE_SanityTest) {
[email protected]3c788582013-01-25 21:51:35281 Init("FuzzServerClient");
282
[email protected]df3c1ca12008-12-19 21:37:01283 FuzzerClientListener listener;
[email protected]3c788582013-01-25 21:51:35284 CreateChannel(&listener);
285 listener.Init(channel());
286 ASSERT_TRUE(ConnectChannel());
287 ASSERT_TRUE(StartClient());
initial.commit09911bf2008-07-26 23:55:29288
289 IPC::Message* msg = NULL;
290 int value = 43;
thestigf84f17f2015-03-11 20:41:55291 msg = new MsgClassIS(value, base::ASCIIToUTF16("expect 43"));
[email protected]3c788582013-01-25 21:51:35292 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29293 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassIS::ID));
294
thestigf84f17f2015-03-11 20:41:55295 msg = new MsgClassSI(base::ASCIIToUTF16("expect 44"), ++value);
[email protected]3c788582013-01-25 21:51:35296 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29297 EXPECT_TRUE(listener.ExpectMessage(value, MsgClassSI::ID));
298
[email protected]3c788582013-01-25 21:51:35299 EXPECT_TRUE(WaitForClientShutdown());
300 DestroyChannel();
initial.commit09911bf2008-07-26 23:55:29301}
302
tfarina8514f0d2015-07-28 14:41:47303#if defined(OS_ANDROID)
304#define MAYBE_MsgBadPayloadShort DISABLED_MsgBadPayloadShort
305#else
306#define MAYBE_MsgBadPayloadShort MsgBadPayloadShort
307#endif
[email protected]3c788582013-01-25 21:51:35308// This test uses a payload that is smaller than expected. This generates an
309// error while unpacking the IPC buffer which in debug trigger an assertion and
310// in release is ignored (!). Right after we generate another valid IPC to make
311// sure framing is working properly.
[email protected]20960e072011-09-20 20:59:01312#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
tfarina8514f0d2015-07-28 14:41:47313TEST_F(IPCFuzzingTest, MAYBE_MsgBadPayloadShort) {
[email protected]3c788582013-01-25 21:51:35314 Init("FuzzServerClient");
315
[email protected]df3c1ca12008-12-19 21:37:01316 FuzzerClientListener listener;
[email protected]3c788582013-01-25 21:51:35317 CreateChannel(&listener);
318 listener.Init(channel());
319 ASSERT_TRUE(ConnectChannel());
320 ASSERT_TRUE(StartClient());
initial.commit09911bf2008-07-26 23:55:29321
[email protected]753bb252013-11-04 22:28:12322 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassIS::ID,
323 IPC::Message::PRIORITY_NORMAL);
initial.commit09911bf2008-07-26 23:55:29324 msg->WriteInt(666);
[email protected]3c788582013-01-25 21:51:35325 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29326 EXPECT_TRUE(listener.ExpectMsgNotHandled(MsgClassIS::ID));
327
thestigf84f17f2015-03-11 20:41:55328 msg = new MsgClassSI(base::ASCIIToUTF16("expect one"), 1);
[email protected]3c788582013-01-25 21:51:35329 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29330 EXPECT_TRUE(listener.ExpectMessage(1, MsgClassSI::ID));
331
[email protected]3c788582013-01-25 21:51:35332 EXPECT_TRUE(WaitForClientShutdown());
333 DestroyChannel();
initial.commit09911bf2008-07-26 23:55:29334}
[email protected]20960e072011-09-20 20:59:01335#endif
initial.commit09911bf2008-07-26 23:55:29336
tfarina8514f0d2015-07-28 14:41:47337#if defined(OS_ANDROID)
338#define MAYBE_MsgBadPayloadArgs DISABLED_MsgBadPayloadArgs
339#else
340#define MAYBE_MsgBadPayloadArgs MsgBadPayloadArgs
341#endif
[email protected]3c788582013-01-25 21:51:35342// This test uses a payload that has too many arguments, but so the payload size
343// is big enough so the unpacking routine does not generate an error as in the
344// case of MsgBadPayloadShort test. This test does not pinpoint a flaw (per se)
345// as by design we don't carry type information on the IPC message.
tfarina8514f0d2015-07-28 14:41:47346TEST_F(IPCFuzzingTest, MAYBE_MsgBadPayloadArgs) {
[email protected]3c788582013-01-25 21:51:35347 Init("FuzzServerClient");
348
[email protected]df3c1ca12008-12-19 21:37:01349 FuzzerClientListener listener;
[email protected]3c788582013-01-25 21:51:35350 CreateChannel(&listener);
351 listener.Init(channel());
352 ASSERT_TRUE(ConnectChannel());
353 ASSERT_TRUE(StartClient());
initial.commit09911bf2008-07-26 23:55:29354
[email protected]753bb252013-11-04 22:28:12355 IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassSI::ID,
356 IPC::Message::PRIORITY_NORMAL);
thestigf84f17f2015-03-11 20:41:55357 msg->WriteString16(base::ASCIIToUTF16("d"));
initial.commit09911bf2008-07-26 23:55:29358 msg->WriteInt(0);
[email protected]95cb7fb92008-12-09 22:00:47359 msg->WriteInt(0x65); // Extra argument.
360
[email protected]3c788582013-01-25 21:51:35361 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29362 EXPECT_TRUE(listener.ExpectMessage(0, MsgClassSI::ID));
363
[email protected]95cb7fb92008-12-09 22:00:47364 // Now send a well formed message to make sure the receiver wasn't
365 // thrown out of sync by the extra argument.
thestigf84f17f2015-03-11 20:41:55366 msg = new MsgClassIS(3, base::ASCIIToUTF16("expect three"));
[email protected]3c788582013-01-25 21:51:35367 sender()->Send(msg);
initial.commit09911bf2008-07-26 23:55:29368 EXPECT_TRUE(listener.ExpectMessage(3, MsgClassIS::ID));
369
[email protected]3c788582013-01-25 21:51:35370 EXPECT_TRUE(WaitForClientShutdown());
371 DestroyChannel();
initial.commit09911bf2008-07-26 23:55:29372}
373
[email protected]2a3aa7b52013-01-11 20:56:22374} // namespace