This is an archive of the discontinued LLVM Phabricator instance.

[libc] Add basic fuzz target for the printf parser
ClosedPublic

Authored by michaelrj on Feb 10 2023, 3:03 PM.

Details

Summary

The goal is to fuzz the entirety of printf, but the plan is to do it in
pieces for simplicity. This test fuzzes just the parser, while later
tests will fuzz the converters. This also adds a mock version of the
arg_list class.

Diff Detail

Event Timeline

michaelrj created this revision.Feb 10 2023, 3:03 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptFeb 10 2023, 3:03 PM
michaelrj requested review of this revision.Feb 10 2023, 3:03 PM

I think the main fuzzer file is missing.

include main fuzzer file that I forgot

sivachandra added inline comments.Feb 13 2023, 12:53 PM
libc/fuzzing/stdio/mock_arg_list.h
18 ↗(On Diff #497033)

It's not clear to me as to how this MockArgList is helping the fuzzer. Can please add comments explaining this?

33 ↗(On Diff #497033)

This is not a virtual function. So, who/what is supposed to make use of this method?

libc/fuzzing/stdio/printf_parser_fuzz.cpp
21

Please add a detailed comment about the fuzzing strategy that is being employed here.

michaelrj updated this revision to Diff 497471.Feb 14 2023, 4:10 PM
michaelrj marked 3 inline comments as done.

Add comment about how the fuzzer is intended to work.
Redo mock arg list so that it actually works.

sivachandra added inline comments.Feb 15 2023, 3:32 PM
libc/fuzzing/stdio/printf_parser_fuzz.cpp
41

Other than passing it to the Parser constructor, I don't see mock_arg_list being used anywhere. What am I missing?

libc/src/__support/arg_list.h
37 ↗(On Diff #497471)

I am assuming that the use of this class is to get the number of args read out from the list. So, my suggestion is as follows. I would really not add a comment referencing printf or fuzz testing here. Also, you can add a mock class here unconditionally. The condition should be at the usage-site, which is the Parser class and the fuzzer, something like:

#ifdef LIBC_COPT_PRINTF_PARSER_WITH_MOCK_ARGS // Or a better name
using ArgProvider = MockArgList;
#else
using ArgProvider = ArgList;
#endif

Update Parser to take ArgProvider.

66 ↗(On Diff #497471)

Since it is a mock, you can just return T(); and avoid implicit type casts and the void* specialization. Also, instead of overloading next_var to read the args fetched, you can add a new method, say:

size_t read_count() const { return arg_counter; }
michaelrj updated this revision to Diff 497838.Feb 15 2023, 4:09 PM
michaelrj marked 3 inline comments as done.

move ArgList changes to https://reviews.llvm.org/D144145

libc/fuzzing/stdio/printf_parser_fuzz.cpp
41

You're not missing anything. The mock arg list is just there so that the program doesn't crash when the parser starts requesting arguments. It needs to respond with some value, but what that value actually is doesn't matter right now. Later I'll hopefully add a separate fuzz test that does check that the arguments were read in the right order, but this works for now.

libc/src/__support/arg_list.h
37 ↗(On Diff #497471)

This seemed to be getting larger than should be in this patch, so I've split the ArgList changes into this other patch: https://reviews.llvm.org/D144145

sivachandra accepted this revision.Feb 16 2023, 10:38 PM
This revision is now accepted and ready to land.Feb 16 2023, 10:38 PM
This revision was landed with ongoing or failed builds.Feb 17 2023, 11:18 AM
This revision was automatically updated to reflect the committed changes.