commit
30f2c048aa
81
Fix-exponential-runtime-in-xmlFARecurseDeterminism.patch
Normal file
81
Fix-exponential-runtime-in-xmlFARecurseDeterminism.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
From 68eadabd0055cba39c4ea1acfa8931d0d10a44e5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||||
|
Date: Sat, 11 Jul 2020 21:32:10 +0200
|
||||||
|
Subject: [PATCH] Fix exponential runtime in xmlFARecurseDeterminism
|
||||||
|
|
||||||
|
In order to prevent visiting a state twice, states must be marked as
|
||||||
|
visited for the whole duration of graph traversal because states might
|
||||||
|
be reached by different paths. Otherwise state graphs like the
|
||||||
|
following can lead to exponential runtime:
|
||||||
|
|
||||||
|
->O-->O-->O-->O-->O->
|
||||||
|
\ / \ / \ / \ /
|
||||||
|
O O O O
|
||||||
|
|
||||||
|
Reset the "visited" flag only after the graph was traversed.
|
||||||
|
|
||||||
|
xmlFAComputesDeterminism still has massive performance problems when
|
||||||
|
handling fuzzed input. By design, it has quadratic time complexity in
|
||||||
|
the number of reachable states. Some issues might also stem from
|
||||||
|
redundant epsilon transitions. With this fix, fuzzing regexes with a
|
||||||
|
maximum length of 100 becomes feasible at least.
|
||||||
|
|
||||||
|
Found with libFuzzer.
|
||||||
|
---
|
||||||
|
xmlregexp.c | 26 +++++++++++++++++++++++++-
|
||||||
|
1 file changed, 25 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||||
|
index dbf3bf2c..f971f0c8 100644
|
||||||
|
--- a/xmlregexp.c
|
||||||
|
+++ b/xmlregexp.c
|
||||||
|
@@ -2658,7 +2658,6 @@ xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
|
||||||
|
state->markd = XML_REGEXP_MARK_VISITED;
|
||||||
|
res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
|
||||||
|
to, atom);
|
||||||
|
- state->markd = 0;
|
||||||
|
if (res == 0) {
|
||||||
|
ret = 0;
|
||||||
|
/* t1->nd = 1; */
|
||||||
|
@@ -2676,6 +2675,30 @@ xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * xmlFAFinishRecurseDeterminism:
|
||||||
|
+ * @ctxt: a regexp parser context
|
||||||
|
+ *
|
||||||
|
+ * Reset flags after checking determinism.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+xmlFAFinishRecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
|
||||||
|
+ int transnr, nbTrans;
|
||||||
|
+
|
||||||
|
+ if (state == NULL)
|
||||||
|
+ return;
|
||||||
|
+ if (state->markd != XML_REGEXP_MARK_VISITED)
|
||||||
|
+ return;
|
||||||
|
+ state->markd = 0;
|
||||||
|
+
|
||||||
|
+ nbTrans = state->nbTrans;
|
||||||
|
+ for (transnr = 0; transnr < nbTrans; transnr++) {
|
||||||
|
+ xmlRegTransPtr t1 = &state->trans[transnr];
|
||||||
|
+ if ((t1->atom == NULL) && (t1->to >= 0))
|
||||||
|
+ xmlFAFinishRecurseDeterminism(ctxt, ctxt->states[t1->to]);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* xmlFAComputesDeterminism:
|
||||||
|
* @ctxt: a regexp parser context
|
||||||
|
@@ -2789,6 +2812,7 @@ xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
|
||||||
|
*/
|
||||||
|
ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
|
||||||
|
t2->to, t2->atom);
|
||||||
|
+ xmlFAFinishRecurseDeterminism(ctxt, ctxt->states[t1->to]);
|
||||||
|
/* don't shortcut the computation so all non deterministic
|
||||||
|
transition get marked down
|
||||||
|
if (ret == 0)
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
50
Limit-regexp-nesting-depth.patch
Normal file
50
Limit-regexp-nesting-depth.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From fc842f6eba81f3b630e1ff1ffea69c6f4dd66ccc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||||
|
Date: Mon, 6 Jul 2020 15:22:12 +0200
|
||||||
|
Subject: [PATCH] Limit regexp nesting depth
|
||||||
|
|
||||||
|
Enforce a maximum nesting depth of 50 for regular expressions. Avoids
|
||||||
|
stack overflows with deeply nested regexes.
|
||||||
|
|
||||||
|
Found by OSS-Fuzz.
|
||||||
|
---
|
||||||
|
xmlregexp.c | 8 ++++++++
|
||||||
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||||
|
index 687290e2..dbf3bf2c 100644
|
||||||
|
--- a/xmlregexp.c
|
||||||
|
+++ b/xmlregexp.c
|
||||||
|
@@ -273,6 +273,8 @@ struct _xmlAutomata {
|
||||||
|
int determinist;
|
||||||
|
int negs;
|
||||||
|
int flags;
|
||||||
|
+
|
||||||
|
+ int depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _xmlRegexp {
|
||||||
|
@@ -5330,6 +5332,10 @@ xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
|
||||||
|
xmlRegStatePtr start, oldend, start0;
|
||||||
|
|
||||||
|
NEXT;
|
||||||
|
+ if (ctxt->depth >= 50) {
|
||||||
|
+ ERROR("xmlFAParseAtom: maximum nesting depth exceeded");
|
||||||
|
+ return(-1);
|
||||||
|
+ }
|
||||||
|
/*
|
||||||
|
* this extra Epsilon transition is needed if we count with 0 allowed
|
||||||
|
* unfortunately this can't be known at that point
|
||||||
|
@@ -5341,7 +5347,9 @@ xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
|
||||||
|
oldend = ctxt->end;
|
||||||
|
ctxt->end = NULL;
|
||||||
|
ctxt->atom = NULL;
|
||||||
|
+ ctxt->depth++;
|
||||||
|
xmlFAParseRegExp(ctxt, 0);
|
||||||
|
+ ctxt->depth--;
|
||||||
|
if (CUR == ')') {
|
||||||
|
NEXT;
|
||||||
|
} else {
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
Summary: Library providing XML and HTML support
|
Summary: Library providing XML and HTML support
|
||||||
Name: libxml2
|
Name: libxml2
|
||||||
Version: 2.9.10
|
Version: 2.9.10
|
||||||
Release: 4
|
Release: 5
|
||||||
License: MIT
|
License: MIT
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
||||||
@ -29,6 +29,8 @@ Patch19: Never-expand-parameter-entities-in-text-declaration.patch
|
|||||||
Patch20: Fix-integer-overflow-in-xmlFAParseQuantExact.patch
|
Patch20: Fix-integer-overflow-in-xmlFAParseQuantExact.patch
|
||||||
Patch21: Report-error-for-invalid-regexp-quantifiers.patch
|
Patch21: Report-error-for-invalid-regexp-quantifiers.patch
|
||||||
Patch22: Add-regexp-regression-tests.patch
|
Patch22: Add-regexp-regression-tests.patch
|
||||||
|
Patch23: Limit-regexp-nesting-depth.patch
|
||||||
|
Patch24: Fix-exponential-runtime-in-xmlFARecurseDeterminism.patch
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||||
BuildRequires: python2-devel
|
BuildRequires: python2-devel
|
||||||
@ -220,6 +222,10 @@ rm -fr %{buildroot}
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Aug 12 2020 Liquor <lirui130@huawei.com> - 2.9.10-5
|
||||||
|
- Limit regexp nesting depth
|
||||||
|
- Fix exponential runtime in xmlFARecurseDeterminism
|
||||||
|
|
||||||
* Mon Aug 3 2020 Liquor <lirui130@huawei.com> - 2.9.10-4
|
* Mon Aug 3 2020 Liquor <lirui130@huawei.com> - 2.9.10-4
|
||||||
- Fix integer overflow in xmlFAParseQuantExact
|
- Fix integer overflow in xmlFAParseQuantExact
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user