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

Side by Side Diff: tools/ipc_fuzzer/replay/replay_process.cc

Issue 106163003: Refactor IPC fuzzer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 "tools/ipc_fuzzer/replay/replay_process.h"
6
5 #include <limits.h> 7 #include <limits.h>
6 #include <list> 8 #include <string>
7
8 #include "base/bind.h" 9 #include "base/bind.h"
9 #include "base/command_line.h" 10 #include "base/command_line.h"
10 #include "base/files/memory_mapped_file.h" 11 #include "base/files/file_path.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/posix/global_descriptors.h" 13 #include "base/posix/global_descriptors.h"
Tom Sepez 2013/12/05 19:05:49 Ok. Would be nice if we didn't need posix-specifi
aedla 2013/12/05 23:16:21 Yes, I made ipc_fuzzer target linux-only. I would
15 #include "base/stl_util.h" 14 #include "base/stl_util.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" 15 #include "chrome/common/chrome_switches.h"
20 #include "ipc/ipc_channel_proxy.h"
21 #include "ipc/ipc_descriptors.h" 16 #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" 17 #include "ipc/ipc_switches.h"
26 18
27 namespace { 19 namespace ipc_fuzzer {
28 20
29 class IpcFuzzerProcess : public IPC::Listener { 21 ReplayProcess::ReplayProcess()
30 public:
31 IpcFuzzerProcess();
32 virtual ~IpcFuzzerProcess();
33
34 // Set up command line, logging, IO thread.
35 void Initialize(int argc, const char **argv);
36
37 // Open a channel to the browser process. It will think we are a renderer.
38 void OpenChannel();
39
40 // Extract messages from a file specified by --ipc-fuzzer-testcase=.
41 bool OpenTestcase();
42
43 // Trigger the sending of messages to the browser.
44 void StartSendingMessages();
45
46 // IPC::Listener implementation.
47 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
48 virtual void OnChannelError() OVERRIDE;
49
50 private:
51 bool ExtractMessages(const char *data, size_t len);
52 void SendNextMessage();
53
54 scoped_ptr<IPC::ChannelProxy> channel_;
55 base::MessageLoop main_loop_;
56 base::Thread io_thread_;
57 base::WaitableEvent shutdown_event_;
58 scoped_ptr<base::Timer> timer_;
59 scoped_ptr<base::MemoryMappedFile> testcase_map_;
60 std::list<IPC::Message*> messages_;
61
62 DISALLOW_COPY_AND_ASSIGN(IpcFuzzerProcess);
63 };
64
65 IpcFuzzerProcess::IpcFuzzerProcess()
66 : main_loop_(base::MessageLoop::TYPE_DEFAULT), 22 : main_loop_(base::MessageLoop::TYPE_DEFAULT),
67 io_thread_("Chrome_ChildIOThread"), 23 io_thread_("Chrome_ChildIOThread"),
68 shutdown_event_(true, false) { 24 shutdown_event_(true, false) {
69 } 25 }
70 26
71 IpcFuzzerProcess::~IpcFuzzerProcess() { 27 ReplayProcess::~ReplayProcess() {
72 channel_.reset(); 28 channel_.reset();
73 STLDeleteElements(&messages_); 29 STLDeleteElements(&messages_);
74 } 30 }
75 31
76 void IpcFuzzerProcess::Initialize(int argc, const char **argv) { 32 void ReplayProcess::Initialize(int argc, const char **argv) {
77 CommandLine::Init(argc, argv); 33 CommandLine::Init(argc, argv);
78 34
79 // Log to default destination. 35 // Log to default destination.
80 logging::SetMinLogLevel(logging::LOG_ERROR); 36 logging::SetMinLogLevel(logging::LOG_ERROR);
81 logging::InitLogging(logging::LoggingSettings()); 37 logging::InitLogging(logging::LoggingSettings());
82 38
83 io_thread_.StartWithOptions( 39 io_thread_.StartWithOptions(
84 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 40 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
85 41
86 #if defined(OS_POSIX) 42 #if defined(OS_POSIX)
87 base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance(); 43 base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
88 g_fds->Set(kPrimaryIPCChannel, 44 g_fds->Set(kPrimaryIPCChannel,
89 kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor); 45 kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
90 #endif 46 #endif
91 } 47 }
92 48
93 void IpcFuzzerProcess::OpenChannel() { 49 void ReplayProcess::OpenChannel() {
94 std::string channel_name = 50 std::string channel_name =
95 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 51 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
96 switches::kProcessChannelID); 52 switches::kProcessChannelID);
97 53
98 channel_.reset( 54 channel_.reset(
99 new IPC::ChannelProxy(channel_name, 55 new IPC::ChannelProxy(channel_name,
100 IPC::Channel::MODE_CLIENT, 56 IPC::Channel::MODE_CLIENT,
101 this, 57 this,
102 io_thread_.message_loop_proxy())); 58 io_thread_.message_loop_proxy()));
103 } 59 }
104 60
105 bool IpcFuzzerProcess::ExtractMessages(const char *data, size_t len) { 61 bool ReplayProcess::ExtractMessages(const char *data, size_t len) {
106 const char* end = data + len; 62 const char* end = data + len;
107 63
108 while (data < end) { 64 while (data < end) {
109 const char* message_tail = IPC::Message::FindNext(data, end); 65 const char* message_tail = IPC::Message::FindNext(data, end);
110 if (!message_tail) 66 if (!message_tail)
111 break; 67 break;
112 68
113 size_t len = message_tail - data; 69 size_t len = message_tail - data;
114 if (len > INT_MAX) { 70 if (len > INT_MAX) {
115 LOG(ERROR) << "Message too large"; 71 LOG(ERROR) << "Message too large";
116 break; 72 break;
Tom Sepez 2013/12/05 19:05:49 return false here with error. This is the only wa
aedla 2013/12/05 23:16:21 Ah, good catch. Another way to data < end below wa
117 } 73 }
118 74
119 IPC::Message* message = new IPC::Message(data, len); 75 IPC::Message* message = new IPC::Message(data, len);
120 messages_.push_back(message); 76 messages_.push_back(message);
121 data = message_tail; 77 data = message_tail;
122 } 78 }
123 79
124 if (data < end) { 80 if (data < end) {
125 unsigned long left = end - data; 81 unsigned long left = end - data;
126 LOG(ERROR) << left << " bytes left while extracting messages"; 82 LOG(ERROR) << left << " bytes left while extracting messages";
127 return false; 83 return false;
128 } 84 }
129 85
130 return true; 86 return true;
131 } 87 }
132 88
133 bool IpcFuzzerProcess::OpenTestcase() { 89 bool ReplayProcess::OpenTestcase() {
134 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 90 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
135 91
136 if (!command_line.HasSwitch(switches::kIpcFuzzerTestcase)) { 92 if (!command_line.HasSwitch(switches::kIpcFuzzerTestcase)) {
137 LOG(ERROR) << "No IPC fuzzer testcase specified"; 93 LOG(ERROR) << "No IPC fuzzer testcase specified";
138 return false; 94 return false;
139 } 95 }
140 96
141 base::FilePath path = 97 base::FilePath path =
142 command_line.GetSwitchValuePath(switches::kIpcFuzzerTestcase); 98 command_line.GetSwitchValuePath(switches::kIpcFuzzerTestcase);
143 testcase_map_.reset(new base::MemoryMappedFile()); 99 testcase_map_.reset(new base::MemoryMappedFile());
144 if (!testcase_map_->Initialize(path)) { 100 if (!testcase_map_->Initialize(path)) {
145 LOG(ERROR) << "Failed to map testcase: " << path.value(); 101 LOG(ERROR) << "Failed to map testcase: " << path.value();
146 return false; 102 return false;
147 } 103 }
148 104
149 const char* data = reinterpret_cast<const char *>(testcase_map_->data()); 105 const char* data = reinterpret_cast<const char *>(testcase_map_->data());
150 size_t len = testcase_map_->length(); 106 size_t len = testcase_map_->length();
151 107
152 return ExtractMessages(data, len); 108 return ExtractMessages(data, len);
153 } 109 }
154 110
155 void IpcFuzzerProcess::SendNextMessage() { 111 void ReplayProcess::SendNextMessage() {
156 if (messages_.empty()) { 112 if (messages_.empty()) {
157 base::MessageLoop::current()->Quit(); 113 base::MessageLoop::current()->Quit();
158 return; 114 return;
159 } 115 }
160 116
161 IPC::Message* message = messages_.front(); 117 IPC::Message* message = messages_.front();
162 messages_.pop_front(); 118 messages_.pop_front();
163 119
164 channel_->Send(message); 120 channel_->Send(message);
Tom Sepez 2013/12/05 19:05:49 check return value. this could fail.
aedla 2013/12/05 23:16:21 ChannelProxy::Send() doesn't actually return false
165 } 121 }
166 122
167 void IpcFuzzerProcess::StartSendingMessages() { 123 void ReplayProcess::Run() {
168 timer_.reset(new base::Timer(false, true)); 124 timer_.reset(new base::Timer(false, true));
169 timer_->Start(FROM_HERE, 125 timer_->Start(FROM_HERE,
170 base::TimeDelta::FromMilliseconds(1), 126 base::TimeDelta::FromMilliseconds(1),
171 base::Bind(&IpcFuzzerProcess::SendNextMessage, 127 base::Bind(&ReplayProcess::SendNextMessage,
172 base::Unretained(this))); 128 base::Unretained(this)));
129 base::MessageLoop::current()->Run();
173 } 130 }
174 131
175 bool IpcFuzzerProcess::OnMessageReceived(const IPC::Message& msg) { 132 bool ReplayProcess::OnMessageReceived(const IPC::Message& msg) {
176 return true; 133 return true;
177 } 134 }
178 135
179 void IpcFuzzerProcess::OnChannelError() { 136 void ReplayProcess::OnChannelError() {
180 LOG(ERROR) << "Channel error, quitting"; 137 LOG(ERROR) << "Channel error, quitting";
181 base::MessageLoop::current()->Quit(); 138 base::MessageLoop::current()->Quit();
182 } 139 }
183 140
184 } // namespace 141 } // namespace ipc_fuzzer
185
186 int main(int argc, const char **argv) {
187 IpcFuzzerProcess fuzzer;
188 fuzzer.Initialize(argc, argv);
189 fuzzer.OpenChannel();
190
191 if (!fuzzer.OpenTestcase())
192 return 0;
193
194 fuzzer.StartSendingMessages();
195
196 base::MessageLoop::current()->Run();
197 return 0;
198 }
OLDNEW
« tools/ipc_fuzzer/replay/replay_process.h ('K') | « tools/ipc_fuzzer/replay/replay_process.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698