[librsvg/librsvg-2.42: 6/8] Limit the number of loaded elements
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.42: 6/8] Limit the number of loaded elements
- Date: Tue, 25 Feb 2020 23:15:35 +0000 (UTC)
commit 61945d663bdeacf72aa74dc6dd74a9302b337234
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Feb 25 14:48:16 2020 -0600
Limit the number of loaded elements
To avoid unbounded memory consumption from malicious files.
librsvg/rsvg-base.c | 18 +++++++++++++++++
librsvg/rsvg-private.h | 1 +
tests/errors.c | 24 +++++++++++++++++++++++
tests/fixtures/errors/515-too-many-elements.svgz | Bin 0 -> 40811 bytes
4 files changed, 43 insertions(+)
---
diff --git a/librsvg/rsvg-base.c b/librsvg/rsvg-base.c
index 8b8ba25d..1995a20b 100644
--- a/librsvg/rsvg-base.c
+++ b/librsvg/rsvg-base.c
@@ -431,12 +431,29 @@ node_set_atts (RsvgNode * node, RsvgHandle *handle, const NodeCreator *creator,
}
}
+static gboolean
+loading_limits_exceeded (RsvgHandle *handle)
+{
+ /* This is a mitigation for SVG files which create millions of elements
+ * in an attempt to exhaust memory. We don't allow loading more than
+ * this number of elements during the initial streaming load process.
+ */
+ return handle->priv->num_loaded_elements > 200000;
+}
+
static void
rsvg_standard_element_start (RsvgHandle *handle, const char *name, RsvgPropertyBag * atts)
{
const NodeCreator *creator;
RsvgNode *newnode = NULL;
+ if (loading_limits_exceeded (handle)) {
+ g_set_error (handle->priv->error, RSVG_ERROR, 0, "instancing limit");
+
+ xmlStopParser (handle->priv->ctxt);
+ return;
+ }
+
creator = get_node_creator_for_element_name (name);
g_assert (creator != NULL && creator->create_fn != NULL);
@@ -456,6 +473,7 @@ rsvg_standard_element_start (RsvgHandle *handle, const char *name, RsvgPropertyB
handle->priv->treebase = rsvg_node_ref (newnode);
}
+ handle->priv->num_loaded_elements += 1;
handle->priv->currentnode = rsvg_node_ref (newnode);
node_set_atts (newnode, handle, creator, atts);
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index c9aba05e..06f4c2b7 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -164,6 +164,7 @@ struct RsvgHandlePrivate {
*/
RsvgSaxHandler *handler;
int handler_nest;
+ gsize num_loaded_elements;
GHashTable *entities; /* g_malloc'd string -> xmlEntityPtr */
diff --git a/tests/errors.c b/tests/errors.c
index fba3f5fc..ab5898a8 100644
--- a/tests/errors.c
+++ b/tests/errors.c
@@ -22,6 +22,24 @@ get_test_filename (const char *basename) {
basename,
NULL);
}
+
+static void
+test_loading_error (gconstpointer data)
+{
+ const char *basename = data;
+ char *filename = get_test_filename (basename);
+ RsvgHandle *handle;
+ GError *error = NULL;
+
+ handle = rsvg_handle_new_from_file (filename, &error);
+ g_free (filename);
+
+ g_assert (handle == NULL);
+ g_assert (g_error_matches (error, RSVG_ERROR, RSVG_ERROR_FAILED));
+
+ g_error_free (error);
+}
+
static void
test_instancing_limit (gconstpointer data)
{
@@ -73,5 +91,11 @@ main (int argc, char **argv)
test_instancing_limit,
NULL);
+ g_test_add_data_func_full ("/errors/515-too-many-elements.svgz",
+ "515-too-many-elements.svgz",
+ test_loading_error,
+ NULL);
+
+
return g_test_run ();
}
diff --git a/tests/fixtures/errors/515-too-many-elements.svgz
b/tests/fixtures/errors/515-too-many-elements.svgz
new file mode 100644
index 00000000..a7f7cf67
Binary files /dev/null and b/tests/fixtures/errors/515-too-many-elements.svgz differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]