xref: /aosp_15_r20/external/libprotobuf-mutator/README.md (revision fd525a9c096e28cf6f8d8719388df0568a611e7b)
1*fd525a9cSAndroid Build Coastguard Worker# libprotobuf-mutator
2*fd525a9cSAndroid Build Coastguard Worker
3*fd525a9cSAndroid Build Coastguard Worker[![TravisCI Build Status](https://travis-ci.org/google/libprotobuf-mutator.svg?branch=master)](https://travis-ci.org/google/libprotobuf-mutator)
4*fd525a9cSAndroid Build Coastguard Worker[![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*fd525a9cSAndroid Build Coastguard Worker
6*fd525a9cSAndroid Build Coastguard Worker## Overview
7*fd525a9cSAndroid Build Coastguard Workerlibprotobuf-mutator is a library to randomly mutate
8*fd525a9cSAndroid Build Coastguard Worker[protobuffers](https://github.com/google/protobuf). <BR>
9*fd525a9cSAndroid Build Coastguard WorkerIt could be used together with guided fuzzing engines, such as [libFuzzer](http://libfuzzer.info).
10*fd525a9cSAndroid Build Coastguard Worker
11*fd525a9cSAndroid Build Coastguard Worker## Quick start on Debian/Ubuntu
12*fd525a9cSAndroid Build Coastguard Worker
13*fd525a9cSAndroid Build Coastguard WorkerInstall prerequisites:
14*fd525a9cSAndroid Build Coastguard Worker
15*fd525a9cSAndroid Build Coastguard Worker```
16*fd525a9cSAndroid Build Coastguard Workersudo apt-get update
17*fd525a9cSAndroid Build Coastguard Workersudo apt-get install protobuf-compiler libprotobuf-dev binutils cmake \
18*fd525a9cSAndroid Build Coastguard Worker  ninja-build liblzma-dev libz-dev pkg-config autoconf libtool
19*fd525a9cSAndroid Build Coastguard Worker```
20*fd525a9cSAndroid Build Coastguard Worker
21*fd525a9cSAndroid Build Coastguard WorkerCompile and test everything:
22*fd525a9cSAndroid Build Coastguard Worker
23*fd525a9cSAndroid Build Coastguard Worker```
24*fd525a9cSAndroid Build Coastguard Workermkdir build
25*fd525a9cSAndroid Build Coastguard Workercd build
26*fd525a9cSAndroid Build Coastguard Workercmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug
27*fd525a9cSAndroid Build Coastguard Workerninja check
28*fd525a9cSAndroid Build Coastguard Worker```
29*fd525a9cSAndroid Build Coastguard Worker
30*fd525a9cSAndroid Build Coastguard WorkerClang is only needed for libFuzzer integration. <BR>
31*fd525a9cSAndroid Build Coastguard WorkerBy default, the system-installed version of
32*fd525a9cSAndroid Build Coastguard Worker[protobuf](https://github.com/google/protobuf) is used.  However, on some
33*fd525a9cSAndroid Build Coastguard Workersystems, the system version is too old.  You can pass
34*fd525a9cSAndroid Build Coastguard Worker`LIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON` to cmake to automatically download and
35*fd525a9cSAndroid Build Coastguard Workerbuild a working version of protobuf.
36*fd525a9cSAndroid Build Coastguard Worker
37*fd525a9cSAndroid Build Coastguard WorkerInstallation:
38*fd525a9cSAndroid Build Coastguard Worker
39*fd525a9cSAndroid Build Coastguard Worker```
40*fd525a9cSAndroid Build Coastguard Workerninja
41*fd525a9cSAndroid Build Coastguard Workersudo ninja install
42*fd525a9cSAndroid Build Coastguard Worker```
43*fd525a9cSAndroid Build Coastguard Worker
44*fd525a9cSAndroid Build Coastguard WorkerThis installs the headers, pkg-config, and static library.
45*fd525a9cSAndroid Build Coastguard WorkerBy default the headers are put in `/usr/local/include/libprotobuf-mutator`.
46*fd525a9cSAndroid Build Coastguard Worker
47*fd525a9cSAndroid Build Coastguard Worker## Usage
48*fd525a9cSAndroid Build Coastguard Worker
49*fd525a9cSAndroid Build Coastguard WorkerTo use libprotobuf-mutator simply include
50*fd525a9cSAndroid Build Coastguard Worker[mutator.h](/src/mutator.h) and
51*fd525a9cSAndroid Build Coastguard Worker[mutator.cc](/src/mutator.cc) into your build files.
52*fd525a9cSAndroid Build Coastguard Worker
53*fd525a9cSAndroid Build Coastguard WorkerThe `ProtobufMutator` class implements mutations of the protobuf
54*fd525a9cSAndroid Build Coastguard Workertree structure and mutations of individual fields.
55*fd525a9cSAndroid Build Coastguard WorkerThe field mutation logic is very basic --
56*fd525a9cSAndroid Build Coastguard Workerfor better results you should override the `ProtobufMutator::Mutate*`
57*fd525a9cSAndroid Build Coastguard Workermethods with more sophisticated logic, e.g.
58*fd525a9cSAndroid Build Coastguard Workerusing [libFuzzer](http://libfuzzer.info)'s mutators.
59*fd525a9cSAndroid Build Coastguard Worker
60*fd525a9cSAndroid Build Coastguard WorkerTo apply one mutation to a protobuf object do the following:
61*fd525a9cSAndroid Build Coastguard Worker
62*fd525a9cSAndroid Build Coastguard Worker```
63*fd525a9cSAndroid Build Coastguard Workerclass MyProtobufMutator : public protobuf_mutator::Mutator {
64*fd525a9cSAndroid Build Coastguard Worker public:
65*fd525a9cSAndroid Build Coastguard Worker  // Optionally redefine the Mutate* methods to perform more sophisticated mutations.
66*fd525a9cSAndroid Build Coastguard Worker}
67*fd525a9cSAndroid Build Coastguard Workervoid Mutate(MyMessage* message) {
68*fd525a9cSAndroid Build Coastguard Worker  MyProtobufMutator mutator;
69*fd525a9cSAndroid Build Coastguard Worker  mutator.Seed(my_random_seed);
70*fd525a9cSAndroid Build Coastguard Worker  mutator.Mutate(message, 200);
71*fd525a9cSAndroid Build Coastguard Worker}
72*fd525a9cSAndroid Build Coastguard Worker```
73*fd525a9cSAndroid Build Coastguard Worker
74*fd525a9cSAndroid Build Coastguard WorkerSee also the `ProtobufMutatorMessagesTest.UsageExample` test from
75*fd525a9cSAndroid Build Coastguard Worker[mutator_test.cc](/src/mutator_test.cc).
76*fd525a9cSAndroid Build Coastguard Worker
77*fd525a9cSAndroid Build Coastguard Worker## Integrating with libFuzzer
78*fd525a9cSAndroid Build Coastguard WorkerLibFuzzerProtobufMutator can help to integrate with libFuzzer. For example
79*fd525a9cSAndroid Build Coastguard Worker
80*fd525a9cSAndroid Build Coastguard Worker```
81*fd525a9cSAndroid Build Coastguard Worker#include "src/libfuzzer/libfuzzer_macro.h"
82*fd525a9cSAndroid Build Coastguard Worker
83*fd525a9cSAndroid Build Coastguard WorkerDEFINE_PROTO_FUZZER(const MyMessageType& input) {
84*fd525a9cSAndroid Build Coastguard Worker  // Code which needs to be fuzzed.
85*fd525a9cSAndroid Build Coastguard Worker  ConsumeMyMessageType(input);
86*fd525a9cSAndroid Build Coastguard Worker}
87*fd525a9cSAndroid Build Coastguard Worker```
88*fd525a9cSAndroid Build Coastguard Worker
89*fd525a9cSAndroid Build Coastguard WorkerPlease see [libfuzzer_example.cc](/examples/libfuzzer/libfuzzer_example.cc) as an example.
90*fd525a9cSAndroid Build Coastguard Worker
91*fd525a9cSAndroid Build Coastguard Worker### Mutation post-processing (experimental)
92*fd525a9cSAndroid Build Coastguard WorkerSometimes it's necessary to keep particular values in some fields without which the proto
93*fd525a9cSAndroid Build Coastguard Workeris going to be rejected by fuzzed code. E.g. code may expect consistency between some fields
94*fd525a9cSAndroid Build Coastguard Workeror it may use some fields as checksums. Such constraints are going to be significant bottleneck
95*fd525a9cSAndroid Build Coastguard Workerfor fuzzer even if it's capable of inserting acceptable values with time.
96*fd525a9cSAndroid Build Coastguard Worker
97*fd525a9cSAndroid Build Coastguard WorkerPostProcessorRegistration can be used to avoid such issue and guide your fuzzer towards interesting
98*fd525a9cSAndroid Build Coastguard Workercode. It registers callback which will be called for each message of particular type after each mutation.
99*fd525a9cSAndroid Build Coastguard Worker
100*fd525a9cSAndroid Build Coastguard Worker```
101*fd525a9cSAndroid Build Coastguard Workerstatic protobuf_mutator::libfuzzer::PostProcessorRegistration<MyMessageType> reg = {
102*fd525a9cSAndroid Build Coastguard Worker    [](MyMessageType* message, unsigned int seed) {
103*fd525a9cSAndroid Build Coastguard Worker      TweakMyMessage(message, seed);
104*fd525a9cSAndroid Build Coastguard Worker    }};
105*fd525a9cSAndroid Build Coastguard Worker
106*fd525a9cSAndroid Build Coastguard WorkerDEFINE_PROTO_FUZZER(const MyMessageType& input) {
107*fd525a9cSAndroid Build Coastguard Worker  // Code which needs to be fuzzed.
108*fd525a9cSAndroid Build Coastguard Worker  ConsumeMyMessageType(input);
109*fd525a9cSAndroid Build Coastguard Worker}
110*fd525a9cSAndroid Build Coastguard Worker```
111*fd525a9cSAndroid Build Coastguard WorkerOptional: Use seed if callback uses random numbers. It may help later with debugging.
112*fd525a9cSAndroid Build Coastguard Worker
113*fd525a9cSAndroid Build Coastguard WorkerImportant: Callbacks should be deterministic and avoid modifying good messages.
114*fd525a9cSAndroid Build Coastguard WorkerCallbacks are called for both: mutator generated and user provided inputs, like
115*fd525a9cSAndroid Build Coastguard Workercorpus or bug reproducer. So if callback performs unnecessary transformation it
116*fd525a9cSAndroid Build Coastguard Workermay corrupt the reproducer so it stops triggering the bug.
117*fd525a9cSAndroid Build Coastguard Worker
118*fd525a9cSAndroid Build Coastguard WorkerNote: You can add callback for any nested message and you can add multiple callbacks for
119*fd525a9cSAndroid Build Coastguard Workerthe same message type.
120*fd525a9cSAndroid Build Coastguard Worker```
121*fd525a9cSAndroid Build Coastguard Workerstatic PostProcessorRegistration<MyMessageType> reg1 = {
122*fd525a9cSAndroid Build Coastguard Worker    [](MyMessageType* message, unsigned int seed) {
123*fd525a9cSAndroid Build Coastguard Worker      TweakMyMessage(message, seed);
124*fd525a9cSAndroid Build Coastguard Worker    }};
125*fd525a9cSAndroid Build Coastguard Workerstatic PostProcessorRegistration<MyMessageType> reg2 = {
126*fd525a9cSAndroid Build Coastguard Worker    [](MyMessageType* message, unsigned int seed) {
127*fd525a9cSAndroid Build Coastguard Worker      DifferentTweakMyMessage(message, seed);
128*fd525a9cSAndroid Build Coastguard Worker    }};
129*fd525a9cSAndroid Build Coastguard Workerstatic PostProcessorRegistration<MyMessageType::Nested> reg_nested = {
130*fd525a9cSAndroid Build Coastguard Worker    [](MyMessageType::Nested* message, unsigned int seed) {
131*fd525a9cSAndroid Build Coastguard Worker      TweakMyNestedMessage(message, seed);
132*fd525a9cSAndroid Build Coastguard Worker    }};
133*fd525a9cSAndroid Build Coastguard Worker
134*fd525a9cSAndroid Build Coastguard WorkerDEFINE_PROTO_FUZZER(const MyMessageType& input) {
135*fd525a9cSAndroid Build Coastguard Worker  // Code which needs to be fuzzed.
136*fd525a9cSAndroid Build Coastguard Worker  ConsumeMyMessageType(input);
137*fd525a9cSAndroid Build Coastguard Worker}
138*fd525a9cSAndroid Build Coastguard Worker```
139*fd525a9cSAndroid Build Coastguard Worker## UTF-8 strings
140*fd525a9cSAndroid Build Coastguard Worker"proto2" and "proto3" handle invalid UTF-8 strings differently. In both cases
141*fd525a9cSAndroid Build Coastguard Workerstring should be UTF-8, however only "proto3" enforces that. So if fuzzer is
142*fd525a9cSAndroid Build Coastguard Workerapplied to "proto2" type libprotobuf-mutator will generate any strings including
143*fd525a9cSAndroid Build Coastguard Workerinvalid UTF-8. If it's a "proto3" message type, only valid UTF-8 will be used.
144*fd525a9cSAndroid Build Coastguard Worker
145*fd525a9cSAndroid Build Coastguard Worker## Extensions
146*fd525a9cSAndroid Build Coastguard WorkerCurrently the library does not mutate
147*fd525a9cSAndroid Build Coastguard Worker[extensions](https://developers.google.com/protocol-buffers/docs/proto#extensions).
148*fd525a9cSAndroid Build Coastguard WorkerThis can be a problem if extension contains required fields so the library will not
149*fd525a9cSAndroid Build Coastguard Workerbe able to change the message into valid initialized state.
150*fd525a9cSAndroid Build Coastguard WorkerYou can use [post processing hooks](#mutation-post-processing-experimental) to
151*fd525a9cSAndroid Build Coastguard Workercleanup/initialize the message as workaround.
152*fd525a9cSAndroid Build Coastguard Worker
153*fd525a9cSAndroid Build Coastguard Worker## Users of the library
154*fd525a9cSAndroid Build Coastguard Worker* [Chromium](https://cs.chromium.org/search/?q=DEFINE_.*._PROTO_FUZZER%5C\()
155*fd525a9cSAndroid Build Coastguard Worker* [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)
156*fd525a9cSAndroid Build Coastguard Worker* [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)
157*fd525a9cSAndroid Build Coastguard Worker
158*fd525a9cSAndroid Build Coastguard Worker## Bugs found with help of the library
159*fd525a9cSAndroid Build Coastguard Worker
160*fd525a9cSAndroid Build Coastguard Worker### Chromium
161*fd525a9cSAndroid Build Coastguard Worker* [AppCache exploit](http://www.powerofcommunity.net/poc2018/ned.pdf) ([Actual still restricted bug](https://bugs.chromium.org/p/chromium/issues/detail?id=888926))
162*fd525a9cSAndroid Build Coastguard Worker* [Stack Buffer Overflow in QuicClientPromisedInfo](https://bugs.chromium.org/p/chromium/issues/detail?id=777728)
163*fd525a9cSAndroid Build Coastguard Worker* [null dereference in sqlite3ExprCompare](https://bugs.chromium.org/p/chromium/issues/detail?id=911251)
164*fd525a9cSAndroid Build Coastguard Worker### Envoy
165*fd525a9cSAndroid Build Coastguard Worker* [strftime overflow](https://github.com/envoyproxy/envoy/pull/4321)
166*fd525a9cSAndroid Build Coastguard Worker* [Heap-use-after-free in Envoy::Upstream::SubsetLoadBalancer::updateFallbackSubset](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8028)
167*fd525a9cSAndroid Build Coastguard Worker* [Heap-use-after-free in Envoy::Secret::SecretManagerImpl](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11231)
168*fd525a9cSAndroid Build Coastguard Worker* [Heap-buffer-overflow in Envoy::Http::HeaderString](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10038)
169*fd525a9cSAndroid Build Coastguard Worker
170*fd525a9cSAndroid Build Coastguard Worker## Related materials
171*fd525a9cSAndroid Build Coastguard Worker* [Attacking Chrome IPC: Reliably finding bugs to escape the Chrome sandbox](https://media.ccc.de/v/35c3-9579-attacking_chrome_ipc)
172*fd525a9cSAndroid Build Coastguard Worker* [Structure-aware fuzzing for Clang and LLVM with libprotobuf-mutator](https://www.youtube.com/watch?v=U60hC16HEDY)
173*fd525a9cSAndroid Build Coastguard Worker* [Structure-Aware Fuzzing with libFuzzer](https://github.com/google/fuzzer-test-suite/blob/master/tutorial/structure-aware-fuzzing.md)
174