[libxml2] Fuzz target for XML Schemas
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml2] Fuzz target for XML Schemas
- Date: Tue, 23 Jun 2020 14:32:18 +0000 (UTC)
commit eac1c7e2e5afffffddf305a290451d80be4a2c19
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Sun Jun 21 14:42:00 2020 +0200
Fuzz target for XML Schemas
This only tests the schema parser for now.
fuzz/.gitignore | 3 +++
fuzz/Makefile.am | 29 +++++++++++++++++++++++++++-
fuzz/fuzz.c | 10 ++++++++++
fuzz/fuzz.h | 3 +++
fuzz/schema.c | 36 +++++++++++++++++++++++++++++++++++
fuzz/schema.dict | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
fuzz/schema.options | 2 ++
fuzz/schemaSeed.c | 34 +++++++++++++++++++++++++++++++++
fuzz/xmlSeed.c | 1 +
9 files changed, 172 insertions(+), 1 deletion(-)
---
diff --git a/fuzz/.gitignore b/fuzz/.gitignore
index 178a6592..d7ea7964 100644
--- a/fuzz/.gitignore
+++ b/fuzz/.gitignore
@@ -1,7 +1,10 @@
corpus/
html
regexp
+schema
+schemaSeed
seed/xml*
+seed/schema*
testFuzzer
uri
xml
diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am
index a286f867..c360e567 100644
--- a/fuzz/Makefile.am
+++ b/fuzz/Makefile.am
@@ -1,4 +1,4 @@
-EXTRA_PROGRAMS = html regexp uri xml xmlSeed
+EXTRA_PROGRAMS = html regexp uri schema schemaSeed xml xmlSeed
check_PROGRAMS = testFuzzer
CLEANFILES = $(EXTRA_PROGRAMS)
AM_CPPFLAGS = -I$(top_srcdir)/include
@@ -84,3 +84,30 @@ fuzz-uri: uri$(EXEEXT)
-timeout=2 \
corpus/uri $(srcdir)/seed/uri
+schemaSeed_SOURCES = schemaSeed.c fuzz.c
+
+seed/schema.stamp: schemaSeed$(EXEEXT)
+ @mkdir -p seed/schema
+ @for i in ../test/schemas/*.xsd; do \
+ if [ -f $$i ]; then \
+ echo Processing seed $$i; \
+ base=$$(basename $$i) \
+ outfile=$(abs_builddir)/seed/schema/$$base; \
+ pushd $$(dirname $$i) >/dev/null; \
+ $(abs_builddir)/schemaSeed$(EXEEXT) $$base > $$outfile; \
+ popd >/dev/null; \
+ fi; \
+ done
+ @touch seed/schema.stamp
+
+schema_SOURCES = schema.c fuzz.c
+schema_LDFLAGS = -fsanitize=fuzzer
+
+fuzz-schema: schema$(EXEEXT) seed/schema.stamp
+ @mkdir -p corpus/schema
+ ./schema$(EXEEXT) \
+ -dict=schema.dict \
+ -max_len=$(PARSER_FUZZER_MAX_LEN) \
+ -timeout=20 \
+ corpus/schema seed/schema
+
diff --git a/fuzz/fuzz.c b/fuzz/fuzz.c
index 5bf8e552..ba7c9cad 100644
--- a/fuzz/fuzz.c
+++ b/fuzz/fuzz.c
@@ -265,6 +265,16 @@ xmlFuzzReadEntities(void) {
}
}
+/**
+ * xmlFuzzMainUrl:
+ *
+ * Returns the main URL.
+ */
+const char *
+xmlFuzzMainUrl(void) {
+ return(fuzzData.mainUrl);
+}
+
/**
* xmlFuzzMainEntity:
* @size: size of the main entity in bytes
diff --git a/fuzz/fuzz.h b/fuzz/fuzz.h
index eabe0941..7e7fc29c 100644
--- a/fuzz/fuzz.h
+++ b/fuzz/fuzz.h
@@ -42,6 +42,9 @@ xmlFuzzEntityRecorder(const char *URL, const char *ID, xmlParserCtxtPtr ctxt);
void
xmlFuzzReadEntities(void);
+const char *
+xmlFuzzMainUrl(void);
+
const char *
xmlFuzzMainEntity(size_t *size);
diff --git a/fuzz/schema.c b/fuzz/schema.c
new file mode 100644
index 00000000..f1ee9380
--- /dev/null
+++ b/fuzz/schema.c
@@ -0,0 +1,36 @@
+/*
+ * schema.c: a libFuzzer target to test the XML Schema processor.
+ *
+ * See Copyright for the status of this software.
+ */
+
+#include <libxml/xmlschemas.h>
+#include "fuzz.h"
+
+int
+LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
+ char ***argv ATTRIBUTE_UNUSED) {
+ xmlInitParser();
+ xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
+ xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
+
+ return 0;
+}
+
+int
+LLVMFuzzerTestOneInput(const char *data, size_t size) {
+ xmlSchemaParserCtxtPtr pctxt;
+
+ xmlFuzzDataInit(data, size);
+ xmlFuzzReadEntities();
+
+ pctxt = xmlSchemaNewParserCtxt(xmlFuzzMainUrl());
+ xmlSchemaSetParserErrors(pctxt, xmlFuzzErrorFunc, xmlFuzzErrorFunc, NULL);
+ xmlSchemaFree(xmlSchemaParse(pctxt));
+ xmlSchemaFreeParserCtxt(pctxt);
+
+ xmlFuzzDataCleanup();
+
+ return(0);
+}
+
diff --git a/fuzz/schema.dict b/fuzz/schema.dict
new file mode 100644
index 00000000..9a8fd386
--- /dev/null
+++ b/fuzz/schema.dict
@@ -0,0 +1,55 @@
+# TODO: Add more language elements
+
+xs_annotation="<xs:annotation></xs:annotation>"
+
+xs_attribute="<xs:attribute name='a'></xs:attribute>"
+xs_attribute_required="<xs:attribute name='a' use='required'></xs:attribute>"
+xs_element="<xs:element name='e'></xs:element>"
+
+# Primitive datatypes
+type_string=" type='xs:string'"
+type_boolean=" type='xs:boolean'"
+type_decimal=" type='xs:decimal'"
+type_float=" type='xs:float'"
+type_double=" type='xs:double'"
+type_date_time=" type='xs:dateTime'"
+type_time=" type='xs:time'"
+type_date=" type='xs:date'"
+type_g_year_month=" type='xs:gYearMonth'"
+type_g_year=" type='xs:gYear'"
+type_g_month_day=" type='xs:gMonthDay'"
+type_g_day=" type='xs:gDay'"
+type_g_month=" type='xs:gMonth'"
+type_hex_binary=" type='xs:hexBinary'"
+type_base64_binary=" type='xs:base64Binary'"
+type_any_uri=" type='xs:anyURI'"
+type_qname=" type='xs:QName'"
+type_notation=" type='xs:NOTATION'"
+
+# Occurs
+occurs_min=" minOccurs='1'"
+occurs_max=" maxOccurs='9'"
+occurs_max_unbounded=" maxOccurs='unbounded'"
+
+# Simple type
+xs_restriction_integer="<xs:simpleType><xs:restriction base='xs:integer'></xs:restriction></xs:simpleType>"
+xs_restriction_string="<xs:simpleType><xs:restriction base='xs:string'></xs:restriction></xs:simpleType>"
+xs_list="<xs:simpleType><xs:list></xs:list></xs:simpleType>"
+xs_union="<xs:simpleType><xs:union></xs:union></xs:simpleType>"
+
+# Restrictions
+xs_min_exclusive="<xs:minExclusive value='0'/>"
+xs_min_inclusive="<xs:minInclusive value='0'/>"
+xs_max_exclusive="<xs:maxExclusive value='9'/>"
+xs_max_inclusive="<xs:maxInclusive value='9'/>"
+xs_total_digits="<xs:totalDigits value='3'/>"
+xs_fraction_digits="<xs:fractionDigits value='3'/>"
+xs_length="<xs:length value='3'/>"
+xs_min_length="<xs:minLength value='3'/>"
+xs_max_length="<xs:maxLength value='3'/>"
+xs_enumeration="<xs:enumeration value='a'/>"
+xs_white_space_collapse="<xs:whiteSpace value='collapse'/>"
+xs_white_space_preserve="<xs:whiteSpace value='preserve'/>"
+xs_white_space_replace="<xs:whiteSpace value='replace'/>"
+xs_pattern="<xs:pattern value='a'/>"
+
diff --git a/fuzz/schema.options b/fuzz/schema.options
new file mode 100644
index 00000000..09f13d89
--- /dev/null
+++ b/fuzz/schema.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 80000
diff --git a/fuzz/schemaSeed.c b/fuzz/schemaSeed.c
new file mode 100644
index 00000000..4e2c6bc6
--- /dev/null
+++ b/fuzz/schemaSeed.c
@@ -0,0 +1,34 @@
+/*
+ * xmlSeed.c: Generate the XML seed corpus for fuzzing.
+ *
+ * See Copyright for the status of this software.
+ */
+
+#include <stdio.h>
+#include <libxml/xmlschemas.h>
+#include "fuzz.h"
+
+int
+main(int argc, char **argv) {
+ xmlSchemaPtr schema;
+ xmlSchemaParserCtxtPtr pctxt;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: schemaSeed [XSD]\n");
+ return(1);
+ }
+
+ xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
+ xmlSetExternalEntityLoader(xmlFuzzEntityRecorder);
+
+ pctxt = xmlSchemaNewParserCtxt(argv[1]);
+ xmlSchemaSetParserErrors(pctxt, xmlFuzzErrorFunc, xmlFuzzErrorFunc, NULL);
+ schema = xmlSchemaParse(pctxt);
+ xmlSchemaFreeParserCtxt(pctxt);
+
+ xmlSchemaFree(schema);
+ xmlFuzzDataCleanup();
+
+ return(0);
+}
+
diff --git a/fuzz/xmlSeed.c b/fuzz/xmlSeed.c
index fc64cd45..5ce97d0b 100644
--- a/fuzz/xmlSeed.c
+++ b/fuzz/xmlSeed.c
@@ -13,6 +13,7 @@ main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: xmlSeed [FILE]\n");
+ return(1);
}
fwrite(&opts, sizeof(opts), 1, stdout);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]