fuzz: Inject IO failures

We use the same counter for injecting malloc and IO failures. This
mostly renames several functions and variables.
This commit is contained in:
Nick Wellnhofer 2024-11-25 19:41:33 +01:00
parent 754843abda
commit 9f652e57c1
12 changed files with 191 additions and 150 deletions

View File

@ -970,7 +970,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
size_t maxAlloc;
size_t failurePos;
int i;
if (size > 1000)
@ -980,8 +980,8 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlFuzzDataInit(data, size);
maxAlloc = xmlFuzzReadInt(4) % (size * 50 + 10);
xmlFuzzMemSetLimit(maxAlloc);
failurePos = xmlFuzzReadInt(4) % (size * 50 + 10);
xmlFuzzInjectFailure(failurePos);
/*
* Interpreter loop
@ -1804,7 +1804,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
node,
BAD_CAST "lang",
XML_XML_NAMESPACE);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
removeChildren((xmlNodePtr) attr, 0);
res = xmlNodeSetLang(
node,
@ -1838,7 +1838,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
node,
BAD_CAST "space",
XML_XML_NAMESPACE);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
removeChildren((xmlNodePtr) attr, 0);
res = xmlNodeSetSpacePreserve(
node,
@ -1890,7 +1890,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
node,
BAD_CAST "base",
XML_XML_NAMESPACE);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
removeChildren((xmlNodePtr) attr, 0);
res = xmlNodeSetBase(
node,
@ -2029,7 +2029,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
oldAttr = xmlHasNsProp(node, name, NULL);
else
oldAttr = xmlHasNsProp(node, localName, ns->href);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
if (oldAttr != NULL)
removeChildren((xmlNodePtr) oldAttr, 0);
@ -2056,7 +2056,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
name = getStr(0);
value = getStr(1);
oldAttr = xmlHasNsProp(node, name, ns ? ns->href : NULL);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
if (oldAttr != NULL)
removeChildren((xmlNodePtr) oldAttr, 0);
attr = xmlSetNsProp(node, ns, name, value);
@ -2105,7 +2105,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
node = getNode(0);
name = getStr(0);
attr = xmlHasNsProp(node, name, NULL);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
if (attr != NULL)
removeChildren((xmlNodePtr) attr, 1);
setInt(0, xmlUnsetProp(node, name));
@ -2127,7 +2127,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
ns = nodeGetNs(getNode(1), getInt(1));
name = getStr(0);
attr = xmlHasNsProp(node, name, ns ? ns->href : NULL);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
if (attr != NULL)
removeChildren((xmlNodePtr) attr, 1);
setInt(0, xmlUnsetNsProp(node, ns, name));
@ -2389,7 +2389,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlAttrPtr attr = xmlHasNsProp(parent, node->name,
node->ns ? node->ns->href : NULL);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
/* Attribute might be replaced */
if (attr != NULL && attr != (xmlAttrPtr) node)
removeChildren((xmlNodePtr) attr, 1);
@ -3016,7 +3016,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
node = getNode(0);
type = node ? node->type : 0;
xmlValidCtxtPtr vctxt = xmlNewValidCtxt();
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
switch (type) {
case XML_DOCUMENT_NODE:
@ -3178,7 +3178,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
incStrIdx();
buffer = xmlBufferCreate();
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
node = getNode(0);
doc = node ? node->doc : NULL;
level = getInt(0);
@ -3302,7 +3302,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
incStrIdx();
output = xmlAllocOutputBuffer(NULL);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
node = getNode(0);
doc = node ? node->doc : NULL;
encoding = (const char *) getStr(1);
@ -3570,7 +3570,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
break;
}
xmlFuzzCheckMallocFailure(vars->opName, oomReport);
xmlFuzzCheckFailureReport(vars->opName, oomReport, 0);
}
for (i = 0; i < REG_MAX; i++)
@ -3583,7 +3583,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
dropNode(node);
}
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();
return(0);

View File

