Skip to content
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

Add fuzz boilerplate to druntime #2501

Closed
JohanEngelen opened this Issue Jan 13, 2018 · 6 comments

Comments

Projects
None yet
3 participants
@JohanEngelen
Copy link
Member

commented Jan 13, 2018

Currently a complete simple fuzz target looks like this:

bool FuzzMe(const(ubyte[]) data)
{
    return (data.length >= 3) &&
           data[0] == 'F' && data[1] == 'U' && data[2] == 'Z' &&
           data[3] == 'Z'; // <-- access possibly out of bounds
}

int LLVMFuzzerTestOneInput(const(ubyte[]) data)
{
    FuzzMe(data);
    return 0;
}

// Boilerplate that you should not have to write in the future:
extern (C) void _d_print_throwable(Throwable t);
extern (C) int LLVMFuzzerTestOneInput(const(ubyte*) data, size_t size) {
    // D runtime must be initialized, but only once.
    static bool init = false;
    if (!init) {
        import core.runtime : rt_init;
        rt_init();
        init = true;
    }
    try {
        return LLVMFuzzerTestOneInput(data[0 .. size]);
    }
    catch (Throwable t) {
        _d_print_throwable(t);
        import ldc.intrinsics : llvm_trap;
        llvm_trap();
    }
    assert(0);
}

I think we should add the part below // Boilerplate... to druntime. It would make things easier for the user to do fuzzing. Because of linker deadstripping, normal executables would not contain the fuzz boilerplate.

@dnadlinger

This comment has been minimized.

Copy link
Member

commented Jan 13, 2018

Not sure exporting the function by default is a good idea – what if druntime as a shared library is linked into some other library that is being fuzzed? Could always be a mixin template (perhaps with the extern(D) actual function as alias parameter), though.

@JohanEngelen

This comment has been minimized.

Copy link
Member Author

commented Jan 14, 2018

what if druntime as a shared library is linked into some other library that is being fuzzed?

You mean in a mixed language situation? You'll have to explain your concern a bit more.

Would it be fixed with marking this @weak? (doesn't work on all platforms I think)
A safer solution would be putting this in its own small library that is also linked-in when passing -fsanitize=fuzzer. Simplest would be with a mixin, indeed.

@dnadlinger

This comment has been minimized.

Copy link
Member

commented Jan 14, 2018

You mean in a mixed language situation?

For example in a mixed-language situation, yes, where a C program that is fuzzed uses a D library internally. Conceptually, LLVMFuzzerTestOneInput should only ever be emitted into what would be the main executable. Putting it into all of druntime is only asking for trouble, as

Because of linker deadstripping, normal executables would not contain the fuzz boilerplate.

is not true for shared libraries. Perhaps this could be worked around by using weak symbols, but why bother in the first place?

Users would already have to know about the magic int LLVMFuzzerTestOneInput(const(ubyte[]) data) signature, and what to do with it (which would have to be extern(C) as well, by the way, to avoid mangling). It doesn't seem any less straightforward to do something like this

import ldc.libfuzzer;

int fuzzMain(in ubyte[] data) { … }

mixin LibFuzzerEntryPoint!fuzzMain;

In fact, I'd prefer the explicit form as documentation is readily provided as a DDoc comment for the template.

@JohanEngelen

This comment has been minimized.

Copy link
Member Author

commented Jan 14, 2018

Yep I like the mixin idea too. So we'll put it in druntime/src/ldc/libfuzzer.di?

@JohanEngelen

This comment has been minimized.

Copy link
Member Author

commented Jan 15, 2018

JohanEngelen added a commit to JohanEngelen/ldc that referenced this issue Jan 15, 2018

JohanEngelen added a commit to JohanEngelen/ldc that referenced this issue Mar 6, 2018

JohanEngelen added a commit to JohanEngelen/ldc that referenced this issue Mar 6, 2018

JohanEngelen added a commit to JohanEngelen/ldc that referenced this issue Mar 7, 2018

JohanEngelen added a commit that referenced this issue Mar 7, 2018

@kinke

This comment has been minimized.

Copy link
Member

commented Apr 17, 2018

Added in #2510.

@kinke kinke closed this Apr 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.