xref: /aosp_15_r20/external/puffin/src/fuzzer_puffpatch.cc (revision 07fb1d065b7cfb4729786fadd42a612532d2f466)
1*07fb1d06SElliott Hughes // Copyright 2018 The ChromiumOS Authors
2*07fb1d06SElliott Hughes // Use of this source code is governed by a BSD-style license that can be
3*07fb1d06SElliott Hughes // found in the LICENSE file.
4*07fb1d06SElliott Hughes 
5*07fb1d06SElliott Hughes #include <vector>
6*07fb1d06SElliott Hughes 
7*07fb1d06SElliott Hughes #include "base/logging.h"
8*07fb1d06SElliott Hughes #include "brillo/test_helpers.h"
9*07fb1d06SElliott Hughes 
10*07fb1d06SElliott Hughes #include "puffin/memory_stream.h"
11*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/common.h"
12*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/puffpatch.h"
13*07fb1d06SElliott Hughes 
14*07fb1d06SElliott Hughes using puffin::BitExtent;
15*07fb1d06SElliott Hughes using puffin::Buffer;
16*07fb1d06SElliott Hughes using puffin::ByteExtent;
17*07fb1d06SElliott Hughes using puffin::MemoryStream;
18*07fb1d06SElliott Hughes using std::vector;
19*07fb1d06SElliott Hughes 
20*07fb1d06SElliott Hughes namespace puffin {
21*07fb1d06SElliott Hughes // From puffpatch.cc
22*07fb1d06SElliott Hughes bool DecodePatch(const uint8_t* patch,
23*07fb1d06SElliott Hughes                  size_t patch_length,
24*07fb1d06SElliott Hughes                  size_t* bsdiff_patch_offset,
25*07fb1d06SElliott Hughes                  size_t* bsdiff_patch_size,
26*07fb1d06SElliott Hughes                  vector<BitExtent>* src_deflates,
27*07fb1d06SElliott Hughes                  vector<BitExtent>* dst_deflates,
28*07fb1d06SElliott Hughes                  vector<ByteExtent>* src_puffs,
29*07fb1d06SElliott Hughes                  vector<ByteExtent>* dst_puffs,
30*07fb1d06SElliott Hughes                  uint64_t* src_puff_size,
31*07fb1d06SElliott Hughes                  uint64_t* dst_puff_size);
32*07fb1d06SElliott Hughes }  // namespace puffin
33*07fb1d06SElliott Hughes 
34*07fb1d06SElliott Hughes namespace {
35*07fb1d06SElliott Hughes template <typename T>
TestExtentsArrayForFuzzer(const vector<T> & extents)36*07fb1d06SElliott Hughes bool TestExtentsArrayForFuzzer(const vector<T>& extents) {
37*07fb1d06SElliott Hughes   const size_t kMaxArraySize = 100;
38*07fb1d06SElliott Hughes   if (extents.size() > kMaxArraySize) {
39*07fb1d06SElliott Hughes     return false;
40*07fb1d06SElliott Hughes   }
41*07fb1d06SElliott Hughes 
42*07fb1d06SElliott Hughes   const size_t kMaxBufferSize = 1024;  // 1Kb
43*07fb1d06SElliott Hughes   for (const auto& ext : extents) {
44*07fb1d06SElliott Hughes     if (ext.length > kMaxBufferSize) {
45*07fb1d06SElliott Hughes       return false;
46*07fb1d06SElliott Hughes     }
47*07fb1d06SElliott Hughes   }
48*07fb1d06SElliott Hughes   return true;
49*07fb1d06SElliott Hughes }
50*07fb1d06SElliott Hughes 
FuzzPuffPatch(const uint8_t * data,size_t size)51*07fb1d06SElliott Hughes void FuzzPuffPatch(const uint8_t* data, size_t size) {
52*07fb1d06SElliott Hughes   // First decode the header and make sure the deflate and puff buffer sizes do
53*07fb1d06SElliott Hughes   // not excede some limits. This is to prevent the fuzzer complain with
54*07fb1d06SElliott Hughes   // out-of-memory errors when the fuzz data is in such a way that causes a huge
55*07fb1d06SElliott Hughes   // random size memory be allocated.
56*07fb1d06SElliott Hughes 
57*07fb1d06SElliott Hughes   size_t bsdiff_patch_offset;
58*07fb1d06SElliott Hughes   size_t bsdiff_patch_size = 0;
59*07fb1d06SElliott Hughes   vector<BitExtent> src_deflates, dst_deflates;
60*07fb1d06SElliott Hughes   vector<ByteExtent> src_puffs, dst_puffs;
61*07fb1d06SElliott Hughes   uint64_t src_puff_size, dst_puff_size;
62*07fb1d06SElliott Hughes   if (DecodePatch(data, size, &bsdiff_patch_offset, &bsdiff_patch_size,
63*07fb1d06SElliott Hughes                   &src_deflates, &dst_deflates, &src_puffs, &dst_puffs,
64*07fb1d06SElliott Hughes                   &src_puff_size, &dst_puff_size) &&
65*07fb1d06SElliott Hughes       TestExtentsArrayForFuzzer(src_deflates) &&
66*07fb1d06SElliott Hughes       TestExtentsArrayForFuzzer(dst_deflates) &&
67*07fb1d06SElliott Hughes       TestExtentsArrayForFuzzer(src_puffs) &&
68*07fb1d06SElliott Hughes       TestExtentsArrayForFuzzer(dst_puffs)) {
69*07fb1d06SElliott Hughes     const size_t kBufferSize = 1000;
70*07fb1d06SElliott Hughes     if ((!src_deflates.empty() &&
71*07fb1d06SElliott Hughes          kBufferSize <
72*07fb1d06SElliott Hughes              src_deflates.back().offset + src_deflates.back().length) ||
73*07fb1d06SElliott Hughes         (!dst_deflates.empty() &&
74*07fb1d06SElliott Hughes          kBufferSize <
75*07fb1d06SElliott Hughes              dst_deflates.back().offset + dst_deflates.back().length)) {
76*07fb1d06SElliott Hughes       return;
77*07fb1d06SElliott Hughes     }
78*07fb1d06SElliott Hughes 
79*07fb1d06SElliott Hughes     Buffer src_buffer(kBufferSize);
80*07fb1d06SElliott Hughes     Buffer dst_buffer(kBufferSize);
81*07fb1d06SElliott Hughes     auto src = MemoryStream::CreateForRead(src_buffer);
82*07fb1d06SElliott Hughes     auto dst = MemoryStream::CreateForWrite(&dst_buffer);
83*07fb1d06SElliott Hughes     puffin::PuffPatch(std::move(src), std::move(dst), data, size, kBufferSize);
84*07fb1d06SElliott Hughes   }
85*07fb1d06SElliott Hughes }
86*07fb1d06SElliott Hughes 
87*07fb1d06SElliott Hughes class Environment {
88*07fb1d06SElliott Hughes  public:
Environment()89*07fb1d06SElliott Hughes   Environment() {
90*07fb1d06SElliott Hughes     // To turn off the logging.
91*07fb1d06SElliott Hughes     logging::SetMinLogLevel(logging::LOGGING_FATAL);
92*07fb1d06SElliott Hughes 
93*07fb1d06SElliott Hughes     // To turn off logging for bsdiff library.
94*07fb1d06SElliott Hughes     std::cerr.setstate(std::ios_base::failbit);
95*07fb1d06SElliott Hughes   }
96*07fb1d06SElliott Hughes };
97*07fb1d06SElliott Hughes 
98*07fb1d06SElliott Hughes }  // namespace
99*07fb1d06SElliott Hughes 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)100*07fb1d06SElliott Hughes extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
101*07fb1d06SElliott Hughes   static Environment env;
102*07fb1d06SElliott Hughes 
103*07fb1d06SElliott Hughes   FuzzPuffPatch(data, size);
104*07fb1d06SElliott Hughes   return 0;
105*07fb1d06SElliott Hughes }
106