Revert 224458 "Enabling MediaStreamInfoBarTest.DenyingCameraDoes..."
[chromium-blink-merge.git] / chrome / tools / ipclist / ipcfuzz.cc
blob40845d743acfedd82e2f1e1cc81fe326a771e635
1 // Copyright (c) 2012 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.
5 #include <algorithm>
6 #include <ostream>
7 #include <set>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/containers/hash_tables.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/singleton.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/pickle.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/thread.h"
20 #include "base/time/time.h"
21 #include "chrome/common/all_messages.h"
22 #include "content/common/all_messages.h"
23 #include "ipc/ipc_message.h"
24 #include "ipc/ipc_message_utils.h"
25 #include "ipc/ipc_switches.h"
26 #include "ipc/ipc_sync_channel.h"
27 #include "ipc/ipc_sync_message.h"
29 #if defined(OS_POSIX)
30 #include <unistd.h>
31 #endif
33 namespace IPC {
34 class Message;
36 // Interface implemented by those who fuzz basic types. The types all
37 // correspond to the types which a pickle from base/pickle.h can pickle,
38 // plus the floating point types.
39 class Fuzzer {
40 public:
41 // Select a message for fuzzing.
42 virtual bool FuzzThisMessage(const IPC::Message *msg) = 0;
44 // Tweak individual values within a message.
45 virtual void FuzzBool(bool* value) = 0;
46 virtual void FuzzInt(int* value) = 0;
47 virtual void FuzzLong(long* value) = 0;
48 virtual void FuzzSize(size_t* value) = 0;
49 virtual void FuzzUChar(unsigned char *value) = 0;
50 virtual void FuzzUInt16(uint16* value) = 0;
51 virtual void FuzzUInt32(uint32* value) = 0;
52 virtual void FuzzInt64(int64* value) = 0;
53 virtual void FuzzUInt64(uint64* value) = 0;
54 virtual void FuzzFloat(float *value) = 0;
55 virtual void FuzzDouble(double *value) = 0;
56 virtual void FuzzString(std::string* value) = 0;
57 virtual void FuzzWString(std::wstring* value) = 0;
58 virtual void FuzzString16(string16* value) = 0;
59 virtual void FuzzData(char* data, int length) = 0;
60 virtual void FuzzBytes(void* data, int data_len) = 0;
63 } // namespace IPC
65 namespace {
67 template <typename T>
68 void FuzzIntegralType(T* value, unsigned int frequency) {
69 if (rand() % frequency == 0) {
70 switch (rand() % 4) {
71 case 0: (*value) = 0; break;
72 case 1: (*value)--; break;
73 case 2: (*value)++; break;
74 case 3: (*value) ^= rand(); break;
79 template <typename T>
80 void FuzzStringType(T* value, unsigned int frequency,
81 const T& literal1, const T& literal2) {
82 if (rand() % frequency == 0) {
83 switch (rand() % 5) {
84 case 4: (*value) = (*value) + (*value); // FALLTHROUGH
85 case 3: (*value) = (*value) + (*value); // FALLTHROUGH
86 case 2: (*value) = (*value) + (*value); break;
87 case 1: (*value) += literal1; break;
88 case 0: (*value) = literal2; break;
93 } // namespace
95 // One such fuzzer implementation.
96 class DefaultFuzzer : public IPC::Fuzzer {
97 public:
98 static const int DEFAULT_FREQUENCY = 23;
100 DefaultFuzzer() : frequency_(DEFAULT_FREQUENCY) {
101 const char *env_var;
102 if ((env_var = getenv("CHROME_IPC_FUZZING_LIST"))) {
103 std::string str = std::string(env_var);
104 size_t pos;
105 while ((pos = str.find_first_of(',')) != std::string::npos) {
106 message_set_.insert(atoi(str.substr(0, pos).c_str()));
107 str = str.substr(pos+1);
109 message_set_.insert(atoi(str.c_str()));
112 if ((env_var = getenv("CHROME_IPC_FUZZING_SEED"))) {
113 int new_seed = atoi(env_var);
114 if (new_seed)
115 srand(new_seed);
118 if ((env_var = getenv("CHROME_IPC_FUZZING_FREQUENCY"))) {
119 unsigned int new_frequency = atoi(env_var);
120 if (new_frequency)
121 frequency_ = new_frequency;
125 virtual ~DefaultFuzzer() {}
127 virtual bool FuzzThisMessage(const IPC::Message *msg) OVERRIDE {
128 return (message_set_.empty() ||
129 std::find(message_set_.begin(),
130 message_set_.end(),
131 msg->type()) != message_set_.end());
134 virtual void FuzzBool(bool* value) OVERRIDE {
135 if (rand() % frequency_ == 0)
136 (*value) = !(*value);
139 virtual void FuzzInt(int* value) OVERRIDE {
140 FuzzIntegralType<int>(value, frequency_);
143 virtual void FuzzLong(long* value) OVERRIDE {
144 FuzzIntegralType<long>(value, frequency_);
147 virtual void FuzzSize(size_t* value) OVERRIDE {
148 FuzzIntegralType<size_t>(value, frequency_);
151 virtual void FuzzUChar(unsigned char* value) OVERRIDE {
152 FuzzIntegralType<unsigned char>(value, frequency_);
155 virtual void FuzzUInt16(uint16* value) OVERRIDE {
156 FuzzIntegralType<uint16>(value, frequency_);
159 virtual void FuzzUInt32(uint32* value) OVERRIDE {
160 FuzzIntegralType<uint32>(value, frequency_);
163 virtual void FuzzInt64(int64* value) OVERRIDE {
164 FuzzIntegralType<int64>(value, frequency_);
167 virtual void FuzzUInt64(uint64* value) OVERRIDE {
168 FuzzIntegralType<uint64>(value, frequency_);
171 virtual void FuzzFloat(float* value) OVERRIDE {
172 if (rand() % frequency_ == 0)
173 (*value) *= rand() / 1000000.0;
176 virtual void FuzzDouble(double* value) OVERRIDE {
177 if (rand() % frequency_ == 0)
178 (*value) *= rand() / 1000000.0;
181 virtual void FuzzString(std::string* value) OVERRIDE {
182 FuzzStringType<std::string>(value, frequency_, "BORKED", std::string());
185 virtual void FuzzWString(std::wstring* value) OVERRIDE {
186 FuzzStringType<std::wstring>(value, frequency_, L"BORKED", std::wstring());
189 virtual void FuzzString16(string16* value) OVERRIDE {
190 FuzzStringType<string16>(value, frequency_,
191 WideToUTF16(L"BORKED"),
192 WideToUTF16(std::wstring()));
195 virtual void FuzzData(char* data, int length) OVERRIDE {
196 if (rand() % frequency_ == 0) {
197 for (int i = 0; i < length; ++i) {
198 FuzzIntegralType<char>(&data[i], frequency_);
203 virtual void FuzzBytes(void* data, int data_len) OVERRIDE {
204 FuzzData(static_cast<char*>(data), data_len);
207 private:
208 std::set<int> message_set_;
209 unsigned int frequency_;
213 // No-op fuzzer. Rewrites each message unchanged to check if the message
214 // re-assembly is legit.
215 class NoOpFuzzer : public IPC::Fuzzer {
216 public:
217 NoOpFuzzer() {}
218 virtual ~NoOpFuzzer() {}
220 virtual bool FuzzThisMessage(const IPC::Message *msg) OVERRIDE {
221 return true;
224 virtual void FuzzBool(bool* value) OVERRIDE {}
225 virtual void FuzzInt(int* value) OVERRIDE {}
226 virtual void FuzzLong(long* value) OVERRIDE {}
227 virtual void FuzzSize(size_t* value) OVERRIDE {}
228 virtual void FuzzUChar(unsigned char* value) OVERRIDE {}
229 virtual void FuzzUInt16(uint16* value) OVERRIDE {}
230 virtual void FuzzUInt32(uint32* value) OVERRIDE {}
231 virtual void FuzzInt64(int64* value) OVERRIDE {}
232 virtual void FuzzUInt64(uint64* value) OVERRIDE {}
233 virtual void FuzzFloat(float* value) OVERRIDE {}
234 virtual void FuzzDouble(double* value) OVERRIDE {}
235 virtual void FuzzString(std::string* value) OVERRIDE {}
236 virtual void FuzzWString(std::wstring* value) OVERRIDE {}
237 virtual void FuzzString16(string16* value) OVERRIDE {}
238 virtual void FuzzData(char* data, int length) OVERRIDE {}
239 virtual void FuzzBytes(void* data, int data_len) OVERRIDE {}
242 class FuzzerFactory {
243 public:
244 static IPC::Fuzzer *NewFuzzer(const std::string& name) {
245 if (name == "no-op")
246 return new NoOpFuzzer();
247 else
248 return new DefaultFuzzer();
252 // Partially-specialized class that knows how to fuzz a given type.
253 template <class P>
254 struct FuzzTraits {
255 static void Fuzz(P* p, IPC::Fuzzer *fuzzer) {}
258 // Template function to invoke partially-specialized class method.
259 template <class P>
260 static void FuzzParam(P* p, IPC::Fuzzer* fuzzer) {
261 FuzzTraits<P>::Fuzz(p, fuzzer);
264 // Specializations to fuzz primitive types.
265 template <>
266 struct FuzzTraits<bool> {
267 static void Fuzz(bool* p, IPC::Fuzzer* fuzzer) {
268 fuzzer->FuzzBool(p);
272 template <>
273 struct FuzzTraits<int> {
274 static void Fuzz(int* p, IPC::Fuzzer* fuzzer) {
275 fuzzer->FuzzInt(p);
279 template <>
280 struct FuzzTraits<unsigned int> {
281 static void Fuzz(unsigned int* p, IPC::Fuzzer* fuzzer) {
282 fuzzer->FuzzInt(reinterpret_cast<int*>(p));
286 template <>
287 struct FuzzTraits<long> {
288 static void Fuzz(long* p, IPC::Fuzzer* fuzzer) {
289 fuzzer->FuzzLong(p);
293 template <>
294 struct FuzzTraits<unsigned long> {
295 static void Fuzz(unsigned long* p, IPC::Fuzzer* fuzzer) {
296 fuzzer->FuzzLong(reinterpret_cast<long*>(p));
300 template <>
301 struct FuzzTraits<long long> {
302 static void Fuzz(long long* p, IPC::Fuzzer* fuzzer) {
303 fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
307 template <>
308 struct FuzzTraits<unsigned long long> {
309 static void Fuzz(unsigned long long* p, IPC::Fuzzer* fuzzer) {
310 fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
314 template <>
315 struct FuzzTraits<short> {
316 static void Fuzz(short* p, IPC::Fuzzer* fuzzer) {
317 fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
321 template <>
322 struct FuzzTraits<unsigned short> {
323 static void Fuzz(unsigned short* p, IPC::Fuzzer* fuzzer) {
324 fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
328 template <>
329 struct FuzzTraits<char> {
330 static void Fuzz(char* p, IPC::Fuzzer* fuzzer) {
331 fuzzer->FuzzUChar(reinterpret_cast<unsigned char*>(p));
335 template <>
336 struct FuzzTraits<unsigned char> {
337 static void Fuzz(unsigned char* p, IPC::Fuzzer* fuzzer) {
338 fuzzer->FuzzUChar(p);
342 template <>
343 struct FuzzTraits<float> {
344 static void Fuzz(float* p, IPC::Fuzzer* fuzzer) {
345 fuzzer->FuzzFloat(p);
349 template <>
350 struct FuzzTraits<double> {
351 static void Fuzz(double* p, IPC::Fuzzer* fuzzer) {
352 fuzzer->FuzzDouble(p);
356 template <>
357 struct FuzzTraits<std::string> {
358 static void Fuzz(std::string* p, IPC::Fuzzer* fuzzer) {
359 fuzzer->FuzzString(p);
363 template <>
364 struct FuzzTraits<std::wstring> {
365 static void Fuzz(std::wstring* p, IPC::Fuzzer* fuzzer) {
366 fuzzer->FuzzWString(p);
370 template <>
371 struct FuzzTraits<string16> {
372 static void Fuzz(string16* p, IPC::Fuzzer* fuzzer) {
373 fuzzer->FuzzString16(p);
377 // Specializations to fuzz tuples.
378 template <class A>
379 struct FuzzTraits<Tuple1<A> > {
380 static void Fuzz(Tuple1<A>* p, IPC::Fuzzer* fuzzer) {
381 FuzzParam(&p->a, fuzzer);
385 template <class A, class B>
386 struct FuzzTraits<Tuple2<A, B> > {
387 static void Fuzz(Tuple2<A, B>* p, IPC::Fuzzer* fuzzer) {
388 FuzzParam(&p->a, fuzzer);
389 FuzzParam(&p->b, fuzzer);
393 template <class A, class B, class C>
394 struct FuzzTraits<Tuple3<A, B, C> > {
395 static void Fuzz(Tuple3<A, B, C>* p, IPC::Fuzzer* fuzzer) {
396 FuzzParam(&p->a, fuzzer);
397 FuzzParam(&p->b, fuzzer);
398 FuzzParam(&p->c, fuzzer);
402 template <class A, class B, class C, class D>
403 struct FuzzTraits<Tuple4<A, B, C, D> > {
404 static void Fuzz(Tuple4<A, B, C, D>* p, IPC::Fuzzer* fuzzer) {
405 FuzzParam(&p->a, fuzzer);
406 FuzzParam(&p->b, fuzzer);
407 FuzzParam(&p->c, fuzzer);
408 FuzzParam(&p->d, fuzzer);
412 template <class A, class B, class C, class D, class E>
413 struct FuzzTraits<Tuple5<A, B, C, D, E> > {
414 static void Fuzz(Tuple5<A, B, C, D, E>* p, IPC::Fuzzer* fuzzer) {
415 FuzzParam(&p->a, fuzzer);
416 FuzzParam(&p->b, fuzzer);
417 FuzzParam(&p->c, fuzzer);
418 FuzzParam(&p->d, fuzzer);
419 FuzzParam(&p->e, fuzzer);
423 // Specializations to fuzz containers.
424 template <class A>
425 struct FuzzTraits<std::vector<A> > {
426 static void Fuzz(std::vector<A>* p, IPC::Fuzzer* fuzzer) {
427 for (size_t i = 0; i < p->size(); ++i) {
428 FuzzParam(&p->at(i), fuzzer);
433 template <class A, class B>
434 struct FuzzTraits<std::map<A, B> > {
435 static void Fuzz(std::map<A, B>* p, IPC::Fuzzer* fuzzer) {
436 typename std::map<A, B>::iterator it;
437 for (it = p->begin(); it != p->end(); ++it) {
438 FuzzParam(&it->second, fuzzer);
443 template <class A, class B>
444 struct FuzzTraits<std::pair<A, B> > {
445 static void Fuzz(std::pair<A, B>* p, IPC::Fuzzer* fuzzer) {
446 FuzzParam(&p->second, fuzzer);
450 // Specializations to fuzz hand-coded tyoes
451 template <>
452 struct FuzzTraits<base::FileDescriptor> {
453 static void Fuzz(base::FileDescriptor* p, IPC::Fuzzer* fuzzer) {
454 FuzzParam(&p->fd, fuzzer);
458 template <>
459 struct FuzzTraits<GURL> {
460 static void Fuzz(GURL *p, IPC::Fuzzer* fuzzer) {
461 FuzzParam(&p->possibly_invalid_spec(), fuzzer);
465 template <>
466 struct FuzzTraits<gfx::Point> {
467 static void Fuzz(gfx::Point *p, IPC::Fuzzer* fuzzer) {
468 int x = p->x();
469 int y = p->y();
470 FuzzParam(&x, fuzzer);
471 FuzzParam(&y, fuzzer);
472 p->SetPoint(x, y);
476 template <>
477 struct FuzzTraits<gfx::Size> {
478 static void Fuzz(gfx::Size *p, IPC::Fuzzer* fuzzer) {
479 int w = p->width();
480 int h = p->height();
481 FuzzParam(&w, fuzzer);
482 FuzzParam(&h, fuzzer);
483 p->SetSize(w, h);
487 template <>
488 struct FuzzTraits<gfx::Rect> {
489 static void Fuzz(gfx::Rect *p, IPC::Fuzzer* fuzzer) {
490 gfx::Point origin = p->origin();
491 gfx::Size size = p->size();
492 FuzzParam(&origin, fuzzer);
493 FuzzParam(&size, fuzzer);
494 p->set_origin(origin);
495 p->set_size(size);
499 // Means for updating message id in pickles.
500 class PickleCracker : public Pickle {
501 public:
502 static void CopyMessageID(PickleCracker *dst, PickleCracker *src) {
503 memcpy(dst->mutable_payload(), src->payload(), sizeof(int));
507 // Redefine macros to generate fuzzing from traits declarations.
508 // Null out all the macros that need nulling.
509 #include "ipc/ipc_message_null_macros.h"
511 // STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
512 #undef IPC_STRUCT_BEGIN_WITH_PARENT
513 #undef IPC_STRUCT_MEMBER
514 #undef IPC_STRUCT_END
515 #define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent)\
516 IPC_STRUCT_TRAITS_BEGIN(struct_name)
517 #define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
518 #define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
520 // Set up so next include will generate fuzz trait classes.
521 #undef IPC_STRUCT_TRAITS_BEGIN
522 #undef IPC_STRUCT_TRAITS_MEMBER
523 #undef IPC_STRUCT_TRAITS_PARENT
524 #undef IPC_STRUCT_TRAITS_END
525 #define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
526 template <> \
527 struct FuzzTraits<struct_name> { \
528 static void Fuzz(struct_name *p, IPC::Fuzzer* fuzzer) { \
530 #define IPC_STRUCT_TRAITS_MEMBER(name) \
531 FuzzParam(&p->name, fuzzer);
533 #define IPC_STRUCT_TRAITS_PARENT(type) \
534 FuzzParam(static_cast<type*>(p), fuzzer);
536 #define IPC_STRUCT_TRAITS_END() \
540 #undef IPC_ENUM_TRAITS_VALIDATE
541 #define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
542 template <> \
543 struct FuzzTraits<enum_name> { \
544 static void Fuzz(enum_name* p, IPC::Fuzzer* fuzzer) { \
545 FuzzParam(reinterpret_cast<int*>(p), fuzzer); \
549 // Bring them into existence.
550 #include "chrome/common/all_messages.h"
551 #include "content/common/all_messages.h"
553 // Redefine macros to generate fuzzing funtions
554 #include "ipc/ipc_message_null_macros.h"
555 #undef IPC_MESSAGE_DECL
556 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
557 IPC_##kind##_##type##_FUZZ(name, in, out, ilist, olist)
559 #define IPC_EMPTY_CONTROL_FUZZ(name, in, out, ilist, olist) \
560 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
561 return NULL; \
564 #define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \
565 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
566 return NULL; \
569 #define IPC_ASYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
570 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
571 name* real_msg = static_cast<name*>(msg); \
572 IPC_TUPLE_IN_##in ilist p; \
573 name::Read(real_msg, &p); \
574 FuzzParam(&p, fuzzer); \
575 return new name(IPC_MEMBERS_IN_##in(p)); \
578 #define IPC_ASYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
579 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
580 name* real_msg = static_cast<name*>(msg); \
581 IPC_TUPLE_IN_##in ilist p; \
582 name::Read(real_msg, &p); \
583 FuzzParam(&p, fuzzer); \
584 return new name(msg->routing_id() \
585 IPC_COMMA_##in \
586 IPC_MEMBERS_IN_##in(p)); \
589 #define IPC_SYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
590 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
591 name* real_msg = static_cast<name*>(msg); \
592 IPC_TUPLE_IN_##in ilist p; \
593 name::ReadSendParam(real_msg, &p); \
594 FuzzParam(&p, fuzzer); \
595 name* new_msg = new name(IPC_MEMBERS_IN_##in(p) \
596 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
597 IPC_MEMBERS_OUT_##out()); \
598 PickleCracker::CopyMessageID( \
599 reinterpret_cast<PickleCracker *>(new_msg), \
600 reinterpret_cast<PickleCracker *>(real_msg)); \
601 return new_msg; \
605 #define IPC_SYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
606 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
607 name* real_msg = static_cast<name*>(msg); \
608 IPC_TUPLE_IN_##in ilist p; \
609 name::ReadSendParam(real_msg, &p); \
610 FuzzParam(&p, fuzzer); \
611 name* new_msg = new name(msg->routing_id() \
612 IPC_COMMA_OR_##out(IPC_COMMA_##in) \
613 IPC_MEMBERS_IN_##in(p) \
614 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
615 IPC_MEMBERS_OUT_##out()); \
616 PickleCracker::CopyMessageID( \
617 reinterpret_cast<PickleCracker *>(new_msg), \
618 reinterpret_cast<PickleCracker *>(real_msg)); \
619 return new_msg; \
622 #define IPC_MEMBERS_IN_0(p)
623 #define IPC_MEMBERS_IN_1(p) p.a
624 #define IPC_MEMBERS_IN_2(p) p.a, p.b
625 #define IPC_MEMBERS_IN_3(p) p.a, p.b, p.c
626 #define IPC_MEMBERS_IN_4(p) p.a, p.b, p.c, p.d
627 #define IPC_MEMBERS_IN_5(p) p.a, p.b, p.c, p.d, p.e
629 #define IPC_MEMBERS_OUT_0()
630 #define IPC_MEMBERS_OUT_1() NULL
631 #define IPC_MEMBERS_OUT_2() NULL, NULL
632 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
633 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
634 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
636 #include "chrome/common/all_messages.h"
637 #include "content/common/all_messages.h"
639 typedef IPC::Message* (*FuzzFunction)(IPC::Message*, IPC::Fuzzer*);
640 typedef base::hash_map<uint32, FuzzFunction> FuzzFunctionMap;
642 // Redefine macros to register fuzzing functions into map.
643 #include "ipc/ipc_message_null_macros.h"
644 #undef IPC_MESSAGE_DECL
645 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
646 (*map)[static_cast<uint32>(name::ID)] = fuzzer_for_##name;
648 void PopulateFuzzFunctionMap(FuzzFunctionMap *map) {
649 #include "chrome/common/all_messages.h"
650 #include "content/common/all_messages.h"
653 class ipcfuzz : public IPC::ChannelProxy::OutgoingMessageFilter {
654 public:
655 ipcfuzz() {
656 const char* env_var = getenv("CHROME_IPC_FUZZING_KIND");
657 fuzzer_ = FuzzerFactory::NewFuzzer(env_var ? env_var : "");
658 PopulateFuzzFunctionMap(&fuzz_function_map_);
661 virtual IPC::Message* Rewrite(IPC::Message* message) OVERRIDE {
662 if (fuzzer_ && fuzzer_->FuzzThisMessage(message)) {
663 FuzzFunctionMap::iterator it = fuzz_function_map_.find(message->type());
664 if (it != fuzz_function_map_.end()) {
665 IPC::Message* fuzzed_message = (*it->second)(message, fuzzer_);
666 if (fuzzed_message) {
667 delete message;
668 message = fuzzed_message;
672 return message;
675 private:
676 IPC::Fuzzer* fuzzer_;
677 FuzzFunctionMap fuzz_function_map_;
680 ipcfuzz g_ipcfuzz;
682 // Entry point avoiding mangled names.
683 extern "C" {
684 __attribute__((visibility("default")))
685 IPC::ChannelProxy::OutgoingMessageFilter* GetFilter(void);
688 IPC::ChannelProxy::OutgoingMessageFilter* GetFilter(void) {
689 return &g_ipcfuzz;