summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2023-01-22 19:42:41 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2023-01-24 11:47:33 +0100
commit6fd8904108f23810699d3a242e3612c4ec2f9cf2 (patch)
treeae2cf65a1df05e3054a0b33c2e62580d1d43fea2
parentc266a220232d1a9cc9f7fe87116299269822a06a (diff)
downloadlibxml2-6fd8904108f23810699d3a242e3612c4ec2f9cf2.tar.gz
malloc-fail: Fix use-after-free in xmlParseStartTag2
Fix error handling in xmlCtxtGrowAttrs. Found with libFuzzer, see #344.
-rw-r--r--.gitlab-ci.yml4
-rw-r--r--parser.c26
2 files changed, 14 insertions, 16 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6b8f3cb3..0cf1c045 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -196,7 +196,9 @@ cmake:mingw:w64-x86_64:static:
tags:
- win32-ps
variables:
- CFLAGS: /WX
+ # MSVC warns when casting `const char **` to `void *` which is wrong.
+ # Disable warning C4090.
+ CFLAGS: /WX /wd4090
CMAKE_VERSION: 3.19.4
script:
- .gitlab-ci/Test-Msvc
diff --git a/parser.c b/parser.c
index 7b4bab0c..7164be7f 100644
--- a/parser.c
+++ b/parser.c
@@ -1655,25 +1655,21 @@ xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
int *attallocs;
int maxatts;
- if (ctxt->atts == NULL) {
- maxatts = 55; /* allow for 10 attrs by default */
- atts = (const xmlChar **)
- xmlMalloc(maxatts * sizeof(xmlChar *));
- if (atts == NULL) goto mem_error;
- ctxt->atts = atts;
- attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
- if (attallocs == NULL) goto mem_error;
- ctxt->attallocs = attallocs;
- ctxt->maxatts = maxatts;
- } else if (nr + 5 > ctxt->maxatts) {
- maxatts = (nr + 5) * 2;
- atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
+ if (nr + 5 > ctxt->maxatts) {
+ maxatts = ctxt->maxatts == 0 ? 55 : (nr + 5) * 2;
+ atts = (const xmlChar **) xmlMalloc(
maxatts * sizeof(const xmlChar *));
if (atts == NULL) goto mem_error;
- ctxt->atts = atts;
attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
(maxatts / 5) * sizeof(int));
- if (attallocs == NULL) goto mem_error;
+ if (attallocs == NULL) {
+ xmlFree(atts);
+ goto mem_error;
+ }
+ if (ctxt->maxatts > 0)
+ memcpy(atts, ctxt->atts, ctxt->maxatts * sizeof(const xmlChar *));
+ xmlFree(ctxt->atts);
+ ctxt->atts = atts;
ctxt->attallocs = attallocs;
ctxt->maxatts = maxatts;
}