• Home
Name Date Size #Lines LOC

..--

cmake/external/03-May-2024-239206

examples/03-May-2024-962648

port/03-May-2024-5818

src/03-May-2024-3,5292,646

.clang-formatD03-May-202422 21

.gitignoreD03-May-20247 21

.travis.ymlD03-May-20241.7 KiB6352

AUTHORSD03-May-2024329 96

Android.bpD03-May-20241.4 KiB4441

CMakeLists.txtD03-May-20245.5 KiB158128

CONTRIBUTINGD03-May-20241.4 KiB2824

LICENSED03-May-202411.1 KiB203169

METADATAD03-May-2024426 1615

MODULE_LICENSE_APACHE2D03-May-20240

NOTICED03-May-202411.1 KiB203169

OWNERSD03-May-2024127 64

README.mdD03-May-20246.5 KiB161129

libprotobuf-mutator.pc.inD03-May-2024269 97

README.md

1# libprotobuf-mutator
2
3[![TravisCI Build Status](https://travis-ci.org/google/libprotobuf-mutator.svg?branch=master)](https://travis-ci.org/google/libprotobuf-mutator)
4[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libprotobuf-mutator.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libprotobuf-mutator)
5
6## Overview
7libprotobuf-mutator is a library to randomly mutate
8[protobuffers](https://github.com/google/protobuf). <BR>
9It could be used together with guided fuzzing engines, such as [libFuzzer](http://libfuzzer.info).
10
11## Quick start on Debian/Ubuntu
12
13Install prerequisites:
14
15```
16sudo apt-get update
17sudo apt-get install protobuf-compiler libprotobuf-dev binutils cmake \
18  ninja-build liblzma-dev libz-dev pkg-config autoconf libtool
19```
20
21Compile and test everything:
22
23```
24mkdir build
25cd build
26cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug
27ninja check
28```
29
30Clang is only needed for libFuzzer integration. <BR>
31By default, the system-installed version of
32[protobuf](https://github.com/google/protobuf) is used.  However, on some
33systems, the system version is too old.  You can pass
34`LIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON` to cmake to automatically download and
35build a working version of protobuf.
36
37Installation:
38
39```
40ninja
41sudo ninja install
42```
43
44This installs the headers, pkg-config, and static library.
45By default the headers are put in `/usr/local/include/libprotobuf-mutator`.
46
47## Usage
48
49To use libprotobuf-mutator simply include
50[mutator.h](/src/mutator.h) and
51[mutator.cc](/src/mutator.cc) into your build files.
52
53The `ProtobufMutator` class implements mutations of the protobuf
54tree structure and mutations of individual fields.
55The field mutation logic is very basic --
56for better results you should override the `ProtobufMutator::Mutate*`
57methods with more sophisticated logic, e.g.
58using [libFuzzer](http://libfuzzer.info)'s mutators.
59
60To apply one mutation to a protobuf object do the following:
61
62```
63class MyProtobufMutator : public protobuf_mutator::Mutator {
64 public:
65  // Optionally redefine the Mutate* methods to perform more sophisticated mutations.
66}
67void Mutate(MyMessage* message) {
68  MyProtobufMutator mutator;
69  mutator.Seed(my_random_seed);
70  mutator.Mutate(message, 200);
71}
72```
73
74See also the `ProtobufMutatorMessagesTest.UsageExample` test from
75[mutator_test.cc](/src/mutator_test.cc).
76
77## Integrating with libFuzzer
78LibFuzzerProtobufMutator can help to integrate with libFuzzer. For example
79
80```
81#include "src/libfuzzer/libfuzzer_macro.h"
82
83DEFINE_PROTO_FUZZER(const MyMessageType& input) {
84  // Code which needs to be fuzzed.
85  ConsumeMyMessageType(input);
86}
87```
88
89Please see [libfuzzer_example.cc](/examples/libfuzzer/libfuzzer_example.cc) as an example.
90
91### Mutation post-processing (experimental)
92Sometimes it's necessary to keep particular values in some fields without which the proto
93is going to be rejected by fuzzed code. E.g. code may expect consistency between some fields
94or it may use some fields as checksums. Such constraints are going to be significant bottleneck
95for fuzzer even if it's capable of inserting acceptable values with time.
96
97PostProcessorRegistration can be used to avoid such issue and guide your fuzzer towards interesting
98code. It registers callback which will be called for each message of particular type after each mutation.
99
100```
101DEFINE_PROTO_FUZZER(const MyMessageType& input) {
102  static PostProcessorRegistration reg = {
103      [](MyMessageType* message, unsigned int seed) {
104        TweakMyMessage(message, seed);
105      }};
106
107  // Code which needs to be fuzzed.
108  ConsumeMyMessageType(input);
109}
110```
111Optional: Use seed if callback uses random numbers. It may help later with debugging.
112
113Note: You can add callback for any nested message and you can add multiple callbacks for
114the same message type.
115```
116DEFINE_PROTO_FUZZER(const MyMessageType& input) {
117  static PostProcessorRegistration reg1 = {
118      [](MyMessageType* message, unsigned int seed) {
119        TweakMyMessage(message, seed);
120      }};
121  static PostProcessorRegistration reg2 = {
122      [](MyMessageType* message, unsigned int seed) {
123        DifferentTweakMyMessage(message, seed);
124      }};
125  static PostProcessorRegistration reg_nested = {
126      [](MyMessageType::Nested* message, unsigned int seed) {
127        TweakMyNestedMessage(message, seed);
128      }};
129
130  // Code which needs to be fuzzed.
131  ConsumeMyMessageType(input);
132}
133```
134## UTF-8 strings
135"proto2" and "proto3" handle invalid UTF-8 strings differently. In both cases
136string should be UTF-8, however only "proto3" enforces that. So if fuzzer is
137applied to "proto2" type libprotobuf-mutator will generate any strings including
138invalid UTF-8. If it's a "proto3" message type, only valid UTF-8 will be used.
139
140## Users of the library
141* [Chromium](https://cs.chromium.org/search/?q=DEFINE_.*._PROTO_FUZZER%5C\()
142* [Envoy](https://github.com/envoyproxy/envoy/search?q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&unscoped_q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&type=Code)
143* [LLVM](https://github.com/llvm-mirror/clang/search?q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&unscoped_q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&type=Code)
144
145## Bugs found with help of the library
146
147### Chromium
148* [AppCache exploit](http://www.powerofcommunity.net/poc2018/ned.pdf) ([Actual still restricted bug](https://bugs.chromium.org/p/chromium/issues/detail?id=888926))
149* [Stack Buffer Overflow in QuicClientPromisedInfo](https://bugs.chromium.org/p/chromium/issues/detail?id=777728)
150* [null dereference in sqlite3ExprCompare](https://bugs.chromium.org/p/chromium/issues/detail?id=911251)
151### Envoy
152* [strftime overflow](https://github.com/envoyproxy/envoy/pull/4321)
153* [Heap-use-after-free in Envoy::Upstream::SubsetLoadBalancer::updateFallbackSubset](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8028)
154* [Heap-use-after-free in Envoy::Secret::SecretManagerImpl](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11231)
155* [Heap-buffer-overflow in Envoy::Http::HeaderString](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10038)
156
157## Related materials
158* [Attacking Chrome IPC: Reliably finding bugs to escape the Chrome sandbox](https://media.ccc.de/v/35c3-9579-attacking_chrome_ipc)
159* [Structure-aware fuzzing for Clang and LLVM with libprotobuf-mutator](https://www.youtube.com/watch?v=U60hC16HEDY)
160* [Structure-Aware Fuzzing with libFuzzer](https://github.com/google/fuzzer-test-suite/blob/master/tutorial/structure-aware-fuzzing.md)
161