Introspector report: link
A previous blog post by Project Zero
details a vulnerability exploited by NSO to hack iOS users in xpdf. This vulnerability is in the JBIG2Stream::readTextRegionSeg
function in xpdf.
xpdf is integrated into OSS-Fuzz, but the existing fuzzing did not cover JBIG2Stream::readTextRegionSeg
.
As shown in Figure 1, in the "Optimal target analysis" section of Fuzz Introspector report for xpdf, the
second function suggested is JBIG2Stream::reset()
.
The main function called by JBIG2Stream::reset()
is JBIG2Stream::readSegments
.
readSegments
actually calls the vulnerable function readTextRegionSeg
.
So the call tree for this fuzz target would be:
JBIG2Stream::reset()
readSegments()
readTextRegionSeg() // vulnerable function.
Figure 1: List of suggested targets for xpdf
Based on this suggestion, we wrote a new fuzzer to target JBIG2Stream::reset()
. As visible in the latest coverage reports, OSS-Fuzz is now exercising the vulnerable
function JBIG2stream::readTextRegionSeg()
.
This proves the usefulness of Fuzz Introspector in identifying and suggesting interesting new fuzz targets.
Introspector report: link
Fuzz Introspector provides a call-tree overview for each fuzz target (Figure 2). This overview shows the fuzz target coverage by color coding the call instructions. The red shaded areas are where the target fails to cover. As Figure 2 shows, jsonnet fuzz target fails to cover a big chunk of code.
Figure 2: Fuzz target coverage for jsonnet before adding new targets
Looking at the Fuzz blocker table (Figure 3), the top blocker is in the jsonnet_evaluate_snippet_aux()
funcion,
where a switch statement branches on an argument of type EvalKind.
Figure 3: Top fuzz blockers for jsonnet
Looking into the fuzz target call tree reveals that the argument of type EvalKind
is always set to a static value (REGULAR
in this case).
It means that the existing fuzz target has no way to explore other cases of the switch statement.
To improve the fuzzing coverage, one could quickly conclude that we need fuzz targets to
make a call to jsonnet_evaluate_snippet_aux()
with other possible values of Evalkind
. To this end we wrote two new fuzz targets to do
this via the provided interfaces
jsonnet_evaluate_snippet_multi()
and jsonnet_evaluate_snippet_stream()
.
This way we were able to unblock the jsonnet fuzzer and increase the call tree coverage dramatically (Figure 4).
Figure 4: Fuzz target coverage for jsonnet after adding new targets