| Index: tools/ipc_fuzzer/mutate/mutate.cc
|
| diff --git a/tools/ipc_fuzzer/mutate/mutate.cc b/tools/ipc_fuzzer/mutate/mutate.cc
|
| deleted file mode 100644
|
| index e25c8da6ace2c43b0981e063a6af8d76a5f86aad..0000000000000000000000000000000000000000
|
| --- a/tools/ipc_fuzzer/mutate/mutate.cc
|
| +++ /dev/null
|
| @@ -1,732 +0,0 @@
|
| -// Copyright 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stdlib.h>
|
| -
|
| -#include <algorithm>
|
| -#include <iostream>
|
| -#include <ostream>
|
| -#include <set>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/command_line.h"
|
| -#include "base/pickle.h"
|
| -#include "base/strings/string_split.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "ipc/ipc_message.h"
|
| -#include "ipc/ipc_message_utils.h"
|
| -#include "ipc/ipc_switches.h"
|
| -#include "ipc/ipc_sync_channel.h"
|
| -#include "ipc/ipc_sync_message.h"
|
| -#include "tools/ipc_fuzzer/message_lib/all_messages.h"
|
| -#include "tools/ipc_fuzzer/message_lib/message_cracker.h"
|
| -#include "tools/ipc_fuzzer/message_lib/message_file.h"
|
| -#include "tools/ipc_fuzzer/mutate/rand_util.h"
|
| -
|
| -#if defined(OS_POSIX)
|
| -#include <unistd.h>
|
| -#endif
|
| -
|
| -namespace IPC {
|
| -class Message;
|
| -} // namespace IPC
|
| -
|
| -namespace ipc_fuzzer {
|
| -
|
| -// Interface implemented by those who fuzz basic types. The types all
|
| -// correspond to the types which a pickle from base/pickle.h can pickle,
|
| -// plus the floating point types.
|
| -class Fuzzer {
|
| - public:
|
| - // Tweak individual values within a message.
|
| - virtual void FuzzBool(bool* value) = 0;
|
| - virtual void FuzzInt(int* value) = 0;
|
| - virtual void FuzzLong(long* value) = 0;
|
| - virtual void FuzzSize(size_t* value) = 0;
|
| - virtual void FuzzUChar(unsigned char *value) = 0;
|
| - virtual void FuzzUInt16(uint16* value) = 0;
|
| - virtual void FuzzUInt32(uint32* value) = 0;
|
| - virtual void FuzzInt64(int64* value) = 0;
|
| - virtual void FuzzUInt64(uint64* value) = 0;
|
| - virtual void FuzzFloat(float *value) = 0;
|
| - virtual void FuzzDouble(double *value) = 0;
|
| - virtual void FuzzString(std::string* value) = 0;
|
| - virtual void FuzzString16(base::string16* value) = 0;
|
| - virtual void FuzzData(char* data, int length) = 0;
|
| - virtual void FuzzBytes(void* data, int data_len) = 0;
|
| -};
|
| -
|
| -template <typename T>
|
| -void FuzzIntegralType(T* value, unsigned int frequency) {
|
| - if (RandEvent(frequency)) {
|
| - switch (RandInRange(4)) {
|
| - case 0: (*value) = 0; break;
|
| - case 1: (*value)--; break;
|
| - case 2: (*value)++; break;
|
| - case 3: (*value) = RandU64(); break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -template <typename T>
|
| -void FuzzStringType(T* value, unsigned int frequency,
|
| - const T& literal1, const T& literal2) {
|
| - if (RandEvent(frequency)) {
|
| - switch (RandInRange(5)) {
|
| - case 4: (*value) = (*value) + (*value); // FALLTHROUGH
|
| - case 3: (*value) = (*value) + (*value); // FALLTHROUGH
|
| - case 2: (*value) = (*value) + (*value); break;
|
| - case 1: (*value) += literal1; break;
|
| - case 0: (*value) = literal2; break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -// One such fuzzer implementation.
|
| -class DefaultFuzzer : public Fuzzer {
|
| - public:
|
| - DefaultFuzzer(int frequency) : frequency_(frequency) {
|
| - }
|
| -
|
| - virtual ~DefaultFuzzer() {}
|
| -
|
| - void FuzzBool(bool* value) override {
|
| - if (RandEvent(frequency_))
|
| - (*value) = !(*value);
|
| - }
|
| -
|
| - void FuzzInt(int* value) override {
|
| - FuzzIntegralType<int>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzLong(long* value) override {
|
| - FuzzIntegralType<long>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzSize(size_t* value) override {
|
| - FuzzIntegralType<size_t>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzUChar(unsigned char* value) override {
|
| - FuzzIntegralType<unsigned char>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzUInt16(uint16* value) override {
|
| - FuzzIntegralType<uint16>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzUInt32(uint32* value) override {
|
| - FuzzIntegralType<uint32>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzInt64(int64* value) override {
|
| - FuzzIntegralType<int64>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzUInt64(uint64* value) override {
|
| - FuzzIntegralType<uint64>(value, frequency_);
|
| - }
|
| -
|
| - void FuzzFloat(float* value) override {
|
| - if (RandEvent(frequency_))
|
| - *value = RandDouble();
|
| - }
|
| -
|
| - void FuzzDouble(double* value) override {
|
| - if (RandEvent(frequency_))
|
| - *value = RandDouble();
|
| - }
|
| -
|
| - void FuzzString(std::string* value) override {
|
| - FuzzStringType<std::string>(value, frequency_, "BORKED", std::string());
|
| - }
|
| -
|
| - void FuzzString16(base::string16* value) override {
|
| - FuzzStringType<base::string16>(value, frequency_,
|
| - base::WideToUTF16(L"BORKED"),
|
| - base::WideToUTF16(L""));
|
| - }
|
| -
|
| - void FuzzData(char* data, int length) override {
|
| - if (RandEvent(frequency_)) {
|
| - for (int i = 0; i < length; ++i) {
|
| - FuzzIntegralType<char>(&data[i], frequency_);
|
| - }
|
| - }
|
| - }
|
| -
|
| - void FuzzBytes(void* data, int data_len) override {
|
| - FuzzData(static_cast<char*>(data), data_len);
|
| - }
|
| -
|
| - private:
|
| - unsigned int frequency_;
|
| -};
|
| -
|
| -
|
| -// No-op fuzzer. Rewrites each message unchanged to check if the message
|
| -// re-assembly is legit.
|
| -class NoOpFuzzer : public Fuzzer {
|
| - public:
|
| - NoOpFuzzer() {}
|
| - virtual ~NoOpFuzzer() {}
|
| -
|
| - void FuzzBool(bool* value) override {}
|
| - void FuzzInt(int* value) override {}
|
| - void FuzzLong(long* value) override {}
|
| - void FuzzSize(size_t* value) override {}
|
| - void FuzzUChar(unsigned char* value) override {}
|
| - void FuzzUInt16(uint16* value) override {}
|
| - void FuzzUInt32(uint32* value) override {}
|
| - void FuzzInt64(int64* value) override {}
|
| - void FuzzUInt64(uint64* value) override {}
|
| - void FuzzFloat(float* value) override {}
|
| - void FuzzDouble(double* value) override {}
|
| - void FuzzString(std::string* value) override {}
|
| - void FuzzString16(base::string16* value) override {}
|
| - void FuzzData(char* data, int length) override {}
|
| - void FuzzBytes(void* data, int data_len) override {}
|
| -};
|
| -
|
| -class FuzzerFactory {
|
| - public:
|
| - static Fuzzer *Create(const std::string& name, int frequency) {
|
| - if (name == "no-op")
|
| - return new NoOpFuzzer();
|
| -
|
| - if (name == "default")
|
| - return new DefaultFuzzer(frequency);
|
| -
|
| - std::cerr << "No such fuzzer: " << name << "\n";
|
| - return 0;
|
| - }
|
| -};
|
| -
|
| -// Partially-specialized class that knows how to fuzz a given type.
|
| -template <class P>
|
| -struct FuzzTraits {
|
| - static void Fuzz(P* p, Fuzzer *fuzzer) {
|
| - // This is the catch-all for types we don't have enough information
|
| - // to fuzz. It simply does nothing to the type. We might want to
|
| - // change it to randomly flip a bit in the range (p, p+sizeof(P)).
|
| - }
|
| -};
|
| -
|
| -// Template function to invoke partially-specialized class method.
|
| -template <class P>
|
| -static void FuzzParam(P* p, Fuzzer* fuzzer) {
|
| - FuzzTraits<P>::Fuzz(p, fuzzer);
|
| -}
|
| -
|
| -// Specializations to fuzz primitive types.
|
| -template <>
|
| -struct FuzzTraits<bool> {
|
| - static void Fuzz(bool* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzBool(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<int> {
|
| - static void Fuzz(int* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzInt(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<unsigned int> {
|
| - static void Fuzz(unsigned int* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzInt(reinterpret_cast<int*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<long> {
|
| - static void Fuzz(long* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzLong(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<unsigned long> {
|
| - static void Fuzz(unsigned long* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzLong(reinterpret_cast<long*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<long long> {
|
| - static void Fuzz(long long* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<unsigned long long> {
|
| - static void Fuzz(unsigned long long* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<short> {
|
| - static void Fuzz(short* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<unsigned short> {
|
| - static void Fuzz(unsigned short* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<char> {
|
| - static void Fuzz(char* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzUChar(reinterpret_cast<unsigned char*>(p));
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<unsigned char> {
|
| - static void Fuzz(unsigned char* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzUChar(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<float> {
|
| - static void Fuzz(float* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzFloat(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<double> {
|
| - static void Fuzz(double* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzDouble(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<std::string> {
|
| - static void Fuzz(std::string* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzString(p);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<base::string16> {
|
| - static void Fuzz(base::string16* p, Fuzzer* fuzzer) {
|
| - fuzzer->FuzzString16(p);
|
| - }
|
| -};
|
| -
|
| -// Specializations to fuzz tuples.
|
| -template <class A>
|
| -struct FuzzTraits<Tuple<A>> {
|
| - static void Fuzz(Tuple<A>* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&get<0>(*p), fuzzer);
|
| - }
|
| -};
|
| -
|
| -template <class A, class B>
|
| -struct FuzzTraits<Tuple<A, B>> {
|
| - static void Fuzz(Tuple<A, B>* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&get<0>(*p), fuzzer);
|
| - FuzzParam(&get<1>(*p), fuzzer);
|
| - }
|
| -};
|
| -
|
| -template <class A, class B, class C>
|
| -struct FuzzTraits<Tuple<A, B, C>> {
|
| - static void Fuzz(Tuple<A, B, C>* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&get<0>(*p), fuzzer);
|
| - FuzzParam(&get<1>(*p), fuzzer);
|
| - FuzzParam(&get<2>(*p), fuzzer);
|
| - }
|
| -};
|
| -
|
| -template <class A, class B, class C, class D>
|
| -struct FuzzTraits<Tuple<A, B, C, D>> {
|
| - static void Fuzz(Tuple<A, B, C, D>* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&get<0>(*p), fuzzer);
|
| - FuzzParam(&get<1>(*p), fuzzer);
|
| - FuzzParam(&get<2>(*p), fuzzer);
|
| - FuzzParam(&get<3>(*p), fuzzer);
|
| - }
|
| -};
|
| -
|
| -template <class A, class B, class C, class D, class E>
|
| -struct FuzzTraits<Tuple<A, B, C, D, E>> {
|
| - static void Fuzz(Tuple<A, B, C, D, E>* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&get<0>(*p), fuzzer);
|
| - FuzzParam(&get<1>(*p), fuzzer);
|
| - FuzzParam(&get<2>(*p), fuzzer);
|
| - FuzzParam(&get<3>(*p), fuzzer);
|
| - FuzzParam(&get<4>(*p), fuzzer);
|
| - }
|
| -};
|
| -
|
| -// Specializations to fuzz containers.
|
| -template <class A>
|
| -struct FuzzTraits<std::vector<A> > {
|
| - static void Fuzz(std::vector<A>* p, Fuzzer* fuzzer) {
|
| - for (size_t i = 0; i < p->size(); ++i) {
|
| - FuzzParam(&p->at(i), fuzzer);
|
| - }
|
| - }
|
| -};
|
| -
|
| -template <class A, class B>
|
| -struct FuzzTraits<std::map<A, B> > {
|
| - static void Fuzz(std::map<A, B>* p, Fuzzer* fuzzer) {
|
| - typename std::map<A, B>::iterator it;
|
| - for (it = p->begin(); it != p->end(); ++it) {
|
| - FuzzParam(&it->second, fuzzer);
|
| - }
|
| - }
|
| -};
|
| -
|
| -template <class A, class B>
|
| -struct FuzzTraits<std::pair<A, B> > {
|
| - static void Fuzz(std::pair<A, B>* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&p->second, fuzzer);
|
| - }
|
| -};
|
| -
|
| -// Specializations to fuzz hand-coded types.
|
| -#if defined(OS_POSIX)
|
| -template <>
|
| -struct FuzzTraits<base::FileDescriptor> {
|
| - static void Fuzz(base::FileDescriptor* p, Fuzzer* fuzzer) {
|
| - FuzzParam(&p->fd, fuzzer);
|
| - }
|
| -};
|
| -#endif
|
| -
|
| -template <>
|
| -struct FuzzTraits<GURL> {
|
| - static void Fuzz(GURL *p, Fuzzer* fuzzer) {
|
| - FuzzParam(&p->possibly_invalid_spec(), fuzzer);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<gfx::Point> {
|
| - static void Fuzz(gfx::Point *p, Fuzzer* fuzzer) {
|
| - int x = p->x();
|
| - int y = p->y();
|
| - FuzzParam(&x, fuzzer);
|
| - FuzzParam(&y, fuzzer);
|
| - p->SetPoint(x, y);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<gfx::Size> {
|
| - static void Fuzz(gfx::Size *p, Fuzzer* fuzzer) {
|
| - int w = p->width();
|
| - int h = p->height();
|
| - FuzzParam(&w, fuzzer);
|
| - FuzzParam(&h, fuzzer);
|
| - p->SetSize(w, h);
|
| - }
|
| -};
|
| -
|
| -template <>
|
| -struct FuzzTraits<gfx::Rect> {
|
| - static void Fuzz(gfx::Rect *p, Fuzzer* fuzzer) {
|
| - gfx::Point origin = p->origin();
|
| - gfx::Size size = p->size();
|
| - FuzzParam(&origin, fuzzer);
|
| - FuzzParam(&size, fuzzer);
|
| - p->set_origin(origin);
|
| - p->set_size(size);
|
| - }
|
| -};
|
| -
|
| -// Redefine macros to generate fuzzing from traits declarations.
|
| -// Null out all the macros that need nulling.
|
| -#include "ipc/ipc_message_null_macros.h"
|
| -
|
| -// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
|
| -#undef IPC_STRUCT_BEGIN
|
| -#undef IPC_STRUCT_BEGIN_WITH_PARENT
|
| -#undef IPC_STRUCT_MEMBER
|
| -#undef IPC_STRUCT_END
|
| -#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
|
| - IPC_STRUCT_BEGIN(struct_name)
|
| -#define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
|
| -#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
|
| -#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
|
| -
|
| -// Set up so next include will generate fuzz trait classes.
|
| -#undef IPC_STRUCT_TRAITS_BEGIN
|
| -#undef IPC_STRUCT_TRAITS_MEMBER
|
| -#undef IPC_STRUCT_TRAITS_PARENT
|
| -#undef IPC_STRUCT_TRAITS_END
|
| -#define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
|
| - template <> \
|
| - struct FuzzTraits<struct_name> { \
|
| - static void Fuzz(struct_name *p, Fuzzer* fuzzer) {
|
| -
|
| -#define IPC_STRUCT_TRAITS_MEMBER(name) \
|
| - FuzzParam(&p->name, fuzzer);
|
| -
|
| -#define IPC_STRUCT_TRAITS_PARENT(type) \
|
| - FuzzParam(static_cast<type*>(p), fuzzer);
|
| -
|
| -#define IPC_STRUCT_TRAITS_END() \
|
| - } \
|
| - };
|
| -
|
| -// TODO(tsepez): Make sure to end up with an enum that meets |condition|.
|
| -#undef IPC_ENUM_TRAITS_VALIDATE
|
| -#define IPC_ENUM_TRAITS_VALIDATE(enum_name, conditon) \
|
| - template <> \
|
| - struct FuzzTraits<enum_name> { \
|
| - static void Fuzz(enum_name* p, Fuzzer* fuzzer) { \
|
| - FuzzParam(reinterpret_cast<int*>(p), fuzzer); \
|
| - } \
|
| - };
|
| -
|
| -// Bring them into existence.
|
| -#include "tools/ipc_fuzzer/message_lib/all_messages.h"
|
| -
|
| -// Redefine macros to generate fuzzing funtions
|
| -#include "ipc/ipc_message_null_macros.h"
|
| -#undef IPC_MESSAGE_DECL
|
| -#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
|
| - IPC_##kind##_##type##_FUZZ(name, in, out, ilist, olist)
|
| -
|
| -#define IPC_EMPTY_CONTROL_FUZZ(name, in, out, ilist, olist) \
|
| - IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
|
| - return NULL; \
|
| - }
|
| -
|
| -#define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \
|
| - IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
|
| - return NULL; \
|
| - }
|
| -
|
| -#define IPC_ASYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
|
| - IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
|
| - name* real_msg = static_cast<name*>(msg); \
|
| - IPC_TUPLE_IN_##in ilist p; \
|
| - name::Read(real_msg, &p); \
|
| - FuzzParam(&p, fuzzer); \
|
| - return new name(IPC_MEMBERS_IN_##in(p)); \
|
| - }
|
| -
|
| -#define IPC_ASYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
|
| - IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
|
| - name* real_msg = static_cast<name*>(msg); \
|
| - IPC_TUPLE_IN_##in ilist p; \
|
| - name::Read(real_msg, &p); \
|
| - FuzzParam(&p, fuzzer); \
|
| - return new name(msg->routing_id() \
|
| - IPC_COMMA_##in \
|
| - IPC_MEMBERS_IN_##in(p)); \
|
| - }
|
| -
|
| -#define IPC_SYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
|
| - IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
|
| - name* real_msg = static_cast<name*>(msg); \
|
| - IPC_TUPLE_IN_##in ilist p; \
|
| - name::ReadSendParam(real_msg, &p); \
|
| - FuzzParam(&p, fuzzer); \
|
| - name* new_msg = new name(IPC_MEMBERS_IN_##in(p) \
|
| - IPC_COMMA_AND_##out(IPC_COMMA_##in) \
|
| - IPC_MEMBERS_OUT_##out()); \
|
| - MessageCracker::CopyMessageID(new_msg, real_msg); \
|
| - return new_msg; \
|
| - }
|
| -
|
| -
|
| -#define IPC_SYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
|
| - IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
|
| - name* real_msg = static_cast<name*>(msg); \
|
| - IPC_TUPLE_IN_##in ilist p; \
|
| - name::ReadSendParam(real_msg, &p); \
|
| - FuzzParam(&p, fuzzer); \
|
| - name* new_msg = new name(msg->routing_id() \
|
| - IPC_COMMA_OR_##out(IPC_COMMA_##in) \
|
| - IPC_MEMBERS_IN_##in(p) \
|
| - IPC_COMMA_AND_##out(IPC_COMMA_##in) \
|
| - IPC_MEMBERS_OUT_##out()); \
|
| - MessageCracker::CopyMessageID(new_msg, real_msg); \
|
| - return new_msg; \
|
| - }
|
| -
|
| -#define IPC_MEMBERS_IN_0(p)
|
| -#define IPC_MEMBERS_IN_1(p) get<0>(p)
|
| -#define IPC_MEMBERS_IN_2(p) get<0>(p), get<1>(p)
|
| -#define IPC_MEMBERS_IN_3(p) get<0>(p), get<1>(p), get<2>(p)
|
| -#define IPC_MEMBERS_IN_4(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p)
|
| -#define IPC_MEMBERS_IN_5(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p), \
|
| - get<4>(p)
|
| -
|
| -#define IPC_MEMBERS_OUT_0()
|
| -#define IPC_MEMBERS_OUT_1() NULL
|
| -#define IPC_MEMBERS_OUT_2() NULL, NULL
|
| -#define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
|
| -#define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
|
| -#define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
|
| -
|
| -#include "tools/ipc_fuzzer/message_lib/all_messages.h"
|
| -
|
| -typedef IPC::Message* (*FuzzFunction)(IPC::Message*, Fuzzer*);
|
| -typedef base::hash_map<uint32, FuzzFunction> FuzzFunctionMap;
|
| -
|
| -// Redefine macros to register fuzzing functions into map.
|
| -#include "ipc/ipc_message_null_macros.h"
|
| -#undef IPC_MESSAGE_DECL
|
| -#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
|
| - (*map)[static_cast<uint32>(name::ID)] = fuzzer_for_##name;
|
| -
|
| -void PopulateFuzzFunctionMap(FuzzFunctionMap *map) {
|
| -#include "tools/ipc_fuzzer/message_lib/all_messages.h"
|
| -}
|
| -
|
| -static IPC::Message* RewriteMessage(
|
| - IPC::Message* message,
|
| - Fuzzer* fuzzer,
|
| - FuzzFunctionMap* map) {
|
| - FuzzFunctionMap::iterator it = map->find(message->type());
|
| - if (it == map->end()) {
|
| - // This usually indicates a missing message file in all_messages.h, or
|
| - // that the message dump file is taken from a different revision of
|
| - // chromium from this executable.
|
| - std::cerr << "Unknown message type: ["
|
| - << IPC_MESSAGE_ID_CLASS(message->type()) << ", "
|
| - << IPC_MESSAGE_ID_LINE(message->type()) << "].\n";
|
| - return 0;
|
| - }
|
| -
|
| - return (*it->second)(message, fuzzer);
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -const char kHelpSwitch[] = "help";
|
| -const char kHelpSwitchHelp[] =
|
| - "show this message";
|
| -
|
| -const char kFrequencySwitch[] = "frequency";
|
| -const char kFrequencySwitchHelp[] =
|
| - "probability of mutation; tweak every 1/|q| times.";
|
| -
|
| -const char kFuzzerNameSwitch[] = "fuzzer-name";
|
| -const char kFuzzerNameSwitchHelp[] =
|
| - "select default or no-op fuzzer.";
|
| -
|
| -const char kPermuteSwitch[] = "permute";
|
| -const char kPermuteSwitchHelp[] =
|
| - "Randomly shuffle the order of all messages.";
|
| -
|
| -const char kTypeListSwitch[] = "type-list";
|
| -const char kTypeListSwitchHelp[] =
|
| - "explicit list of the only message-ids to mutate.";
|
| -
|
| -void usage() {
|
| - std::cerr << "Mutate messages from an exiting message file.\n";
|
| -
|
| - std::cerr << "Usage:\n"
|
| - << " ipc_fuzzer_mutate"
|
| - << " [--" << kHelpSwitch << "]"
|
| - << " [--" << kFuzzerNameSwitch << "=f]"
|
| - << " [--" << kFrequencySwitch << "=q]"
|
| - << " [--" << kTypeListSwitch << "=x,y,z...]"
|
| - << " [--" << kPermuteSwitch << "]"
|
| - << " infile outfile\n";
|
| -
|
| - std::cerr
|
| - << " --" << kHelpSwitch << " - " << kHelpSwitchHelp << "\n"
|
| - << " --" << kFuzzerNameSwitch << " - " << kFuzzerNameSwitchHelp << "\n"
|
| - << " --" << kFrequencySwitch << " - " << kFrequencySwitchHelp << "\n"
|
| - << " --" << kTypeListSwitch << " - " << kTypeListSwitchHelp << "\n"
|
| - << " --" << kPermuteSwitch << " - " << kPermuteSwitchHelp << "\n";
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -int MutateMain(int argc, char** argv) {
|
| - base::CommandLine::Init(argc, argv);
|
| - base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
|
| - base::CommandLine::StringVector args = cmd->GetArgs();
|
| -
|
| - if (args.size() != 2 || cmd->HasSwitch(kHelpSwitch)) {
|
| - usage();
|
| - return EXIT_FAILURE;
|
| - }
|
| -
|
| - base::FilePath::StringType input_file_name = args[0];
|
| - base::FilePath::StringType output_file_name = args[1];
|
| -
|
| - bool permute = cmd->HasSwitch(kPermuteSwitch);
|
| -
|
| - std::string fuzzer_name = "default";
|
| - if (cmd->HasSwitch(kFuzzerNameSwitch))
|
| - fuzzer_name = cmd->GetSwitchValueASCII(kFuzzerNameSwitch);
|
| -
|
| - int frequency = 23;
|
| - if (cmd->HasSwitch(kFrequencySwitch))
|
| - frequency = atoi(cmd->GetSwitchValueASCII(kFrequencySwitch).c_str());
|
| -
|
| - std::string type_string_list = cmd->GetSwitchValueASCII(kTypeListSwitch);
|
| - std::vector<std::string> type_string_vector;
|
| - base::SplitString(type_string_list, ',', &type_string_vector);
|
| - std::set<uint32> type_set;
|
| - for (size_t i = 0; i < type_string_vector.size(); ++i) {
|
| - type_set.insert(atoi(type_string_vector[i].c_str()));
|
| - }
|
| -
|
| - InitRand();
|
| -
|
| - Fuzzer* fuzzer = FuzzerFactory::Create(fuzzer_name, frequency);
|
| - if (!fuzzer)
|
| - return EXIT_FAILURE;
|
| -
|
| - FuzzFunctionMap fuzz_function_map;
|
| - PopulateFuzzFunctionMap(&fuzz_function_map);
|
| -
|
| - MessageVector message_vector;
|
| - if (!MessageFile::Read(base::FilePath(input_file_name), &message_vector))
|
| - return EXIT_FAILURE;
|
| -
|
| - for (size_t i = 0; i < message_vector.size(); ++i) {
|
| - IPC::Message* msg = message_vector[i];
|
| - if (!type_set.empty() && type_set.end() == std::find(
|
| - type_set.begin(), type_set.end(), msg->type())) {
|
| - continue;
|
| - }
|
| - IPC::Message* new_message = RewriteMessage(msg, fuzzer, &fuzz_function_map);
|
| - if (new_message) {
|
| - delete message_vector[i];
|
| - message_vector[i] = new_message;
|
| - }
|
| - }
|
| -
|
| - if (permute) {
|
| - std::random_shuffle(message_vector.begin(), message_vector.end(),
|
| - RandInRange);
|
| - }
|
| -
|
| - if (!MessageFile::Write(base::FilePath(output_file_name), message_vector))
|
| - return EXIT_FAILURE;
|
| -
|
| - return EXIT_SUCCESS;
|
| -}
|
| -
|
| -} // namespace ipc_fuzzer
|
| -
|
| -int main(int argc, char** argv) {
|
| - return ipc_fuzzer::MutateMain(argc, argv);
|
| -}
|
|
|