@ -42,9 +42,10 @@ static struct {
xmlFuzzEntityInfo *mainEntity;
} fuzzData;
size_t fuzzNumAllocs;
size_t fuzzMaxAllocs;
size_t fuzzNumAttempts;
size_t fuzzFailurePos;
int fuzzAllocFailed;
int fuzzIoFailed;
/**
* xmlFuzzErrorFunc:
@ -67,29 +68,61 @@ xmlFuzzSErrorFunc(void *ctx ATTRIBUTE_UNUSED,
}
/*
* Malloc failure injection.
* Failure injection.
*
* To debug issues involving malloc failures, it's often helpful to set
* MALLOC_ABORT to 1. This should provide a backtrace of the failed
* allocation.
* To debug issues involving injected failures, it's often helpful to set
* FAILURE_ABORT to 1. This should provide a backtrace of the failed
* operation.
*/
#define XML_FUZZ_MALLOC_ABORT 0
#define XML_FUZZ_FAILURE_ABORT 0
void
xmlFuzzInjectFailure(size_t failurePos) {
fuzzNumAttempts = 0;
fuzzFailurePos = failurePos;
fuzzAllocFailed = 0;
fuzzIoFailed = 0;
}
static int
xmlFuzzTryMalloc(void) {
if (fuzzFailurePos > 0) {
fuzzNumAttempts += 1;
if (fuzzNumAttempts == fuzzFailurePos) {
#if XML_FUZZ_FAILURE_ABORT
abort();
#endif
fuzzAllocFailed = 1;
return -1;
}
}
return 0;
}
static int
xmlFuzzTryIo(void) {
if (fuzzFailurePos > 0) {
fuzzNumAttempts += 1;
if (fuzzNumAttempts == fuzzFailurePos) {
#if XML_FUZZ_FAILURE_ABORT
abort();
#endif
fuzzIoFailed = 1;
return -1;
}
}
return 0;
}
static void *
xmlFuzzMalloc(size_t size) {
void *ret;
if (fuzzMaxAllocs > 0) {
fuzzNumAllocs += 1;
if (fuzzNumAllocs == fuzzMaxAllocs) {
#if XML_FUZZ_MALLOC_ABORT
abort();
#endif
fuzzAllocFailed = 1;
return NULL;
}
}
if (xmlFuzzTryMalloc() < 0)
return NULL;
ret = malloc(size);
if (ret == NULL)
@ -102,16 +135,8 @@ static void *
xmlFuzzRealloc(void *ptr, size_t size) {
void *ret;
if (fuzzMaxAllocs > 0) {
fuzzNumAllocs += 1;
if (fuzzNumAllocs == fuzzMaxAllocs) {
#if XML_FUZZ_MALLOC_ABORT
abort();
#endif
fuzzAllocFailed = 1;
return NULL;
}
}
if (xmlFuzzTryMalloc() < 0)
return NULL;
ret = realloc(ptr, size);
if (ret == NULL)
@ -125,31 +150,31 @@ xmlFuzzMemSetup(void) {
xmlMemSetup(free, xmlFuzzMalloc, xmlFuzzRealloc, xmlMemStrdup);
}
void
xmlFuzzMemSetLimit(size_t limit) {
fuzzNumAllocs = 0;
fuzzMaxAllocs = limit;
fuzzAllocFailed = 0;
}
int
xmlFuzzMallocFailed(void) {
return fuzzAllocFailed;
}
void
xmlFuzzResetMallocFailed(void) {
xmlFuzzResetFailure(void) {
fuzzAllocFailed = 0;
fuzzIoFailed = 0;
}
void
xmlFuzzCheckMallocFailure(const char *func, int error) {
if (error >= 0 && fuzzAllocFailed != error) {
xmlFuzzCheckFailureReport(const char *func, int oomReport, int ioReport) {
if (oomReport >= 0 && fuzzAllocFailed != oomReport) {
fprintf(stderr, "%s: malloc failure %s reported\n",
func, fuzzAllocFailed ? "not" : "erroneously");
abort();
}
if (ioReport >= 0 && fuzzIoFailed != ioReport) {
fprintf(stderr, "%s: IO failure %s reported\n",
func, fuzzIoFailed ? "not" : "erroneously");
abort();
}
fuzzAllocFailed = 0;
fuzzIoFailed = 0;
}
/**
@ -413,6 +438,10 @@ xmlFuzzResourceLoader(void *data ATTRIBUTE_UNUSED, const char *URL,
if (entity == NULL)
return(XML_IO_ENOENT);
/* IO failure injection */
if (xmlFuzzTryIo() < 0)
return(XML_IO_EIO);
input = xmlNewInputFromMemory(URL, entity->data, entity->size,
XML_INPUT_BUF_STATIC |
XML_INPUT_BUF_ZERO_TERMINATED);

View File

@ -68,16 +68,16 @@ void
xmlFuzzMemSetup(void);
void
xmlFuzzMemSetLimit(size_t limit);
xmlFuzzInjectFailure(size_t failurePos);
int
xmlFuzzMallocFailed(void);
void
xmlFuzzResetMallocFailed(void);
xmlFuzzResetFailure(void);
void
xmlFuzzCheckMallocFailure(const char *func, int expect);
xmlFuzzCheckFailureReport(const char *func, int oomReport, int ioReport);
void
xmlFuzzDataInit(const char *data, size_t size);

View File

@ -27,12 +27,12 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlParserCtxtPtr ctxt;
htmlDocPtr doc;
const char *docBuffer;
size_t maxAlloc, docSize;
size_t failurePos, docSize;
int opts;
xmlFuzzDataInit(data, size);
opts = (int) xmlFuzzReadInt(4);
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
docBuffer = xmlFuzzReadRemaining(&docSize);
if (docBuffer == NULL) {
@ -42,13 +42,14 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Pull parser */
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = htmlNewParserCtxt();
if (ctxt != NULL) {
xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
doc = htmlCtxtReadMemory(ctxt, docBuffer, docSize, NULL, NULL, opts);
xmlFuzzCheckMallocFailure("htmlCtxtReadMemory",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("htmlCtxtReadMemory",
ctxt->errNo == XML_ERR_NO_MEMORY,
ctxt->errNo == XML_IO_EIO);
if (doc != NULL) {
xmlDocPtr copy;
@ -66,12 +67,12 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
htmlDocContentDumpOutput(out, doc, NULL);
content = xmlOutputBufferGetContent(out);
xmlOutputBufferClose(out);
xmlFuzzCheckMallocFailure("htmlDocContentDumpOutput",
content == NULL);
xmlFuzzCheckFailureReport("htmlDocContentDumpOutput",
content == NULL, 0);
#endif
copy = xmlCopyDoc(doc, 1);
xmlFuzzCheckMallocFailure("xmlCopyNode", copy == NULL);
xmlFuzzCheckFailureReport("xmlCopyNode", copy == NULL, 0);
xmlFreeDoc(copy);
xmlFreeDoc(doc);
@ -88,7 +89,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
static const size_t maxChunkSize = 128;
size_t consumed, chunkSize;
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
XML_CHAR_ENCODING_NONE);
@ -104,8 +105,9 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
}
htmlParseChunk(ctxt, NULL, 0, 1);
xmlFuzzCheckMallocFailure("htmlParseChunk",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("htmlParseChunk",
ctxt->errNo == XML_ERR_NO_MEMORY,
ctxt->errNo == XML_IO_EIO);
xmlFreeDoc(ctxt->myDoc);
htmlFreeParserCtxt(ctxt);
}
@ -114,7 +116,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Cleanup */
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();

View File

@ -107,14 +107,14 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
const xmlError *error;
const char *docBuffer;
const unsigned char *program;
size_t maxAlloc, docSize, programSize, i;
size_t failurePos, docSize, programSize, i;
size_t totalStringSize = 0;
int opts;
int oomReport = 0;
xmlFuzzDataInit(data, size);
opts = (int) xmlFuzzReadInt(4);
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
program = (const unsigned char *) xmlFuzzReadString(&programSize);
if (programSize > 1000)
@ -138,7 +138,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
fprintf(stderr, "\nEOF\n");
#endif
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
@ -539,7 +539,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
error = xmlTextReaderGetLastError(reader);
if (error->code == XML_ERR_NO_MEMORY)
oomReport = 1;
xmlFuzzCheckMallocFailure("reader", oomReport);
xmlFuzzCheckFailureReport("reader", oomReport, 0);
xmlFreeTextReader(reader);
@ -547,7 +547,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlFreeDoc(doc);
exit:
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();
return(0);

View File

@ -20,17 +20,17 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlRegexpPtr regexp;
size_t maxAlloc;
size_t failurePos;
const char *str1;
if (size > 200)
return(0);
xmlFuzzDataInit(data, size);
maxAlloc = xmlFuzzReadInt(4) % (size * 8 + 100);
failurePos = xmlFuzzReadInt(4) % (size * 8 + 100);
str1 = xmlFuzzReadString(NULL);
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
regexp = xmlRegexpCompile(BAD_CAST str1);
if (xmlFuzzMallocFailed() && regexp != NULL) {
fprintf(stderr, "malloc failure not reported\n");
@ -42,7 +42,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
#endif
xmlRegFreeRegexp(regexp);
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();

View File

@ -24,24 +24,24 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlSchemaParserCtxtPtr pctxt;
size_t maxAlloc;
size_t failurePos;
if (size > 50000)
return(0);
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
xmlFuzzDataInit(data, size);
xmlFuzzReadEntities();
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
pctxt = xmlSchemaNewParserCtxt(xmlFuzzMainUrl());
xmlSchemaSetParserStructuredErrors(pctxt, xmlFuzzSErrorFunc, NULL);
xmlSchemaSetResourceLoader(pctxt, xmlFuzzResourceLoader, NULL);
xmlSchemaFree(xmlSchemaParse(pctxt));
xmlSchemaFreeParserCtxt(pctxt);
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();

View File

@ -18,7 +18,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlURIPtr uri;
size_t maxAlloc;
size_t failurePos;
const char *str1, *str2;
char *copy;
xmlChar *strRes;
@ -28,20 +28,20 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
return(0);
xmlFuzzDataInit(data, size);
maxAlloc = xmlFuzzReadInt(4) % (size * 8 + 100);
failurePos = xmlFuzzReadInt(4) % (size * 8 + 100);
str1 = xmlFuzzReadString(NULL);
str2 = xmlFuzzReadString(NULL);
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
intRes = xmlParseURISafe(str1, &uri);
xmlFuzzCheckMallocFailure("xmlParseURISafe", intRes == -1);
xmlFuzzCheckFailureReport("xmlParseURISafe", intRes == -1, 0);
if (uri != NULL) {
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
strRes = xmlSaveUri(uri);
xmlFuzzCheckMallocFailure("xmlSaveURI", strRes == NULL);
xmlFuzzCheckFailureReport("xmlSaveURI", strRes == NULL, 0);
xmlFree(strRes);
xmlFreeURI(uri);
}
@ -52,50 +52,51 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlFree(xmlSaveUri(uri));
xmlFreeURI(uri);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
strRes = BAD_CAST xmlURIUnescapeString(str1, -1, NULL);
xmlFuzzCheckMallocFailure("xmlURIUnescapeString",
str1 != NULL && strRes == NULL);
xmlFuzzCheckFailureReport("xmlURIUnescapeString",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
xmlFree(xmlURIEscape(BAD_CAST str1));
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
strRes = xmlCanonicPath(BAD_CAST str1);
xmlFuzzCheckMallocFailure("xmlCanonicPath",
str1 != NULL && strRes == NULL);
xmlFuzzCheckFailureReport("xmlCanonicPath",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
strRes = xmlPathToURI(BAD_CAST str1);
xmlFuzzCheckMallocFailure("xmlPathToURI", str1 != NULL && strRes == NULL);
xmlFuzzCheckFailureReport("xmlPathToURI",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
intRes = xmlBuildURISafe(BAD_CAST str2, BAD_CAST str1, &strRes);
xmlFuzzCheckMallocFailure("xmlBuildURISafe", intRes == -1);
xmlFuzzCheckFailureReport("xmlBuildURISafe", intRes == -1, 0);
xmlFree(strRes);
xmlFree(xmlBuildURI(BAD_CAST str2, BAD_CAST str1));
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
intRes = xmlBuildRelativeURISafe(BAD_CAST str2, BAD_CAST str1, &strRes);
xmlFuzzCheckMallocFailure("xmlBuildRelativeURISafe", intRes == -1);
xmlFuzzCheckFailureReport("xmlBuildRelativeURISafe", intRes == -1, 0);
xmlFree(strRes);
xmlFree(xmlBuildRelativeURI(BAD_CAST str2, BAD_CAST str1));
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
strRes = xmlURIEscapeStr(BAD_CAST str1, BAD_CAST str2);
xmlFuzzCheckMallocFailure("xmlURIEscapeStr",
str1 != NULL && strRes == NULL);
xmlFuzzCheckFailureReport("xmlURIEscapeStr",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
copy = (char *) xmlCharStrdup(str1);
xmlNormalizeURIPath(copy);
xmlFree(copy);
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
return 0;

View File

@ -28,14 +28,14 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
const char *docBuffer, *docUrl;
size_t maxAlloc, docSize;
size_t failurePos, docSize;
int opts;
xmlFuzzDataInit(data, size);
opts = (int) xmlFuzzReadInt(4);
opts &= ~XML_PARSE_XINCLUDE;
opts |= XML_PARSE_DTDVALID;
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
xmlFuzzReadEntities();
docBuffer = xmlFuzzMainEntity(&docSize);
@ -45,33 +45,37 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Pull parser */
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = xmlNewParserCtxt();
if (ctxt != NULL) {
xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlCtxtReadMemory",
ctxt->errNo == XML_ERR_NO_MEMORY,
ctxt->errNo == XML_IO_EIO);
xmlFreeDoc(doc);
xmlFreeParserCtxt(ctxt);
}
/* Post validation */
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = xmlNewParserCtxt();
if (ctxt != NULL) {
xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL,
opts & ~XML_PARSE_DTDVALID);
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlCtxtReadMemory",
doc == NULL && ctxt->errNo == XML_ERR_NO_MEMORY,
doc == NULL && ctxt->errNo == XML_IO_EIO);
if (doc != NULL) {
xmlCtxtValidateDocument(ctxt, doc);
xmlFuzzCheckMallocFailure("xmlCtxtValidateDocument",
ctxt->errNo == XML_ERR_NO_MEMORY);
int valid = xmlCtxtValidateDocument(ctxt, doc);
xmlFuzzCheckFailureReport("xmlCtxtValidateDocument",
!valid && ctxt->errNo == XML_ERR_NO_MEMORY,
!valid && ctxt->errNo == XML_IO_EIO);
}
xmlFreeDoc(doc);
xmlFreeParserCtxt(ctxt);
@ -84,7 +88,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
static const size_t maxChunkSize = 128;
size_t consumed, chunkSize;
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
/*
* FIXME: xmlCreatePushParserCtxt can still report OOM errors
* to stderr.
@ -105,8 +109,9 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
}
xmlParseChunk(ctxt, NULL, 0, 1);
xmlFuzzCheckMallocFailure("xmlParseChunk",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlParseChunk",
ctxt->errNo == XML_ERR_NO_MEMORY,
ctxt->errNo == XML_IO_EIO);
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
}
@ -114,7 +119,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
#endif
exit:
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();
return(0);

View File

@ -30,13 +30,13 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
const char *docBuffer, *docUrl;
size_t maxAlloc, docSize;
size_t failurePos, docSize;
int opts;
xmlFuzzDataInit(data, size);
opts = (int) xmlFuzzReadInt(4);
opts |= XML_PARSE_XINCLUDE;
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
xmlFuzzReadEntities();
docBuffer = xmlFuzzMainEntity(&docSize);
@ -46,7 +46,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Pull parser */
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = xmlNewParserCtxt();
if (ctxt != NULL) {
xmlXIncludeCtxtPtr xinc;
@ -55,24 +55,27 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlCtxtReadMemory",
doc == NULL && ctxt->errNo == XML_ERR_NO_MEMORY,
doc == NULL && ctxt->errNo == XML_IO_EIO);
xinc = xmlXIncludeNewContext(doc);
xmlXIncludeSetResourceLoader(xinc, xmlFuzzResourceLoader, NULL);
xmlXIncludeSetFlags(xinc, opts);
xmlXIncludeProcessNode(xinc, (xmlNodePtr) doc);
if (doc != NULL) {
xmlFuzzCheckMallocFailure("xmlXIncludeProcessNode",
xmlFuzzCheckFailureReport("xmlXIncludeProcessNode",
xinc == NULL ||
xmlXIncludeGetLastError(xinc) == XML_ERR_NO_MEMORY);
xmlXIncludeGetLastError(xinc) == XML_ERR_NO_MEMORY,
xinc != NULL &&
xmlXIncludeGetLastError(xinc) == XML_IO_EIO);
}
xmlXIncludeFreeContext(xinc);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
copy = xmlCopyDoc(doc, 1);
if (doc != NULL)
xmlFuzzCheckMallocFailure("xmlCopyNode", copy == NULL);
xmlFuzzCheckFailureReport("xmlCopyNode", copy == NULL, 0);
xmlFreeDoc(copy);
xmlFreeDoc(doc);
@ -80,7 +83,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
}
exit:
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();
return(0);

View File

@ -29,7 +29,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
const char *docBuffer, *docUrl;
size_t maxAlloc, docSize;
size_t failurePos, docSize;
int opts;
xmlFuzzDataInit(data, size);
@ -40,7 +40,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
opts &= ~XML_PARSE_XINCLUDE &
~XML_PARSE_DTDVALID &
~XML_PARSE_SAX1;
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
xmlFuzzReadEntities();
docBuffer = xmlFuzzMainEntity(&docSize);
@ -50,15 +50,15 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Pull parser */
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = xmlNewParserCtxt();
if (ctxt != NULL) {
xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
doc == NULL &&
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlCtxtReadMemory",
doc == NULL && ctxt->errNo == XML_ERR_NO_MEMORY,
doc == NULL && ctxt->errNo == XML_IO_EIO);
if (doc != NULL) {
#ifdef LIBXML_OUTPUT_ENABLED
@ -73,8 +73,9 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlSaveDoc(save, doc);
errNo = xmlSaveFinish(save);
xmlFuzzCheckMallocFailure("xmlSaveDoc",
errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlSaveDoc",
errNo == XML_ERR_NO_MEMORY,
errNo == XML_IO_EIO);
}
xmlBufferFree(buffer);
#endif
@ -91,7 +92,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
static const size_t maxChunkSize = 128;
size_t consumed, chunkSize;
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
if (ctxt != NULL) {
xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
@ -106,8 +107,9 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
}
xmlParseChunk(ctxt, NULL, 0, 1);
xmlFuzzCheckMallocFailure("xmlParseChunk",
ctxt->errNo == XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlParseChunk",
ctxt->errNo == XML_ERR_NO_MEMORY,
ctxt->errNo == XML_IO_EIO);
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
}
@ -115,7 +117,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
#endif
exit:
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
xmlResetLastError();
return(0);

View File

@ -27,14 +27,14 @@ int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlDocPtr doc;
const char *expr, *xml;
size_t maxAlloc, exprSize, xmlSize;
size_t failurePos, exprSize, xmlSize;
if (size > 10000)
return(0);
xmlFuzzDataInit(data, size);
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
failurePos = xmlFuzzReadInt(4) % (size + 100);
expr = xmlFuzzReadString(&exprSize);
xml = xmlFuzzReadString(&xmlSize);
@ -43,7 +43,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
if (doc != NULL) {
xmlXPathContextPtr xpctxt;
xmlFuzzMemSetLimit(maxAlloc);
xmlFuzzInjectFailure(failurePos);
xpctxt = xmlXPathNewContext(doc);
if (xpctxt != NULL) {
@ -53,17 +53,16 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xpctxt->opLimit = 500000;
res = xmlXPathContextSetCache(xpctxt, 1, 4, 0);
xmlFuzzCheckMallocFailure("xmlXPathContextSetCache", res == -1);
xmlFuzzCheckFailureReport("xmlXPathContextSetCache", res == -1, 0);
xmlFuzzResetMallocFailed();
xmlFuzzResetFailure();
xmlXPathFreeObject(xmlXPtrEval(BAD_CAST expr, xpctxt));
xmlFuzzCheckMallocFailure("xmlXPtrEval",
xpctxt->lastError.code ==
XML_ERR_NO_MEMORY);
xmlFuzzCheckFailureReport("xmlXPtrEval",
xpctxt->lastError.code == XML_ERR_NO_MEMORY, 0);
xmlXPathFreeContext(xpctxt);
}
xmlFuzzMemSetLimit(0);
xmlFuzzInjectFailure(0);
xmlFreeDoc(doc);
}