xref: /freebsd-src/contrib/libcbor/oss-fuzz/cbor_load_fuzzer.cc (revision 5d3e7166f6a0187fa3f8831b16a06bd9955c21ff)
110ff414cSEd Maste #include <cstdint>
210ff414cSEd Maste #include <cstdio>
3*5d3e7166SEd Maste #include <cstdlib>
4*5d3e7166SEd Maste #include <unordered_map>
510ff414cSEd Maste 
610ff414cSEd Maste #include "cbor.h"
710ff414cSEd Maste 
8*5d3e7166SEd Maste static size_t allocated_mem = 0;
9*5d3e7166SEd Maste static std::unordered_map<void*, size_t> allocated_len_map;
10*5d3e7166SEd Maste static constexpr size_t kMemoryLimit = 1 << 30;
11*5d3e7166SEd Maste 
limited_malloc(size_t size)1210ff414cSEd Maste void *limited_malloc(size_t size) {
13*5d3e7166SEd Maste     if (size + allocated_mem > kMemoryLimit) {
1410ff414cSEd Maste         return nullptr;
1510ff414cSEd Maste     }
16*5d3e7166SEd Maste     if (size == 0) {
17*5d3e7166SEd Maste         return nullptr;
18*5d3e7166SEd Maste     }
19*5d3e7166SEd Maste     void* m = malloc(size);
20*5d3e7166SEd Maste     if (m != nullptr) {
21*5d3e7166SEd Maste         allocated_mem += size;
22*5d3e7166SEd Maste         allocated_len_map[m] = size;
23*5d3e7166SEd Maste     }
24*5d3e7166SEd Maste     return m;
25*5d3e7166SEd Maste }
26*5d3e7166SEd Maste 
limited_free(void * ptr)27*5d3e7166SEd Maste void limited_free(void *ptr) {
28*5d3e7166SEd Maste     if (ptr != NULL && allocated_len_map.find(ptr) == allocated_len_map.end()) {
29*5d3e7166SEd Maste         abort();
30*5d3e7166SEd Maste     }
31*5d3e7166SEd Maste     free(ptr);
32*5d3e7166SEd Maste     if (ptr != NULL) {
33*5d3e7166SEd Maste         allocated_mem -= allocated_len_map[ptr];
34*5d3e7166SEd Maste         allocated_len_map.erase(ptr);
35*5d3e7166SEd Maste     }
36*5d3e7166SEd Maste }
37*5d3e7166SEd Maste 
limited_realloc(void * ptr,size_t size)38*5d3e7166SEd Maste void *limited_realloc(void *ptr, size_t size) {
39*5d3e7166SEd Maste     if (ptr != NULL && allocated_len_map.find(ptr) == allocated_len_map.end()) {
40*5d3e7166SEd Maste         abort();
41*5d3e7166SEd Maste     }
42*5d3e7166SEd Maste     if (ptr == NULL) {
43*5d3e7166SEd Maste         return limited_malloc(size);
44*5d3e7166SEd Maste     }
45*5d3e7166SEd Maste     long delta = (long) size - allocated_len_map[ptr];
46*5d3e7166SEd Maste     if (delta + allocated_mem > kMemoryLimit) {
47*5d3e7166SEd Maste         return nullptr;
48*5d3e7166SEd Maste     }
49*5d3e7166SEd Maste     void* new_ptr = realloc(ptr, size);
50*5d3e7166SEd Maste     if (size > 0 && new_ptr == nullptr) {
51*5d3e7166SEd Maste         return nullptr;
52*5d3e7166SEd Maste     }
53*5d3e7166SEd Maste     allocated_mem += delta;
54*5d3e7166SEd Maste     allocated_len_map.erase(ptr);
55*5d3e7166SEd Maste     if (size > 0) {
56*5d3e7166SEd Maste         allocated_len_map[new_ptr] = size;
57*5d3e7166SEd Maste     }
58*5d3e7166SEd Maste     return new_ptr;
5910ff414cSEd Maste }
6010ff414cSEd Maste 
6110ff414cSEd Maste struct State {
6210ff414cSEd Maste     FILE* fout;
6310ff414cSEd Maste 
StateState6410ff414cSEd Maste     State() : fout(fopen("/dev/null", "r")) {
65*5d3e7166SEd Maste         cbor_set_allocs(limited_malloc, limited_realloc, limited_free);
6610ff414cSEd Maste     }
6710ff414cSEd Maste };
6810ff414cSEd Maste 
6910ff414cSEd Maste static State kState;
7010ff414cSEd Maste 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)7110ff414cSEd Maste extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
7210ff414cSEd Maste     cbor_load_result result;
7310ff414cSEd Maste     cbor_item_t *item = cbor_load(Data, Size, &result);
7410ff414cSEd Maste     if (result.error.code == CBOR_ERR_NONE) {
7510ff414cSEd Maste         cbor_describe(item, kState.fout);
7610ff414cSEd Maste         unsigned char *buffer;
7710ff414cSEd Maste         size_t buffer_size;
7810ff414cSEd Maste         cbor_serialize_alloc(item, &buffer, &buffer_size);
7910ff414cSEd Maste         free(buffer);
8010ff414cSEd Maste         cbor_item_t *copied = cbor_copy(item);
8110ff414cSEd Maste         cbor_decref(&copied);
8210ff414cSEd Maste         cbor_decref(&item);
8310ff414cSEd Maste     }
8410ff414cSEd Maste     return 0;
8510ff414cSEd Maste }
86