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

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: addressed comments 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 "chrome/common/chrome_switches.h"
20 #include "ipc/ipc_channel_proxy.h"
21 #include "ipc/ipc_descriptors.h"
22 #include "ipc/ipc_listener.h"
23 #include "ipc/ipc_message.h"
24 #include "ipc/ipc_platform_file.h"
25 #include "ipc/ipc_switches.h"
26
27 namespace {
28
29 class IpcFuzzerProcess : public IPC::Listener {
30 public:
31 IpcFuzzerProcess();
32 virtual ~IpcFuzzerProcess();
33 void Initialize(int argc, const char **argv);
jochen (gone - plz use gerrit) 2013/10/31 10:47:00 please add comments explaining what the methods do
aedla 2013/11/26 17:09:50 Done.
34 void OpenChannel();
35 bool OpenTestcase();
36 void StartSendingMessages();
37
38 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
jochen (gone - plz use gerrit) 2013/10/31 10:47:00 nit. add // IPC::Listener implementation. comment
aedla 2013/11/26 17:09:50 Done.
39 virtual void OnChannelError() OVERRIDE;
40
41 private:
42 bool ExtractMessages(const char *data, size_t len);
43 IPC::Message* GetNextMessage();
44 void SendNextMessage();
45
46 scoped_ptr<IPC::ChannelProxy> channel_;
47 base::MessageLoop main_loop_;
48 base::Thread io_thread_;
jochen (gone - plz use gerrit) 2013/10/31 10:47:00 during shutdown, the io thread will die before tha
aedla 2013/11/26 17:09:50 Nice catch. I added channel_.reset() to the destru
49 base::WaitableEvent shutdown_event_;
50 scoped_ptr<base::Timer> timer_;
51 scoped_ptr<base::MemoryMappedFile> testcase_map_;
52 std::vector<scoped_ptr<IPC::Message>> messages_;
53 size_t current_message_;
54
55 DISALLOW_COPY_AND_ASSIGN(IpcFuzzerProcess);
56 };
57
58 IpcFuzzerProcess::IpcFuzzerProcess()
59 : main_loop_(base::MessageLoop::TYPE_DEFAULT),
60 io_thread_("Chrome_ChildIOThread"),
61 shutdown_event_(true, false),
62 current_message_(0) {
63 }
64
65 IpcFuzzerProcess::~IpcFuzzerProcess() {
66 }
67
68 void IpcFuzzerProcess::Initialize(int argc, const char **argv) {
69 CommandLine::Init(argc, argv);
70
71 // Log to default destination.
72 logging::SetMinLogLevel(logging::LOG_ERROR);
73 logging::InitLogging(logging::LoggingSettings());
74
75 io_thread_.StartWithOptions(
76 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
77
78 #if defined(OS_POSIX)
79 base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
80 g_fds->Set(kPrimaryIPCChannel,
81 kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
82 #endif
83 }
84
85 void IpcFuzzerProcess::OpenChannel() {
86 std::string channel_name =
87 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
88 switches::kProcessChannelID);
89
90 channel_.reset(
91 new IPC::ChannelProxy(channel_name,
92 IPC::Channel::MODE_CLIENT,
93 this,
94 io_thread_.message_loop_proxy()));
95 }
96
97 bool IpcFuzzerProcess::ExtractMessages(const char *data, size_t len) {
98 const char* end = data + len;
99
100 while (data < end) {
101 const char* message_tail = IPC::Message::FindNext(data, end);
102 if (!message_tail)
103 break;
104
105 size_t len = message_tail - data;
106 if (len > INT_MAX)
107 break;
108
109 IPC::Message* message = new IPC::Message(data, len);
110 data = message_tail;
111
112 messages_.resize(messages_.size() + 1);
113 messages_.back().reset(message);
114 }
115
116 if (data < end) {
117 unsigned long left = end - data;
118 LOG(ERROR) << left << " bytes left while extracting messages";
119 return false;
120 }
121
122 return true;
123 }
124
125 bool IpcFuzzerProcess::OpenTestcase() {
126 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
127
128 if (!command_line.HasSwitch(switches::kIpcFuzzerTestcase)) {
129 LOG(ERROR) << "No IPC fuzzer testcase specified";
130 return false;
131 }
132
133 base::FilePath path =
134 command_line.GetSwitchValuePath(switches::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;
jochen (gone - plz use gerrit) 2013/10/31 10:47:00 what if data is too small?
aedla 2013/11/26 17:09:50 It will actually be large enough, IPC::Message::Fi
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),
jochen (gone - plz use gerrit) 2013/10/31 10:47:00 nit. indentation
aedla 2013/11/26 17:09:50 Done.
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