Skip to content

Commit d38f6a5

Browse files
authored
Add in-tree fuzz target proof-of-concept (#158)
Add in-tree fuzz target proof-of-concept for oss-fuzz
1 parent 3a1fea9 commit d38f6a5

3 files changed

Lines changed: 141 additions & 2 deletions

File tree

.gitattributes

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33

44
# Explicitly declare text file types for this repo
55
*.c text
6-
*.pp text
6+
*.cpp text
77
*.h text
88
*.md text
99
Jenkinsfile text
1010

11-
# VS solution always use Windows line endings
11+
# VS solutions always use Windows line endings
1212
*.sln text eol=crlf
1313
*.vcxproj text eol=crlf
1414

15+
# Bash scripts always use *nux line endings
16+
*.sh text eol=lf
17+
1518
# Denote all files that are truly binary and should not be modified.
1619
*.png binary
1720
*.hdr binary

Source/Fuzzers/build.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash -eu
2+
3+
# SPDX-License-Identifier: Apache-2.0
4+
# ----------------------------------------------------------------------------
5+
# Copyright 2020 Arm Limited
6+
# Copyright 2020 Google Inc.
7+
#
8+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
9+
# use this file except in compliance with the License. You may obtain a copy
10+
# of the License at:
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing, software
15+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17+
# License for the specific language governing permissions and limitations
18+
# under the License.
19+
# ----------------------------------------------------------------------------
20+
21+
# Build the core project
22+
make -j$(nproc) BUILD=debug VEC=sse2
23+
24+
# Package up a library for fuzzers to link against
25+
ar -qc libastcenc.a *.o
26+
27+
# Build project local fuzzers
28+
for fuzzer in $SRC/astc-encoder/Source/Fuzzers/fuzz_*.cpp; do
29+
$CXX $CXXFLAGS \
30+
-DASTCENC_SSE=0 -DASTCENC_AVX=0 -DASTCENC_POPCNT=0 -DASTCENC_VECALIGN=16 \
31+
-I. -std=c++14 $fuzzer $LIB_FUZZING_ENGINE $SRC/astc-encoder/Source/libastcenc.a \
32+
-o $OUT/$(basename -s .cpp $fuzzer)
33+
done
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// ----------------------------------------------------------------------------
3+
// Copyright 2020 Arm Limited
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
6+
// use this file except in compliance with the License. You may obtain a copy
7+
// of the License at:
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
// License for the specific language governing permissions and limitations
15+
// under the License.
16+
// ----------------------------------------------------------------------------
17+
18+
/**
19+
* @brief Fuzz target for physical_to_symbolic().
20+
*
21+
* This function is the first entrypoint for decompressing a 16 byte block of
22+
* input ASTC data from disk. The 16 bytes can contain arbitrary data; they
23+
* are read from an external source, but the block size used must be a valid
24+
* ASTC block footprint.
25+
*/
26+
27+
28+
#include "astcenc_internal.h"
29+
30+
#include <fuzzer/FuzzedDataProvider.h>
31+
#include <array>
32+
#include <vector>
33+
34+
struct BlockSizes {
35+
int x;
36+
int y;
37+
int z;
38+
};
39+
40+
std::array<BlockSizes, 3> testSz {{
41+
{ 4, 4, 1}, // Highest bitrate
42+
{12, 12, 1}, // Largest 2D block
43+
{6, 6, 6} // Largest 3D block
44+
}};
45+
46+
std::array<block_size_descriptor, 3> testBSD;
47+
48+
/**
49+
* @brief Utility function to create all of the block size descriptors needed.
50+
*
51+
* This is triggered once via a static initializer.
52+
*
53+
* Triggering once is important so that we only create a single BSD per block
54+
* size we need, rather than one per fuzzer iteration (it's expensive). This
55+
* improves fuzzer throughput by ~ 1000x!
56+
*
57+
* Triggering via a static initializer, rather than a lazy init in the fuzzer
58+
* function, is important because is means that the BSD is allocated before
59+
* fuzzing starts. This means that leaksanitizer will ignore the fact that we
60+
* "leak" the dynamic allocations inside the BSD (we never call term()).
61+
*/
62+
bool bsd_initializer()
63+
{
64+
for (int i = 0; i < testSz.size(); i++)
65+
{
66+
init_block_size_descriptor(
67+
testSz[i].x,
68+
testSz[i].y,
69+
testSz[i].z,
70+
&(testBSD[i]));
71+
}
72+
73+
return true;
74+
}
75+
76+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
77+
{
78+
// Preinitialize the block size descriptors we need
79+
static bool init = bsd_initializer();
80+
81+
// Must have 4 (select block size) and 16 (payload) bytes
82+
if (size < 4 + 16)
83+
{
84+
return 0;
85+
}
86+
87+
FuzzedDataProvider stream(data, size);
88+
89+
// Select a block size to test
90+
int i = stream.ConsumeIntegralInRange<int>(0, testSz.size() - 1);
91+
block_size_descriptor* bsd = &(testBSD[i]);
92+
93+
// Populate the physical block
94+
physical_compressed_block pcb;
95+
std::vector<uint8_t> buffer = stream.ConsumeBytes<uint8_t>(16);
96+
std::memcpy(&pcb, buffer.data(), 16);
97+
98+
// Call the function under test
99+
symbolic_compressed_block scb;
100+
physical_to_symbolic(bsd, pcb, &scb);
101+
102+
return 0;
103+
}

0 commit comments

Comments
 (0)