Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: tools/ipc_fuzzer/ipc_fuzzer_main.cc

Issue 18254010: IPC fuzzer child process component (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: replace ShouldKillChildProcessOnBadMessage with --disable-kill-after-bad-ipc Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 <limits.h>
6 #include <stdio.h>
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/files/memory_mapped_file.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/posix/global_descriptors.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/threading/thread.h"
18 #include "base/timer/timer.h"
19 #include "ipc/ipc_channel_proxy.h"
20 #include "ipc/ipc_descriptors.h"
21 #include "ipc/ipc_listener.h"
22 #include "ipc/ipc_message.h"
23 #include "ipc/ipc_platform_file.h"
24 #include "ipc/ipc_switches.h"
25
26 namespace {
27
28 const char kIpcFuzzerTestcase[] = "ipc-fuzzer-testcase";
29
30 class IpcFuzzerProcess : public IPC::Listener {
31 public:
32 IpcFuzzerProcess();
33 virtual ~IpcFuzzerProcess();
34 void Initialize(int argc, const char **argv);
35 void OpenChannel();
36 bool OpenTestcase();
37 void StartSendingMessages();
38
39 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
40 virtual void OnChannelError() OVERRIDE;
41
42 private:
43 bool ExtractMessages(const char *data, size_t len);
44 IPC::Message* GetNextMessage();
45 void SendNextMessage();
46
47 scoped_ptr<IPC::ChannelProxy> channel_;
48 base::MessageLoop main_loop_;
49 base::Thread io_thread_;
50 base::WaitableEvent shutdown_event_;
51 scoped_ptr<base::Timer> timer_;
52 scoped_ptr<base::MemoryMappedFile> testcase_map_;
53 std::vector<scoped_ptr<IPC::Message>> messages_;
54 size_t current_message_;
55
56 DISALLOW_COPY_AND_ASSIGN(IpcFuzzerProcess);
57 };
58
59 IpcFuzzerProcess::IpcFuzzerProcess()
60 : main_loop_(base::MessageLoop::TYPE_DEFAULT),
61 io_thread_("Chrome_ChildIOThread"),
62 shutdown_event_(true, false),
63 current_message_(0) {
64 }
65
66 IpcFuzzerProcess::~IpcFuzzerProcess() {
67 }
68
69 void IpcFuzzerProcess::Initialize(int argc, const char **argv) {
70 CommandLine::Init(argc, argv);
71
72 // Log to default destination.
73 logging::SetMinLogLevel(logging::LOG_ERROR);
74 logging::InitLogging(logging::LoggingSettings());
75
76 io_thread_.StartWithOptions(
77 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
78
79 #if defined(OS_POSIX)
80 base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
81 g_fds->Set(kPrimaryIPCChannel,
82 kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
83 #endif
84 }
85
86 void IpcFuzzerProcess::OpenChannel() {
87 std::string channel_name =
88 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
89 switches::kProcessChannelID);
90
91 channel_.reset(
92 new IPC::ChannelProxy(channel_name,
93 IPC::Channel::MODE_CLIENT,
94 this,
95 io_thread_.message_loop_proxy()));
96 }
97
98 bool IpcFuzzerProcess::ExtractMessages(const char *data, size_t len) {
99 const char* end = data + len;
100
101 while (data < end) {
102 const char* message_tail = IPC::Message::FindNext(data, end);
103 if (!message_tail)
104 break;
105
106 size_t len = message_tail - data;
107 if (len > INT_MAX)
108 break;
109
110 IPC::Message* message = new IPC::Message(data, len);
111 data = message_tail;
112
113 messages_.resize(messages_.size() + 1);
114 messages_.back().reset(message);
115 }
116
117 if (data < end) {
118 unsigned long left = end - data;
119 LOG(ERROR) << left << " bytes left while extracting messages";
120 return false;
121 }
122
123 return true;
124 }
125
126 bool IpcFuzzerProcess::OpenTestcase() {
127 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
128
129 if (!command_line.HasSwitch(kIpcFuzzerTestcase)) {
130 LOG(ERROR) << "No IPC fuzzer testcase specified";
131 return false;
132 }
133
134 base::FilePath path = command_line.GetSwitchValuePath(kIpcFuzzerTestcase);
135 testcase_map_.reset(new base::MemoryMappedFile());
136 if (!testcase_map_->Initialize(path)) {
137 LOG(ERROR) << "Failed to map testcase: " << path.value();
138 return false;
139 }
140
141 const char* data = reinterpret_cast<const char *>(testcase_map_->data());
142 size_t len = testcase_map_->length();
143
144 return ExtractMessages(data, len);
145 }
146
147 IPC::Message* IpcFuzzerProcess::GetNextMessage() {
148 if (current_message_ == messages_.size())
149 return NULL;
150
151 LOG(INFO) << "Sending message "
152 << current_message_ << "/"
153 << messages_.size();
154
155 IPC::Message* const_message = messages_[current_message_].get();
156 IPC::Message* message = new IPC::Message(*const_message);
157 static_cast<uint16*>(const_cast<void*>(message->data()))[8] = 0;
158 ++current_message_;
159
160 return message;
161 }
162
163 void IpcFuzzerProcess::SendNextMessage() {
164 IPC::Message* message = GetNextMessage();
165 if (!message) {
166 base::MessageLoop::current()->Quit();
167 return;
168 }
169
170 channel_->Send(message);
171 }
172
173 void IpcFuzzerProcess::StartSendingMessages() {
174 timer_.reset(new base::Timer(false, true));
175 timer_->Start(FROM_HERE,
176 base::TimeDelta::FromMilliseconds(1),
177 base::Bind(&IpcFuzzerProcess::SendNextMessage,
178 base::Unretained(this)));
179 }
180
181 bool IpcFuzzerProcess::OnMessageReceived(const IPC::Message& msg) {
182 return true;
183 }
184
185 void IpcFuzzerProcess::OnChannelError() {
186 LOG(ERROR) << "Channel error, quitting";
187 base::MessageLoop::current()->Quit();
188 }
189
190 } // namespace
191
192 int main(int argc, const char **argv) {
193 IpcFuzzerProcess fuzzer;
194 fuzzer.Initialize(argc, argv);
195 fuzzer.OpenChannel();
196
197 if (!fuzzer.OpenTestcase())
198 return 0;
199
200 fuzzer.StartSendingMessages();
201
202 base::MessageLoop::current()->Run();
203 return 0;
204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698