Libfuzzer target for on-disk parsing












0















I'm currently integrating libFuzzer in a project which parses files on the hard drive. I have some prior experience with AFL, where a command line like this one was used:



afl-fuzz -m500 -i input/ -o output/ -t100 -- program_to_fuzz @@


...where @@ was a path to the generated input.
Looking at libFuzzer however, I see that the fuzz targets look like this:



extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}


I understand that the input isn't provided in the form of a file, but as a buffer in-memory instead. The problem is that the program I'm trying to fuzz works with files and obtains its data through fread() calls. At no point in time is the whole input supposed to be loaded in memory (where, in the general case, it might not even fit); so there's not much I can do with a const uint8_t*.



Writing the buffer back to the hard drive to get back a file seems extremely inefficient. Is there a way around this?










share|improve this question


















  • 1





    Maybe a file on a tmpfs would help (in case of Linux -- it is a RAM disk, so no writing to underlying disk, but still some fs syscall overhead...). Next, you could mmap this file and then memcpy data into it, but not sure how to handle the file size properly.

    – Anatoly Trosinenko
    Nov 28 '18 at 6:57
















0















I'm currently integrating libFuzzer in a project which parses files on the hard drive. I have some prior experience with AFL, where a command line like this one was used:



afl-fuzz -m500 -i input/ -o output/ -t100 -- program_to_fuzz @@


...where @@ was a path to the generated input.
Looking at libFuzzer however, I see that the fuzz targets look like this:



extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}


I understand that the input isn't provided in the form of a file, but as a buffer in-memory instead. The problem is that the program I'm trying to fuzz works with files and obtains its data through fread() calls. At no point in time is the whole input supposed to be loaded in memory (where, in the general case, it might not even fit); so there's not much I can do with a const uint8_t*.



Writing the buffer back to the hard drive to get back a file seems extremely inefficient. Is there a way around this?










share|improve this question


















  • 1





    Maybe a file on a tmpfs would help (in case of Linux -- it is a RAM disk, so no writing to underlying disk, but still some fs syscall overhead...). Next, you could mmap this file and then memcpy data into it, but not sure how to handle the file size properly.

    – Anatoly Trosinenko
    Nov 28 '18 at 6:57














0












0








0








I'm currently integrating libFuzzer in a project which parses files on the hard drive. I have some prior experience with AFL, where a command line like this one was used:



afl-fuzz -m500 -i input/ -o output/ -t100 -- program_to_fuzz @@


...where @@ was a path to the generated input.
Looking at libFuzzer however, I see that the fuzz targets look like this:



extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}


I understand that the input isn't provided in the form of a file, but as a buffer in-memory instead. The problem is that the program I'm trying to fuzz works with files and obtains its data through fread() calls. At no point in time is the whole input supposed to be loaded in memory (where, in the general case, it might not even fit); so there's not much I can do with a const uint8_t*.



Writing the buffer back to the hard drive to get back a file seems extremely inefficient. Is there a way around this?










share|improve this question














I'm currently integrating libFuzzer in a project which parses files on the hard drive. I have some prior experience with AFL, where a command line like this one was used:



afl-fuzz -m500 -i input/ -o output/ -t100 -- program_to_fuzz @@


...where @@ was a path to the generated input.
Looking at libFuzzer however, I see that the fuzz targets look like this:



extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}


I understand that the input isn't provided in the form of a file, but as a buffer in-memory instead. The problem is that the program I'm trying to fuzz works with files and obtains its data through fread() calls. At no point in time is the whole input supposed to be loaded in memory (where, in the general case, it might not even fit); so there's not much I can do with a const uint8_t*.



Writing the buffer back to the hard drive to get back a file seems extremely inefficient. Is there a way around this?







fuzzing libfuzzer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 '18 at 16:15









executifsexecutifs

628619




628619








  • 1





    Maybe a file on a tmpfs would help (in case of Linux -- it is a RAM disk, so no writing to underlying disk, but still some fs syscall overhead...). Next, you could mmap this file and then memcpy data into it, but not sure how to handle the file size properly.

    – Anatoly Trosinenko
    Nov 28 '18 at 6:57














  • 1





    Maybe a file on a tmpfs would help (in case of Linux -- it is a RAM disk, so no writing to underlying disk, but still some fs syscall overhead...). Next, you could mmap this file and then memcpy data into it, but not sure how to handle the file size properly.

    – Anatoly Trosinenko
    Nov 28 '18 at 6:57








