Message ID | 20200819061110.1320568-12-alxndr@bu.edu |
---|---|
State | New |
Headers | show |
Series | Add a General Virtual Device Fuzzer | expand |
On Wednesday, 2020-08-19 at 02:11:06 -04, Alexander Bulekov wrote: > This parses a yaml file containing general-fuzzer configs and builds a > separate oss-fuzz wrapper binary for each one, changing some > preprocessor macros for each configuration. To avoid dealing with > escaping and stringifying, convert each string into a byte-array > representation > > Signed-off-by: Alexander Bulekov <alxndr@bu.edu> > --- > scripts/oss-fuzz/build_general_fuzzers.py | 62 +++++++++++++++++++++++ > 1 file changed, 62 insertions(+) > create mode 100755 scripts/oss-fuzz/build_general_fuzzers.py > > diff --git a/scripts/oss-fuzz/build_general_fuzzers.py b/scripts/oss-fuzz/build_general_fuzzers.py > new file mode 100755 > index 0000000000..79f4664117 > --- /dev/null > +++ b/scripts/oss-fuzz/build_general_fuzzers.py > @@ -0,0 +1,62 @@ > +#!/usr/bin/env python3 > +# -*- coding: utf-8 -*- > + > +""" > +This script creates wrapper binaries that invoke the general-device-fuzzer with > +configurations specified in a yaml config file. > +""" > +import sys > +import os > +import yaml > +import tempfile > + > +CC = "" > +TEMPLATE = "" > + > + > +def usage(): > + print("Usage: CC=COMPILER {} CONFIG_PATH \ > +OUTPUT_PATH_PREFIX".format(sys.argv[0])) > + sys.exit(0) > + > + > +def str_to_c_byte_array(s): > + """ > + Convert strings to byte-arrays so we don't worry about formatting > + strings to play nicely with cc -DQEMU_FUZZARGS etc > + """ > + return ','.join('0x{:02x}'.format(ord(x)) for x in s) > + > + > +def compile_wrapper(cfg, path): > + os.system('$CC -DQEMU_FUZZ_ARGS="{}" -DQEMU_FUZZ_OBJECTS="{}" \ > + {} -o {}'.format( > + str_to_c_byte_array(cfg["args"].replace("\n", " ")), > + str_to_c_byte_array(cfg["objects"].replace("\n", " ")), > + TEMPLATE, path)) NIT: When using multiple placeholders, it is nicer to use names for them, so that reordering, or adding new ones is easier too. > + > + > +def main(): > + global CC > + global TEMPLATE > + > + if len(sys.argv) != 3: > + usage() > + > + cfg_path = sys.argv[1] > + out_path = sys.argv[2] > + > + CC = os.getenv("CC") Maybe provide a fall-back/default value if someone is calling it directly? > + TEMPLATE = os.path.join(os.path.dirname(__file__), "target.c") No harm to double-check this exists, but also I would suggest that the string "target.c" should be defined as a global value. > + > + with open(cfg_path, "r") as f: > + configs = yaml.load(f)["configs"] > + for cfg in configs: > + assert "name" in cfg > + assert "args" in cfg > + assert "objects" in cfg > + compile_wrapper(cfg, out_path + cfg["name"]) > + > + > +if __name__ == '__main__': > + main() > -- > 2.27.0 Thanks, Darren.
diff --git a/scripts/oss-fuzz/build_general_fuzzers.py b/scripts/oss-fuzz/build_general_fuzzers.py new file mode 100755 index 0000000000..79f4664117 --- /dev/null +++ b/scripts/oss-fuzz/build_general_fuzzers.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +This script creates wrapper binaries that invoke the general-device-fuzzer with +configurations specified in a yaml config file. +""" +import sys +import os +import yaml +import tempfile + +CC = "" +TEMPLATE = "" + + +def usage(): + print("Usage: CC=COMPILER {} CONFIG_PATH \ +OUTPUT_PATH_PREFIX".format(sys.argv[0])) + sys.exit(0) + + +def str_to_c_byte_array(s): + """ + Convert strings to byte-arrays so we don't worry about formatting + strings to play nicely with cc -DQEMU_FUZZARGS etc + """ + return ','.join('0x{:02x}'.format(ord(x)) for x in s) + + +def compile_wrapper(cfg, path): + os.system('$CC -DQEMU_FUZZ_ARGS="{}" -DQEMU_FUZZ_OBJECTS="{}" \ + {} -o {}'.format( + str_to_c_byte_array(cfg["args"].replace("\n", " ")), + str_to_c_byte_array(cfg["objects"].replace("\n", " ")), + TEMPLATE, path)) + + +def main(): + global CC + global TEMPLATE + + if len(sys.argv) != 3: + usage() + + cfg_path = sys.argv[1] + out_path = sys.argv[2] + + CC = os.getenv("CC") + TEMPLATE = os.path.join(os.path.dirname(__file__), "target.c") + + with open(cfg_path, "r") as f: + configs = yaml.load(f)["configs"] + for cfg in configs: + assert "name" in cfg + assert "args" in cfg + assert "objects" in cfg + compile_wrapper(cfg, out_path + cfg["name"]) + + +if __name__ == '__main__': + main()
This parses a yaml file containing general-fuzzer configs and builds a separate oss-fuzz wrapper binary for each one, changing some preprocessor macros for each configuration. To avoid dealing with escaping and stringifying, convert each string into a byte-array representation Signed-off-by: Alexander Bulekov <alxndr@bu.edu> --- scripts/oss-fuzz/build_general_fuzzers.py | 62 +++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100755 scripts/oss-fuzz/build_general_fuzzers.py