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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
From 2304078555896cf1638c628f50326aeef6f0e0d0 Mon Sep 17 00:00:00 2001
From: Doran Moppert <dmoppert@redhat.com>
Date: Fri, 7 Apr 2017 16:45:56 +0200
Subject: Add an XML_PARSE_NOXXE flag to block all entities loading even local
For https://bugzilla.gnome.org/show_bug.cgi?id=772726
* include/libxml/parser.h: Add a new parser flag XML_PARSE_NOXXE
* elfgcchack.h, xmlIO.h, xmlIO.c: associated loading routine
* include/libxml/xmlerror.h: new error raised
* xmllint.c: adds --noxxe flag to activate the option
---
elfgcchack.h | 10 ++++++++++
include/libxml/parser.h | 3 ++-
include/libxml/xmlIO.h | 8 ++++++++
include/libxml/xmlerror.h | 1 +
parser.c | 4 ++++
xmlIO.c | 40 +++++++++++++++++++++++++++++++++++-----
xmllint.c | 5 +++++
7 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/elfgcchack.h b/elfgcchack.h
index 8c52884..1b81dcd 100644
--- a/elfgcchack.h
+++ b/elfgcchack.h
@@ -6547,6 +6547,16 @@ extern __typeof (xmlNoNetExternalEntityLoader) xmlNoNetExternalEntityLoader__int
#endif
#endif
+#ifdef bottom_xmlIO
+#undef xmlNoXxeExternalEntityLoader
+extern __typeof (xmlNoXxeExternalEntityLoader) xmlNoXxeExternalEntityLoader __attribute((alias("xmlNoXxeExternalEntityLoader__internal_alias")));
+#else
+#ifndef xmlNoXxeExternalEntityLoader
+extern __typeof (xmlNoXxeExternalEntityLoader) xmlNoXxeExternalEntityLoader__internal_alias __attribute((visibility("hidden")));
+#define xmlNoXxeExternalEntityLoader xmlNoXxeExternalEntityLoader__internal_alias
+#endif
+#endif
+
#ifdef bottom_tree
#undef xmlNodeAddContent
extern __typeof (xmlNodeAddContent) xmlNodeAddContent __attribute((alias("xmlNodeAddContent__internal_alias")));
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 47fbec0..63ca1b9 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -1111,7 +1111,8 @@ typedef enum {
XML_PARSE_HUGE = 1<<19,/* relax any hardcoded limit from the parser */
XML_PARSE_OLDSAX = 1<<20,/* parse using SAX2 interface before 2.7.0 */
XML_PARSE_IGNORE_ENC= 1<<21,/* ignore internal document encoding hint */
- XML_PARSE_BIG_LINES = 1<<22 /* Store big lines numbers in text PSVI field */
+ XML_PARSE_BIG_LINES = 1<<22,/* Store big lines numbers in text PSVI field */
+ XML_PARSE_NOXXE = 1<<23 /* Forbid any external entity loading */
} xmlParserOption;
XMLPUBFUN void XMLCALL
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 3e41744..8d3fdef 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -300,6 +300,14 @@ XMLPUBFUN xmlParserInputPtr XMLCALL
xmlParserCtxtPtr ctxt);
/*
+ * A predefined entity loader external entity expansion
+ */
+XMLPUBFUN xmlParserInputPtr XMLCALL
+ xmlNoXxeExternalEntityLoader (const char *URL,
+ const char *ID,
+ xmlParserCtxtPtr ctxt);
+
+/*
* xmlNormalizeWindowsPath is obsolete, don't use it.
* Check xmlCanonicPath in uri.h for a better alternative.
*/
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 037c16d..3036062 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -470,6 +470,7 @@ typedef enum {
XML_IO_EADDRINUSE, /* 1554 */
XML_IO_EALREADY, /* 1555 */
XML_IO_EAFNOSUPPORT, /* 1556 */
+ XML_IO_ILLEGAL_XXE, /* 1557 */
XML_XINCLUDE_RECURSION=1600,
XML_XINCLUDE_PARSE_VALUE, /* 1601 */
XML_XINCLUDE_ENTITY_DEF_MISMATCH, /* 1602 */
diff --git a/parser.c b/parser.c
index 53a6b7f..609a270 100644
--- a/parser.c
+++ b/parser.c
@@ -15350,6 +15350,10 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi
ctxt->options |= XML_PARSE_NONET;
options -= XML_PARSE_NONET;
}
+ if (options & XML_PARSE_NOXXE) {
+ ctxt->options |= XML_PARSE_NOXXE;
+ options -= XML_PARSE_NOXXE;
+ }
if (options & XML_PARSE_COMPACT) {
ctxt->options |= XML_PARSE_COMPACT;
options -= XML_PARSE_COMPACT;
diff --git a/xmlIO.c b/xmlIO.c
index 300ee47..e625612 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -210,6 +210,7 @@ static const char *IOerr[] = {
"adddress in use", /* EADDRINUSE */
"already in use", /* EALREADY */
"unknown address familly", /* EAFNOSUPPORT */
+ "Attempt to load external entity %s", /* XML_IO_ILLEGAL_XXE */
};
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
@@ -4053,13 +4054,22 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
xmlGenericError(xmlGenericErrorContext,
"xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
#endif
- if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
+ if (ctxt != NULL) {
int options = ctxt->options;
- ctxt->options -= XML_PARSE_NONET;
- ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
- ctxt->options = options;
- return(ret);
+ if (options & XML_PARSE_NOXXE) {
+ ctxt->options -= XML_PARSE_NOXXE;
+ ret = xmlNoXxeExternalEntityLoader(URL, ID, ctxt);
+ ctxt->options = options;
+ return(ret);
+ }
+
+ if (options & XML_PARSE_NONET) {
+ ctxt->options -= XML_PARSE_NONET;
+ ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+ ctxt->options = options;
+ return(ret);
+ }
}
#ifdef LIBXML_CATALOG_ENABLED
resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
@@ -4160,6 +4170,13 @@ xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
xmlParserInputPtr input = NULL;
xmlChar *resource = NULL;
+ if (ctxt == NULL) {
+ return(NULL);
+ }
+ if (ctxt->input_id == 1) {
+ return xmlDefaultExternalEntityLoader((const char *) URL, ID, ctxt);
+ }
+
#ifdef LIBXML_CATALOG_ENABLED
resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
#endif
@@ -4182,5 +4199,18 @@ xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
return(input);
}
+xmlParserInputPtr
+xmlNoXxeExternalEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ if (ctxt == NULL) {
+ return(NULL);
+ }
+ if (ctxt->input_id == 1) {
+ return xmlDefaultExternalEntityLoader((const char *) URL, ID, ctxt);
+ }
+ xmlIOErr(XML_IO_ILLEGAL_XXE, (const char *) URL);
+ return(NULL);
+}
+
#define bottom_xmlIO
#include "elfgcchack.h"
diff --git a/xmllint.c b/xmllint.c
index 67f7adb..d9368c1 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -3019,6 +3019,7 @@ static void usage(const char *name) {
printf("\t--path 'paths': provide a set of paths for resources\n");
printf("\t--load-trace : print trace of all external entities loaded\n");
printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
+ printf("\t--noxxe : forbid any external entity loading\n");
printf("\t--nocompact : do not generate compact text nodes\n");
printf("\t--htmlout : output results as HTML\n");
printf("\t--nowrap : do not put HTML doc wrapper\n");
@@ -3461,6 +3462,10 @@ main(int argc, char **argv) {
(!strcmp(argv[i], "--nonet"))) {
options |= XML_PARSE_NONET;
xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
+ } else if ((!strcmp(argv[i], "-noxxe")) ||
+ (!strcmp(argv[i], "--noxxe"))) {
+ options |= XML_PARSE_NOXXE;
+ xmlSetExternalEntityLoader(xmlNoXxeExternalEntityLoader);
} else if ((!strcmp(argv[i], "-nocompact")) ||
(!strcmp(argv[i], "--nocompact"))) {
options &= ~XML_PARSE_COMPACT;
--
cgit v0.12
|