Hash :
9086988f
Author :
Date :
2020-12-16T15:41:52
Enforce maximum length of fuzz input Remove the libfuzzer max_len option which doesn't apply to other fuzzing engines. Enforce the maximum length directly in the fuzz targets. For the xml target, lower the maximum when expanding entities to avoid timeout and OOM errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
/*
* xml.c: a libFuzzer target to test several XML parser interfaces.
*
* See Copyright for the status of this software.
*/
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <libxml/xinclude.h>
#include <libxml/xmlreader.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) {
static const size_t maxChunkSize = 128;
xmlDocPtr doc;
xmlParserCtxtPtr ctxt;
xmlTextReaderPtr reader;
xmlChar *out;
const char *docBuffer, *docUrl;
size_t maxSize, docSize, consumed, chunkSize;
int opts, outSize;
xmlFuzzDataInit(data, size);
opts = xmlFuzzReadInt();
/* Lower maximum size when processing entities for now. */
maxSize = opts & XML_PARSE_NOENT ? 50000 : 500000;
if (size > maxSize) {
xmlFuzzDataCleanup();
return(0);
}
xmlFuzzReadEntities();
docBuffer = xmlFuzzMainEntity(&docSize);
docUrl = xmlFuzzMainUrl();
if (docBuffer == NULL) {
xmlFuzzDataCleanup();
return(0);
}
/* Pull parser */
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
if (opts & XML_PARSE_XINCLUDE)
xmlXIncludeProcessFlags(doc, opts);
/* Also test the serializer. */
xmlDocDumpMemory(doc, &out, &outSize);
xmlFree(out);
xmlFreeDoc(doc);
/* Push parser */
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
xmlCtxtUseOptions(ctxt, opts);
for (consumed = 0; consumed < docSize; consumed += chunkSize) {
chunkSize = docSize - consumed;
if (chunkSize > maxChunkSize)
chunkSize = maxChunkSize;
xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
}
xmlParseChunk(ctxt, NULL, 0, 1);
if (opts & XML_PARSE_XINCLUDE)
xmlXIncludeProcessFlags(ctxt->myDoc, opts);
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
/* Reader */
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
while (xmlTextReaderRead(reader) == 1) {
if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
int i, n = xmlTextReaderAttributeCount(reader);
for (i=0; i<n; i++) {
xmlTextReaderMoveToAttributeNo(reader, i);
while (xmlTextReaderReadAttributeValue(reader) == 1);
}
}
}
xmlFreeTextReader(reader);
/* Cleanup */
xmlFuzzDataCleanup();
return(0);
}