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.
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"
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.
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;
68 void FuzzIntegralType(T
* value
, unsigned int frequency
) {
69 if (rand() % frequency
== 0) {
71 case 0: (*value
) = 0; break;
72 case 1: (*value
)--; break;
73 case 2: (*value
)++; break;
74 case 3: (*value
) ^= rand(); break;
80 void FuzzStringType(T
* value
, unsigned int frequency
,
81 const T
& literal1
, const T
& literal2
) {
82 if (rand() % frequency
== 0) {
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;
95 // One such fuzzer implementation.
96 class DefaultFuzzer
: public IPC::Fuzzer
{
98 static const int DEFAULT_FREQUENCY
= 23;
100 DefaultFuzzer() : frequency_(DEFAULT_FREQUENCY
) {
102 if ((env_var
= getenv("CHROME_IPC_FUZZING_LIST"))) {
103 std::string str
= std::string(env_var
);
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
);
118 if ((env_var
= getenv("CHROME_IPC_FUZZING_FREQUENCY"))) {
119 unsigned int new_frequency
= atoi(env_var
);
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(),
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
);
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
{
218 virtual ~NoOpFuzzer() {}
220 virtual bool FuzzThisMessage(const IPC::Message
*msg
) OVERRIDE
{
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
{
244 static IPC::Fuzzer
*NewFuzzer(const std::string
& name
) {
246 return new NoOpFuzzer();
248 return new DefaultFuzzer();
252 // Partially-specialized class that knows how to fuzz a given type.
255 static void Fuzz(P
* p
, IPC::Fuzzer
*fuzzer
) {}
258 // Template function to invoke partially-specialized class method.
260 static void FuzzParam(P
* p
, IPC::Fuzzer
* fuzzer
) {
261 FuzzTraits
<P
>::Fuzz(p
, fuzzer
);
264 // Specializations to fuzz primitive types.
266 struct FuzzTraits
<bool> {
267 static void Fuzz(bool* p
, IPC::Fuzzer
* fuzzer
) {
273 struct FuzzTraits
<int> {
274 static void Fuzz(int* p
, IPC::Fuzzer
* fuzzer
) {
280 struct FuzzTraits
<unsigned int> {
281 static void Fuzz(unsigned int* p
, IPC::Fuzzer
* fuzzer
) {
282 fuzzer
->FuzzInt(reinterpret_cast<int*>(p
));
287 struct FuzzTraits
<long> {
288 static void Fuzz(long* p
, IPC::Fuzzer
* fuzzer
) {
294 struct FuzzTraits
<unsigned long> {
295 static void Fuzz(unsigned long* p
, IPC::Fuzzer
* fuzzer
) {
296 fuzzer
->FuzzLong(reinterpret_cast<long*>(p
));
301 struct FuzzTraits
<long long> {
302 static void Fuzz(long long* p
, IPC::Fuzzer
* fuzzer
) {
303 fuzzer
->FuzzInt64(reinterpret_cast<int64
*>(p
));
308 struct FuzzTraits
<unsigned long long> {
309 static void Fuzz(unsigned long long* p
, IPC::Fuzzer
* fuzzer
) {
310 fuzzer
->FuzzInt64(reinterpret_cast<int64
*>(p
));
315 struct FuzzTraits
<short> {
316 static void Fuzz(short* p
, IPC::Fuzzer
* fuzzer
) {
317 fuzzer
->FuzzUInt16(reinterpret_cast<uint16
*>(p
));
322 struct FuzzTraits
<unsigned short> {
323 static void Fuzz(unsigned short* p
, IPC::Fuzzer
* fuzzer
) {
324 fuzzer
->FuzzUInt16(reinterpret_cast<uint16
*>(p
));
329 struct FuzzTraits
<char> {
330 static void Fuzz(char* p
, IPC::Fuzzer
* fuzzer
) {
331 fuzzer
->FuzzUChar(reinterpret_cast<unsigned char*>(p
));
336 struct FuzzTraits
<unsigned char> {
337 static void Fuzz(unsigned char* p
, IPC::Fuzzer
* fuzzer
) {
338 fuzzer
->FuzzUChar(p
);
343 struct FuzzTraits
<float> {
344 static void Fuzz(float* p
, IPC::Fuzzer
* fuzzer
) {
345 fuzzer
->FuzzFloat(p
);
350 struct FuzzTraits
<double> {
351 static void Fuzz(double* p
, IPC::Fuzzer
* fuzzer
) {
352 fuzzer
->FuzzDouble(p
);
357 struct FuzzTraits
<std::string
> {
358 static void Fuzz(std::string
* p
, IPC::Fuzzer
* fuzzer
) {
359 fuzzer
->FuzzString(p
);
364 struct FuzzTraits
<std::wstring
> {
365 static void Fuzz(std::wstring
* p
, IPC::Fuzzer
* fuzzer
) {
366 fuzzer
->FuzzWString(p
);
371 struct FuzzTraits
<string16
> {
372 static void Fuzz(string16
* p
, IPC::Fuzzer
* fuzzer
) {
373 fuzzer
->FuzzString16(p
);
377 // Specializations to fuzz tuples.
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.
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
452 struct FuzzTraits
<base::FileDescriptor
> {
453 static void Fuzz(base::FileDescriptor
* p
, IPC::Fuzzer
* fuzzer
) {
454 FuzzParam(&p
->fd
, fuzzer
);
459 struct FuzzTraits
<GURL
> {
460 static void Fuzz(GURL
*p
, IPC::Fuzzer
* fuzzer
) {
461 FuzzParam(&p
->possibly_invalid_spec(), fuzzer
);
466 struct FuzzTraits
<gfx::Point
> {
467 static void Fuzz(gfx::Point
*p
, IPC::Fuzzer
* fuzzer
) {
470 FuzzParam(&x
, fuzzer
);
471 FuzzParam(&y
, fuzzer
);
477 struct FuzzTraits
<gfx::Size
> {
478 static void Fuzz(gfx::Size
*p
, IPC::Fuzzer
* fuzzer
) {
481 FuzzParam(&w
, fuzzer
);
482 FuzzParam(&h
, fuzzer
);
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
);
499 // Means for updating message id in pickles.
500 class PickleCracker
: public Pickle
{
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) \
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) \
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) { \
564 #define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \
565 IPC::Message* fuzzer_for_##name(IPC::Message *msg, IPC::Fuzzer* fuzzer) { \
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() \
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)); \
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)); \
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
{
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
) {
668 message
= fuzzed_message
;
676 IPC::Fuzzer
* fuzzer_
;
677 FuzzFunctionMap fuzz_function_map_
;
682 // Entry point avoiding mangled names.
684 __attribute__((visibility("default")))
685 IPC::ChannelProxy::OutgoingMessageFilter
* GetFilter(void);
688 IPC::ChannelProxy::OutgoingMessageFilter
* GetFilter(void) {