is there a fuzzer for libc?
Konstantin Serebryany
konstantin.s.serebryany@gmail.com
Thu Mar 19 18:25:00 GMT 2015
On Thu, Mar 19, 2015 at 10:38 AM, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
>
>
> On 19/03/15 16:38, Konstantin Serebryany wrote:
>> [reviving an old thread]
>> I had some success fuzzing regcomp/fnmatch/wordexp, see updates at
>> https://sourceware.org/glibc/wiki/FuzzingLibc
>>
>> Is anyone interested to help me fuzz some other parts of glibc the same way?
>>
>
> i'm interested in fuzzing standard interfaces
>
> i used regfuzz last year when i cleaned up the musl
> regex parsing code a bit but that was not easy to
> integrate into a standard testing framework
regfuzz is nice, but it's approach is typically less efficient for
this kind of targets than coverage-guided fuzzing.
At least this is what I've seen with glibc's regcomp/regexec: after
fuzzing regcomp with regfuzz for a few days
the coverage-guided fuzzer found 3 more bugs in just a few minutes.
> if you are planning to develop tools that work
> on the standard api (instead of making assuptions
> about glibc internals) then i'm willing to help
This is what I have for fnmatch:
extern "C" void TestOneInput(const unsigned char *Data, size_t Size) {
if (Size < 3) return;
unsigned char flags = Data[0];
size_t PatternSize = Data[1];
if (PatternSize > Size - 2)
PatternSize = Size - 2;
const char *p = (char*)Data + 2;
string Pat(p, p + PatternSize);
string Str((char*)Data, Size);
fnmatch(Pat.c_str(), Str.c_str() + 0, flags);
}
This is a very simple function that takes an array of bytes as a
parameter and does something interesting using one of the glibc's
public APIs.
Similar for wordexp:
if (Size < 2) return;
unsigned char flags = Data[0];
const char *p = (char*)Data + 1;
string Pat(p, Size - 1);
wordexp_t w;
if (!wordexp(Pat.c_str(), &w, flags | WRDE_NOCMD))
wordfree(&w);
and for regcomp:
if (Size < 3) return;
unsigned char flags = Data[0];
size_t PatternSize = Data[1];
if (PatternSize > Size - 2)
PatternSize = Size - 2;
const char *p = (char*)Data + 2;
string Pat(p, p + PatternSize);
string Str((char*)Data, Size);
regex_t r;
flags = 0; // Too many bugs.
if (!regcomp(&r, Pat.c_str(), flags)) {
// fprintf(stderr, "zzz\n");
regexec(&r, "foo.*bar", 0, 0, 0);
regexec(&r, Str.c_str(), 0, 0, 0);
regexec(&r, Pat.c_str(), 0, 0, 0);
}
regfree(&r);
> do you have specific plans?
Step1:
If you can implement a function
void TestOneInput(const unsigned char *Data, size_t Size);
that uses one of the glibc APIs in an interesting way as in the examples above
I can run it with the fuzzer on the instrumented glibc.
You can run yourself too, but the build process is a bit too hairy today.
The requirement for TestOneInput is that it runs reasonably fast (e.g. < 1ms)
and does not crash on malformed inputs (unless there is a bug).
For non-trivial kinds of input I may also need an initial set of
inputs (test corpus),
but for regcomp/fnmatch/wordexp and similar the fuzzer is capable of
generating the corpus from scratch.
Step2:
Finish Glibc+Clang (https://sourceware.org/glibc/wiki/GlibcMeetsClang)
and integrate the LLMV fuzzer
(http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/README.txt?view=markup)
or any similar coverage-guided fuzzer with the glibc testing process.
--kcc
>
>> --kcc
>>
>> On Thu, Jul 3, 2014 at 5:14 AM, Konstantin Serebryany
>> <konstantin.s.serebryany@gmail.com> wrote:
>>> created https://sourceware.org/glibc/wiki/FuzzingLibc, will add more
>>> content when/if I find such.
>>>
>>> On Fri, Jun 20, 2014 at 12:10 AM, Roland McGrath <roland@hack.frob.com> wrote:
>>>> It would be great if you could write something on the wiki pointing to
>>>> available fuzzers.
>>
>
More information about the Libc-alpha
mailing list