Bug: 112369099

Clone this repo:
  1. 7be9f8e Merge sc-mainline-prod by Xin Li · 1 year, 3 months ago android13-dev master
  2. 13cd878 [automerger skipped] Mark ab/7061308 as merged in stage. am: 9e21264e25 -s ours am: 102378d8ce -s ours am: 22628ae958 -s ours by Xin Li · 1 year, 6 months ago android12-mainline-art-release android12-mainline-networkstack-release android12-mainline-tzdata3-release android-mainline-12.0.0_r100 android-mainline-12.0.0_r113 android-mainline-12.0.0_r115 android-mainline-12.0.0_r122 android-mainline-12.0.0_r19 android-mainline-12.0.0_r22 android-mainline-12.0.0_r39 android-mainline-12.0.0_r42 android-mainline-12.0.0_r49 android-mainline-12.0.0_r5 android-mainline-12.0.0_r56 android-mainline-12.0.0_r59 android-mainline-12.0.0_r63 android-mainline-12.0.0_r69 android-mainline-12.0.0_r70 android-mainline-12.0.0_r77 android-mainline-12.0.0_r98 android-mainline-12.0.0_r99
  3. f89f3fb [automerger skipped] Mark ab/7061308 as merged in stage. am: 9e21264e25 -s ours am: 102378d8ce -s ours am: 22628ae958 -s ours by Xin Li · 1 year, 6 months ago
  4. 22628ae [automerger skipped] Mark ab/7061308 as merged in stage. am: 9e21264e25 -s ours am: 102378d8ce -s ours by Xin Li · 1 year, 6 months ago android-s-qpr3-beta-1 android-s-v2-beta-3 android-s-v2-preview-1 android-t-preview-1 android12--mainline-release android12-dev android12-qpr1-d-release android12-qpr1-d-s1-release android12-qpr1-d-s2-release android12-qpr1-d-s3-release android12-qpr1-release android12-qpr3-release android12-qpr3-s1-release android12-qpr3-s2-release android12-qpr3-s3-release android12-qpr3-s4-release android12-qpr3-s5-release android12-qpr3-s6-release android12-qpr3-s7-release android12L-d2-release android12L-d2-s1-release android12L-d2-s2-release android12L-d2-s3-release android12L-d2-s4-release android12L-d2-s5-release android12L-d2-s6-release android12L-d2-s7-release android12L-d2-s8-release android12L-dev gki13-boot-release android-12.0.0_r16 android-12.0.0_r18 android-12.0.0_r19 android-12.0.0_r20 android-12.0.0_r21 android-12.0.0_r26 android-12.0.0_r27 android-12.0.0_r28 android-12.0.0_r29 android-12.0.0_r32 android-12.1.0_r10 android-12.1.0_r11 android-12.1.0_r12 android-12.1.0_r13 android-12.1.0_r14 android-12.1.0_r15 android-12.1.0_r16 android-12.1.0_r17 android-12.1.0_r18 android-12.1.0_r19 android-12.1.0_r20 android-12.1.0_r21 android-12.1.0_r22 android-12.1.0_r23 android-12.1.0_r24 android-12.1.0_r25 android-12.1.0_r26 android-12.1.0_r7 android-12.1.0_r8 android-12.1.0_r9 android-mainline-12.0.0_r36 android-mainline-12.0.0_r4 android-s-qpr3-beta-1 android-s-v2-beta-2 android-s-v2-beta-3 android-s-v2-preview-1 android-s-v2-preview-2 android-t-beta-3 android-t-preview-1 android-t-preview-2
  5. 102378d [automerger skipped] Mark ab/7061308 as merged in stage. am: 9e21264e25 -s ours by Xin Li · 1 year, 6 months ago


TravisCI Build Status Fuzzing Status


libprotobuf-mutator is a library to randomly mutate protobuffers.
It could be used together with guided fuzzing engines, such as libFuzzer.

Quick start on Debian/Ubuntu

Install prerequisites:

sudo apt-get update
sudo apt-get install protobuf-compiler libprotobuf-dev binutils cmake \
  ninja-build liblzma-dev libz-dev pkg-config autoconf libtool

Compile and test everything:

mkdir build
cd build
ninja check

Clang is only needed for libFuzzer integration.
By default, the system-installed version of protobuf is used. However, on some systems, the system version is too old. You can pass LIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON to cmake to automatically download and build a working version of protobuf.


sudo ninja install

This installs the headers, pkg-config, and static library. By default the headers are put in /usr/local/include/libprotobuf-mutator.


To use libprotobuf-mutator simply include mutator.h and mutator.cc into your build files.

The ProtobufMutator class implements mutations of the protobuf tree structure and mutations of individual fields. The field mutation logic is very basic -- for better results you should override the ProtobufMutator::Mutate* methods with more sophisticated logic, e.g. using libFuzzer's mutators.

To apply one mutation to a protobuf object do the following:

class MyProtobufMutator : public protobuf_mutator::Mutator {
  // Optionally redefine the Mutate* methods to perform more sophisticated mutations.
void Mutate(MyMessage* message) {
  MyProtobufMutator mutator;
  mutator.Mutate(message, 200);

See also the ProtobufMutatorMessagesTest.UsageExample test from mutator_test.cc.

Integrating with libFuzzer

LibFuzzerProtobufMutator can help to integrate with libFuzzer. For example

#include "src/libfuzzer/libfuzzer_macro.h"

DEFINE_PROTO_FUZZER(const MyMessageType& input) {
  // Code which needs to be fuzzed.

Please see libfuzzer_example.cc as an example.

Mutation post-processing (experimental)

Sometimes it‘s necessary to keep particular values in some fields without which the proto is going to be rejected by fuzzed code. E.g. code may expect consistency between some fields or it may use some fields as checksums. Such constraints are going to be significant bottleneck for fuzzer even if it’s capable of inserting acceptable values with time.

PostProcessorRegistration can be used to avoid such issue and guide your fuzzer towards interesting code. It registers callback which will be called for each message of particular type after each mutation.

static protobuf_mutator::libfuzzer::PostProcessorRegistration<MyMessageType> reg = {
    [](MyMessageType* message, unsigned int seed) {
      TweakMyMessage(message, seed);

DEFINE_PROTO_FUZZER(const MyMessageType& input) {
  // Code which needs to be fuzzed.

Optional: Use seed if callback uses random numbers. It may help later with debugging.

Important: Callbacks should be deterministic and avoid modifying good messages. Callbacks are called for both: mutator generated and user provided inputs, like corpus or bug reproducer. So if callback performs unnecessary transformation it may corrupt the reproducer so it stops triggering the bug.

Note: You can add callback for any nested message and you can add multiple callbacks for the same message type.

DEFINE_PROTO_FUZZER(const MyMessageType& input) {
  static PostProcessorRegistration reg1 = {
      [](MyMessageType* message, unsigned int seed) {
        TweakMyMessage(message, seed);
  static PostProcessorRegistration reg2 = {
      [](MyMessageType* message, unsigned int seed) {
        DifferentTweakMyMessage(message, seed);
  static PostProcessorRegistration reg_nested = {
      [](MyMessageType::Nested* message, unsigned int seed) {
        TweakMyNestedMessage(message, seed);

  // Code which needs to be fuzzed.

UTF-8 strings

“proto2” and “proto3” handle invalid UTF-8 strings differently. In both cases string should be UTF-8, however only “proto3” enforces that. So if fuzzer is applied to “proto2” type libprotobuf-mutator will generate any strings including invalid UTF-8. If it's a “proto3” message type, only valid UTF-8 will be used.

Users of the library

Bugs found with help of the library



Related materials