New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fuzz target for `parseXML` with 2 crashing testcases #8

Closed
JohanEngelen opened this Issue May 4, 2018 · 7 comments

Comments

2 participants
@JohanEngelen

JohanEngelen commented May 4, 2018

The (libFuzzer) fuzz target I used is:

import ldc.libfuzzer;
mixin DefineTestOneInput!fuzzMe;

int fuzzMe(in ubyte[] data) {
    import dxml.parser;
    try {
        int sum;
        auto range = parseXML(cast(char[])data);
        foreach (elem; range) {
            // Do something unpredictable to actually test the parser
            sum += cast(int) elem.type;
        }
        return sum > 1;
    }
    catch (XMLParsingException) {
        return 0;
    }
}

Compiled with LDC 1.9: bin/ldc2 -g -i -fsanitize=fuzzer fuzz_dxml.d

  1. Error: core.exception.RangeError@std/utf.d(3324): Range violation
    testcase: [0x3c,0xff,0x3e,0x3e,0x3a,0x3c,0x2f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x31,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd8,0xd8,0xd8,0xd8,0xd8,0xff,0xff,0xff]

  2. Error: core.exception.AssertError@dxml/parser.d(5466): Assertion failure
    testcase: [0x3c,0x3f]

(perhaps add this fuzz target, and others, to a dedicated /fuzz/ folder, see e.g. https://github.com/openssl/openssl/tree/master/fuzz)

@jmdavis jmdavis added the 0.3.2 label May 4, 2018

@jmdavis

This comment has been minimized.

Owner

jmdavis commented May 4, 2018

This will be released in 0.3.2.

@jmdavis jmdavis closed this May 4, 2018

@JohanEngelen

This comment has been minimized.

JohanEngelen commented May 4, 2018

@jmdavis [0x3c,0x3f] still crashes!

@jmdavis

This comment has been minimized.

Owner

jmdavis commented May 5, 2018

@jmdavis [0x3c,0x3f] still crashes!

Drat. I read through the issue too quickly and missed that there were two failing test cases. I'll fix it during the hackathon then.

@jmdavis jmdavis reopened this May 5, 2018

jmdavis added a commit that referenced this issue May 5, 2018

jmdavis added a commit that referenced this issue May 5, 2018

@jmdavis

This comment has been minimized.

Owner

jmdavis commented May 5, 2018

Okay. That second case should also be fixed now.

@jmdavis jmdavis closed this May 5, 2018

@JohanEngelen

This comment has been minimized.

JohanEngelen commented May 5, 2018

That second case should also be fixed now.

Starting the fuzzer again! ;-)

@JohanEngelen

This comment has been minimized.

JohanEngelen commented May 5, 2018

New crash:
[0x3c,0x4d,0x3e,0x9,0x3b,0x3c,0x2f]

@JohanEngelen

This comment has been minimized.

JohanEngelen commented May 5, 2018

Fuzz target that should work with 1.8.0

// RUN: ~/ldc/ldc2-1.8.0-osx-x86_64/bin/ldc2 -g -fsanitize=fuzzer fuzz_dxml.d dxml/*.d

import std.typecons : Flag, Yes;


mixin template DefineTestOneInput(alias FuzzTarget, Flag!"initializeDRuntime" initializeDRuntime = Yes.initializeDRuntime)
    if (is(typeof(&FuzzTarget) == int function(in ubyte[])))
{
    static if (initializeDRuntime)
    {
        // Do druntime initialization and de-initialization through module ctor/dtor.
        // Choose a low priority = 10, to hopefully init before (de-init after) standard D module ctors (dtors).
        __gshared static bool runtimeInitialized = false;
        pragma(crt_constructor, 10)
        void initDRuntime()
        {
            import core.runtime : rt_init;
            rt_init();
            runtimeInitialized = true;
        }

        pragma(crt_destructor, 10)
        void terminateDRuntime()
        {
            import core.runtime : rt_term;
            if (runtimeInitialized)
                runtimeInitialized = !rt_term();
        }
    }

    // libFuzzer's user entry point
    pragma(mangle, "LLVMFuzzerTestOneInput") // Work around https://issues.dlang.org/show_bug.cgi?id=12575
    extern (C) int LLVMFuzzerTestOneInput(const(ubyte*) data, size_t size)
    {
        try
        {
            // Call the user's function
            return FuzzTarget(data[0 .. size]);
        }
        catch (Throwable t)
        {
            _d_print_throwable(t);
        }
        // We only reach here when an exception was caught.
        assert(0);
    }

    pragma(mangle, "_d_print_throwable") // Work around https://issues.dlang.org/show_bug.cgi?id=12575
    extern (C) void _d_print_throwable(Throwable t);
}

mixin DefineTestOneInput!fuzzMe;

int fuzzMe(in ubyte[] data)
{
    import dxml.parser;
    try
    {
        int sum;
        auto range = parseXML(cast(char[])data);
        foreach (elem; range) {
            // Do something unpredictable to actually test the parser
            sum += cast(int) elem.type;
        }
        return sum > 1;
    }
    catch (XMLParsingException)
    {
        return 0;
    }
}

jmdavis added a commit that referenced this issue May 8, 2018

jmdavis added a commit that referenced this issue May 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment