Shaleen Jain

· 1 min read

Fuzzing libVLC - Improvements

<p>I have been making some few specific improvement to demux fuzz target and also working on the decoder target side by side which isn’t done yet.</p> <p>Some general improvements that I have made for all fuzz targets is abstracting away and initializing the parent <code>libvlc_instance_t</code> object in <code>LLVMFuzzerInitialize</code> which obviously has some performance improvements as it isn’t created and destroyed on every run of the <code>LLVMFuzzerTestOneInput</code>.</p> <span id="continue-reading"></span><h4 id="fuzzer-common-c"><a class="zola-anchor" href="#fuzzer-common-c" aria-label="Anchor link for: fuzzer-common-c">🔗</a> fuzzer_common.c</h4> <pre class="giallo" style="color: #657B83; background-color: #FDF6E3;" ><code data-lang="c"><span class="giallo-l"><span style="color: #859900;">#include</span><span style="color: #2AA198;"> &lt;assert.h&gt;</span></span> <span class="giallo-l"></span> <span class="giallo-l"><span style="color: #859900;">#include</span><span style="color: #2AA198;"> &quot;fuzzer.h&quot;</span></span> <span class="giallo-l"><span style="color: #586E75;font-weight: bold;">static</span><span style="color: #859900;"> libvlc_instance_t *</span><span>p_libvlc;</span></span> <span class="giallo-l"></span> <span class="giallo-l"><span style="color: #586E75;font-weight: bold;">extern int</span><span style="color: #268BD2;"> LLVMFuzzerInitialize</span><span>(</span><span style="color: #586E75;font-weight: bold;">int</span><span style="color: #859900;"> *</span><span>argc,</span><span style="color: #586E75;font-weight: bold;"> char</span><span style="color: #859900;"> ***</span><span>argv)</span></span> <span class="giallo-l"><span>{</span></span> <span class="giallo-l"><span style="color: #268BD2;"> setenv</span><span>(</span><span style="color: #2AA198;">&quot;VLC_PLUGIN_PATH&quot;</span><span>,</span><span style="color: #2AA198;"> &quot;../../modules&quot;</span><span>,</span><span style="color: #D33682;"> 1</span><span>);</span></span> <span class="giallo-l"><span> p_libvlc </span><span style="color: #859900;">=</span><span style="color: #268BD2;"> libvlc_new</span><span>(</span><span style="color: #D33682;">0</span><span>,</span><span style="color: #B58900;"> NULL</span><span>);</span></span> <span class="giallo-l"><span style="color: #268BD2;"> assert</span><span>(p_libvlc </span><span style="color: #859900;">!=</span><span style="color: #B58900;"> NULL</span><span>);</span></span> <span class="giallo-l"><span style="color: #859900;"> return</span><span style="color: #D33682;"> 0</span><span>;</span></span> <span class="giallo-l"><span>}</span></span> <span class="giallo-l"></span> <span class="giallo-l"><span style="color: #586E75;font-weight: bold;">extern int</span><span style="color: #268BD2;"> LLVMFuzzerTestOneInput</span><span>(</span><span style="color: #586E75;font-weight: bold;">const uint8_t</span><span style="color: #859900;"> *</span><span>buf,</span><span style="color: #586E75;font-weight: bold;"> size_t</span><span> len) {</span></span> <span class="giallo-l"><span style="color: #859900;"> return</span><span style="color: #268BD2;"> FuzzerTestOneInput</span><span>(buf, len, p_libvlc);</span></span> <span class="giallo-l"><span>}</span></span> <span class="giallo-l"></span> <span class="giallo-l"><span style="color: #586E75;font-weight: bold;">void</span><span style="color: #268BD2;"> FuzzerCleanup</span><span>(</span><span style="color: #586E75;font-weight: bold;">void</span><span>)</span></span> <span class="giallo-l"><span>{</span></span> <span class="giallo-l"><span style="color: #268BD2;"> libvlc_release</span><span>(p_libvlc);</span></span> <span class="giallo-l"><span>}</span></span></code></pre> <p>Another benefit of this abstraction is that our fuzz targets are now completely agnostic to the fuzzing engine we use which has been <a rel="noopener nofollow noreferrer external" target="_blank" href="http://llvm.org/docs/LibFuzzer.html#startup-initialization">libFuzzer</a> until now. We can now use the exact same target with <a rel="noopener nofollow noreferrer external" target="_blank" href="http://lcamtuf.coredump.cx/afl/">AFL</a> by writing a driver, since AFL expects a main function, here is an <a rel="noopener nofollow noreferrer external" target="_blank" href="https://github.com/llvm-mirror/compiler-rt/blob/58d43607862096aeb32d72173911c9df244a30f1/lib/fuzzer/afl/afl_driver.cpp">example</a> driver.</p> <h3 id="dictionaries"><a class="zola-anchor" href="#dictionaries" aria-label="Anchor link for: dictionaries">🔗</a> Dictionaries</h3> <p>At this point the demux fuzzer had found a few more bugs but it had kind of reached a saturation point in terms of the line coverage it had and it just wasn’t increasing any more significantly with new sample input.</p> <p>So I decided instead of adding sample files of every possible video file format with different types of chunks and atoms that VLC supports, to create a keywords dictionary of magic values of the various file formats and feed it to the demux target. Libfuzzer has in-built support for dictionary files and can much more efficiently create structured inputs with it.</p> <p>libFuzzer and AFL have the same syntax of dictionary files and the AFL project even has some excellent dictionaries for <a rel="noopener nofollow noreferrer external" target="_blank" href="https://github.com/mcarpenter/afl/blob/master/dictionaries/jpeg.dict">JPEG</a>, <a rel="noopener nofollow noreferrer external" target="_blank" href="https://github.com/mcarpenter/afl/blob/master/dictionaries/png.dict">PNG</a> and <a rel="noopener nofollow noreferrer external" target="_blank" href="https://github.com/mcarpenter/afl/blob/master/dictionaries/gif.dict">GIF</a> file formats. And you guessed it VLC can actually “Play” those files as well since <code>ffmpeg</code> provides their codec as well.</p> <p>I’m still working on the dictionary and I’ll maybe post it once it’s completed or if it’s ever merged into the VLC codebase.</p>
Liked this article? Share this with others

Got any questions or comments? Drop me a message on Twitter @shalzzj

Sign up for my newsletter to be the first to know about a new post