← All libraries
Parser · C
How to fuzz protobuf-c
Protobuf's wire format is compact but its C deserializer has manual length arithmetic.
protobuf-c deserializes binary wire-format messages in C without the safety nets of the C++ runtime. Maliciously crafted varint sequences, embedded length fields, and repeated-field counts can trigger integer overflows in the allocator sizing path, affecting any embedded or IoT firmware that uses protobuf for IPC.
Common bug classes
- •Heap buffer overflow in repeated-field array allocation sizing
- •Integer overflow in varint 64-bit accumulation
- •Out-of-bounds read on truncated length-delimited field
- •Null dereference on missing required field in strict mode
- •Infinite loop on varint with all high bits set
Recommended setup
Fuzzers
- → AFL++
- → libFuzzer
Sanitizers
- → ASan
- → UBSan
Harness scaffold
#include <stdint.h>
#include <stddef.h>
#include <protobuf-c/protobuf-c.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
/* Generic unpack into scratch descriptor — replace MyMsg with target */
ProtobufCAllocator alloc = PROTOBUF_C_ALLOCATOR_DEFAULT;
/* Demonstrate wire-format scan without a concrete descriptor */
ProtobufCBufferSimple buf = PROTOBUF_C_BUFFER_SIMPLE_INIT(NULL);
protobuf_c_buffer_simple_append(&buf.base, size, data);
PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&buf);
return 0;
}Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.
Push the harness above + a Dockerfile. First month 50% off.