1




1





Maybe a file on a tmpfs would help (in case of Linux -- it is a RAM disk, so no writing to underlying disk, but still some fs syscall overhead...). Next, you could mmap this file and then memcpy data into it, but not sure how to handle the file size properly.

– Anatoly Trosinenko
Nov 28 '18 at 6:57





Maybe a file on a tmpfs would help (in case of Linux -- it is a RAM disk, so no writing to underlying disk, but still some fs syscall overhead...). Next, you could mmap this file and then memcpy data into it, but not sure how to handle the file size properly.

– Anatoly Trosinenko
Nov 28 '18 at 6:57












2 Answers
2






active

oldest

votes


















0














You could use LD_PRELOAD and override fread.






share|improve this answer































    0














    You can do as in this example from google security team.
    The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:

    (from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )



    // Write the data provided in buf to a new temporary file. This function is  
    // meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
    // take file names (and not data) as input.
    //
    // Return the path of the newly created file or NULL on error. The caller should
    // eventually free the returned buffer (see delete_file).
    extern "C" char *buf_to_file(const uint8_t *buf, size_t size);


    Be sure to free the ressource with the delete_file function.






    share|improve this answer


























    • Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

      – amanb
      Jan 20 at 20:12











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53460028%2flibfuzzer-target-for-on-disk-parsing%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You could use LD_PRELOAD and override fread.






    share|improve this answer




























      0














      You could use LD_PRELOAD and override fread.






      share|improve this answer


























        0












        0








        0







        You could use LD_PRELOAD and override fread.






        share|improve this answer













        You could use LD_PRELOAD and override fread.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 4 '18 at 12:33









        KonradsKonrads

        1,30811632




        1,30811632

























            0














            You can do as in this example from google security team.
            The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:

            (from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )



            // Write the data provided in buf to a new temporary file. This function is  
            // meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
            // take file names (and not data) as input.
            //
            // Return the path of the newly created file or NULL on error. The caller should
            // eventually free the returned buffer (see delete_file).
            extern "C" char *buf_to_file(const uint8_t *buf, size_t size);


            Be sure to free the ressource with the delete_file function.






            share|improve this answer


























            • Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

              – amanb
              Jan 20 at 20:12
















            0














            You can do as in this example from google security team.
            The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:

            (from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )



            // Write the data provided in buf to a new temporary file. This function is  
            // meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
            // take file names (and not data) as input.
            //
            // Return the path of the newly created file or NULL on error. The caller should
            // eventually free the returned buffer (see delete_file).
            extern "C" char *buf_to_file(const uint8_t *buf, size_t size);


            Be sure to free the ressource with the delete_file function.






            share|improve this answer


























            • Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

              – amanb
              Jan 20 at 20:12














            0












            0








            0







            You can do as in this example from google security team.
            The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:

            (from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )



            // Write the data provided in buf to a new temporary file. This function is  
            // meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
            // take file names (and not data) as input.
            //
            // Return the path of the newly created file or NULL on error. The caller should
            // eventually free the returned buffer (see delete_file).
            extern "C" char *buf_to_file(const uint8_t *buf, size_t size);


            Be sure to free the ressource with the delete_file function.






            share|improve this answer















            You can do as in this example from google security team.
            The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:

            (from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )



            // Write the data provided in buf to a new temporary file. This function is  
            // meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
            // take file names (and not data) as input.
            //
            // Return the path of the newly created file or NULL on error. The caller should
            // eventually free the returned buffer (see delete_file).
            extern "C" char *buf_to_file(const uint8_t *buf, size_t size);


            Be sure to free the ressource with the delete_file function.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 21 at 0:03









            amanb

            1,448522




            1,448522










            answered Jan 20 at 17:46









            neuracrneuracr

            11




            11













            • Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

              – amanb
              Jan 20 at 20:12



















            • Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

              – amanb
              Jan 20 at 20:12

















            Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

            – amanb
            Jan 20 at 20:12





            Welcome to StackOverFlow! While this answer maybe helpful, links to third-party websites can become invalid over time.

            – amanb
            Jan 20 at 20:12


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53460028%2flibfuzzer-target-for-on-disk-parsing%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen