summaryrefslogtreecommitdiff
path: root/fuzz/fuzz.c
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2023-03-08 13:59:03 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2023-03-08 14:14:22 +0100
commit42322eba820022eaebb9b6e7c083a8aadddea286 (patch)
tree941f355518e69dd2d4673d28c58e46cc5b5d6146 /fuzz/fuzz.c
parent7cd2676277f638e8596ce6b01deef901cf4bb0c1 (diff)
downloadlibxml2-42322eba820022eaebb9b6e7c083a8aadddea286.tar.gz
fuzz: Inject random malloc failures
Fixes #344.
Diffstat (limited to 'fuzz/fuzz.c')
-rw-r--r--fuzz/fuzz.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/fuzz/fuzz.c b/fuzz/fuzz.c
index 2e9b480f..76251316 100644
--- a/fuzz/fuzz.c
+++ b/fuzz/fuzz.c
@@ -42,6 +42,9 @@ static struct {
xmlFuzzEntityInfo *mainEntity;
} fuzzData;
+size_t fuzzNumAllocs;
+size_t fuzzMaxAllocs;
+
/**
* xmlFuzzErrorFunc:
*
@@ -52,6 +55,58 @@ xmlFuzzErrorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
...) {
}
+/*
+ * Malloc failure injection.
+ *
+ * Quick tip to debug complicated issues: Increase MALLOC_OFFSET until
+ * the crash disappears (or a different issue is triggered). Then set
+ * the offset to the highest value that produces a crash and set
+ * MALLOC_ABORT to 1 to see which failed memory allocation causes the
+ * issue.
+ */
+
+#define XML_FUZZ_MALLOC_OFFSET 0
+#define XML_FUZZ_MALLOC_ABORT 0
+
+static void *
+xmlFuzzMalloc(size_t size) {
+ if (fuzzMaxAllocs > 0) {
+ if (fuzzNumAllocs >= fuzzMaxAllocs - 1)
+#if XML_FUZZ_MALLOC_ABORT
+ abort();
+#else
+ return(NULL);
+#endif
+ fuzzNumAllocs += 1;
+ }
+ return malloc(size);
+}
+
+static void *
+xmlFuzzRealloc(void *ptr, size_t size) {
+ if (fuzzMaxAllocs > 0) {
+ if (fuzzNumAllocs >= fuzzMaxAllocs - 1)
+#if XML_FUZZ_MALLOC_ABORT
+ abort();
+#else
+ return(NULL);
+#endif
+ fuzzNumAllocs += 1;
+ }
+ return realloc(ptr, size);
+}
+
+void
+xmlFuzzMemSetup(void) {
+ xmlMemSetup(free, xmlFuzzMalloc, xmlFuzzRealloc, xmlMemStrdup);
+}
+
+void
+xmlFuzzMemSetLimit(size_t limit) {
+ fuzzNumAllocs = 0;
+ fuzzMaxAllocs = limit ? limit + XML_FUZZ_MALLOC_OFFSET : 0;
+}
+
/**
* xmlFuzzDataInit:
*
@@ -299,6 +354,8 @@ xmlFuzzEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED,
return(NULL);
input = xmlNewInputStream(ctxt);
+ if (input == NULL)
+ return(NULL);
input->filename = (char *) xmlCharStrdup(URL);
input->buf = xmlParserInputBufferCreateMem(entity->data, entity->size,
XML_CHAR_ENCODING_NONE);
@@ -312,47 +369,6 @@ xmlFuzzEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED,
return input;
}
-/**
- * xmlFuzzExtractStrings:
- *
- * Extract C strings from input data. Use exact-size allocations to detect
- * potential memory errors.
- */
-size_t
-xmlFuzzExtractStrings(const char *data, size_t size, char **strings,
- size_t numStrings) {
- const char *start = data;
- const char *end = data + size;
- size_t i = 0, ret;
-
- while (i < numStrings) {
- size_t strSize = end - start;
- const char *zero = memchr(start, 0, strSize);
-
- if (zero != NULL)
- strSize = zero - start;
-
- strings[i] = xmlMalloc(strSize + 1);
- memcpy(strings[i], start, strSize);
- strings[i][strSize] = '\0';
-
- i++;
- if (zero != NULL)
- start = zero + 1;
- else
- break;
- }
-
- ret = i;
-
- while (i < numStrings) {
- strings[i] = NULL;
- i++;
- }
-
- return(ret);
-}
-
char *
xmlSlurpFile(const char *path, size_t *sizeRet) {
FILE *file;