Bug#736517: opu: package librsvg/2.26.3-1+deb6u2
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: opu
Hi,
please accept the new version of librsvg to fix a regression in the
previous security upload.
librsvg (2.26.3-1+deb6u2) oldstable; urgency=low
* CVE-2013-1881.policy.patch: updated from Raphaël Geissert. Fix
policy check for non-URIs. Closes: #732144.
Thanks,
--
.''`. Josselin Mouette
: :' :
`. `'
`-
Index: debian/changelog
===================================================================
--- debian/changelog (révision 40429)
+++ debian/changelog (révision 40430)
@@ -1,3 +1,10 @@
+librsvg (2.26.3-1+deb6u2) oldstable; urgency=low
+
+ * CVE-2013-1881.policy.patch: updated from Raphaël Geissert. Fix
+ policy check for non-URIs. Closes: #732144.
+
+ -- Josselin Mouette <joss@debian.org> Fri, 24 Jan 2014 14:55:48 +0100
+
librsvg (2.26.3-1+deb6u1) oldstable; urgency=low
[ Raphaël Geissert ]
Index: debian/patches/CVE-2013-1881.policy.patch
===================================================================
--- debian/patches/CVE-2013-1881.policy.patch (révision 40429)
+++ debian/patches/CVE-2013-1881.policy.patch (révision 40430)
@@ -1,8 +1,32 @@
Index: librsvg-2.26.3/rsvg-image.c
===================================================================
---- librsvg-2.26.3.orig/rsvg-image.c 2013-11-28 12:01:22.865236793 +0100
-+++ librsvg-2.26.3/rsvg-image.c 2013-11-28 12:17:25.242370794 +0100
-@@ -356,6 +356,51 @@ rsvg_acquire_vfs_resource (const char *f
+--- librsvg-2.26.3.orig/rsvg-image.c 2013-12-20 14:28:57.731991069 +0100
++++ librsvg-2.26.3/rsvg-image.c 2013-12-20 14:38:59.384692376 +0100
+@@ -325,22 +325,7 @@ rsvg_acquire_vfs_resource (const char *f
+
+ file = g_file_new_for_uri (filename);
+
+- if (!(res = g_file_load_contents (file, NULL, &data, &size, NULL, error))) {
+- if (base_uri != NULL) {
+- GFile *base;
+-
+- rsvg_free_error (error);
+-
+- g_object_unref (file);
+-
+- base = g_file_new_for_uri (base_uri);
+- file = g_file_resolve_relative_path (base, filename);
+- g_object_unref (base);
+-
+- res = g_file_load_contents (file, NULL, &data, &size, NULL, error);
+- }
+- }
+-
++ res = g_file_load_contents (file, NULL, &data, &size, NULL, error);
+ g_object_unref (file);
+
+ if (res) {
+@@ -356,23 +341,136 @@ rsvg_acquire_vfs_resource (const char *f
}
#endif
@@ -23,7 +47,7 @@
+
+ /* Allow loads of data: from any location */
+ if (g_str_equal (href_scheme, "data"))
-+ return TRUE;
++ goto allow;
+
+ /* no valid base URI */
+ if (base_scheme == NULL)
@@ -35,7 +59,7 @@
+
+ /* resource: is allowed to load anything from other resources */
+ if (g_str_equal (href_scheme, "resource"))
-+ return TRUE;
++ goto allow;
+
+ /* Non-file: isn't allowed to load anything */
+ if (!g_str_equal (href_scheme, "file"))
@@ -43,9 +67,14 @@
+
+ /* no local-file policy is applied here */
+
++allow:
++ free(base_scheme);
++ free(href_scheme);
+ return TRUE;
+
+deny:
++ free(base_scheme);
++ free(href_scheme);
+ g_set_error (err, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ "File may not link to URI \"%s\"", href);
+ return FALSE;
@@ -54,20 +83,94 @@
GByteArray *
_rsvg_acquire_xlink_href_resource (const char *href, const char *base_uri, GError ** err)
{
-@@ -367,6 +412,9 @@ _rsvg_acquire_xlink_href_resource (const
- if (!strncmp (href, "data:", 5))
+ GByteArray *arr = NULL;
++ char *base_scheme = NULL, *href_scheme = NULL;
++ char *href_uri = NULL;
++#ifndef HAVE_GIO
++ /* to be used ONLY for the policy check */
++ GString *href_uri_str = NULL;
++#endif
+
+ if (!(href && *href))
+ return NULL;
+
+- if (!strncmp (href, "data:", 5))
++ if (base_uri)
++ base_scheme = g_uri_parse_scheme (base_uri);
++ if (href)
++ href_scheme = g_uri_parse_scheme (href);
++
++ if (href_scheme && g_str_equal (href_scheme, "data"))
arr = rsvg_acquire_base64_resource (href, NULL);
++ if (arr)
++ goto done;
-+ if (!_rsvg_acquire_xlink_allow_load(href, base_uri, err))
-+ return NULL;
+- if (!arr)
++#ifdef HAVE_GIO
++ /* if href is not a URI already, turn it into one based on base_uri */
++ if (href_scheme == NULL) {
++ GFile *file, *base, *parentless_base;
++ base = g_file_new_for_uri (base_uri);
++ /* now strip the file name: */
++ parentless_base = g_file_get_parent (base);
++ file = g_file_resolve_relative_path (parentless_base, href);
+
- if (!arr)
++ g_object_unref (base);
++ g_object_unref (parentless_base);
++ href_uri = g_file_get_uri(file);
++ g_object_unref (file);
++ } else {
++ href_uri = strdup (href);
++ if (!href_uri) /* FIXME: better handling failure */
++ goto done;
++ }
++#else
++ if (href_scheme == NULL) {
++ href_uri_str = g_string_new(href);
++ if (base_scheme) {
++ /* try to turn href into a uri */
++ g_string_prepend (href_uri_str, "://");
++ g_string_prepend (href_uri_str, base_scheme);
++ /* no need to free, as href_scheme is NULL, remember? */
++ href_scheme = strdup (base_scheme);
++ if (!href_scheme) /* FIXME: better handling failure */
++ goto done;
++ } else
++ goto done;
++ } else {
++ href_uri_str = g_string_new(href);
++ }
++ href_uri = href_uri_str->str;
++#endif
++
++ if (!_rsvg_acquire_xlink_allow_load(href_uri, base_uri, err))
++ goto done;
++
++#ifdef HAVE_GIO
++ arr = rsvg_acquire_vfs_resource (href_uri, base_uri, NULL);
++#else
++ /* href must be a path for fopen() to work */
++ if (g_str_equal (href_scheme, "file"))
arr = rsvg_acquire_file_resource (href, base_uri, NULL);
++#endif
++
++done:
++ free(href_scheme);
++ free(base_scheme);
+ #ifdef HAVE_GIO
+- if (!arr)
+- arr = rsvg_acquire_vfs_resource (href, base_uri, NULL);
++ g_free(href_uri);
++#else
++ g_string_free (href_uri_str, TRUE);
+ #endif
+
+ return arr;
Index: librsvg-2.26.3/rsvg-base.c
===================================================================
---- librsvg-2.26.3.orig/rsvg-base.c 2013-11-28 12:01:22.865236793 +0100
-+++ librsvg-2.26.3/rsvg-base.c 2013-11-28 12:13:54.913248784 +0100
+--- librsvg-2.26.3.orig/rsvg-base.c 2013-12-20 14:28:57.731991069 +0100
++++ librsvg-2.26.3/rsvg-base.c 2013-12-20 14:37:44.868110116 +0100
@@ -1049,12 +1049,13 @@ rsvg_handle_set_base_uri (RsvgHandle * h
else
uri = rsvg_get_base_uri_from_filename (base_uri);
@@ -88,3 +191,41 @@
}
/**
+Index: librsvg-2.26.3/rsvg-base-file-util.c
+===================================================================
+--- librsvg-2.26.3.orig/rsvg-base-file-util.c 2013-12-20 14:28:57.731991069 +0100
++++ librsvg-2.26.3/rsvg-base-file-util.c 2013-12-20 14:37:44.868110116 +0100
+@@ -87,11 +87,23 @@ rsvg_handle_new_from_file (const gchar *
+ gchar *base_uri;
+ GByteArray *f;
+ RsvgHandle *handle = NULL;
++ char *base_scheme;
++ gchar *final_file_name = NULL;
+
+ rsvg_return_val_if_fail (file_name != NULL, NULL, error);
+
+- base_uri = rsvg_get_base_uri_from_filename (file_name);
+- f = _rsvg_acquire_xlink_href_resource (file_name, base_uri, error);
++ /* turn the file name/path into a URI if it is not one already */
++ base_scheme = g_uri_parse_scheme (file_name);
++ if (base_scheme) {
++ free (base_scheme);
++ base_scheme = 0;
++ base_uri = g_strdup (file_name);
++ final_file_name = g_strdup (file_name);
++ } else {
++ base_uri = rsvg_get_base_uri_from_filename (file_name);
++ final_file_name = g_path_get_basename (file_name);
++ }
++ f = _rsvg_acquire_xlink_href_resource (final_file_name, base_uri, error);
+
+ if (f) {
+ handle = rsvg_handle_new ();
+@@ -106,6 +118,7 @@ rsvg_handle_new_from_file (const gchar *
+ }
+
+ g_free (base_uri);
++ g_free (final_file_name);
+
+ return handle;
+ }
Index: librsvg-2.26.3/rsvg-image.c
===================================================================
--- librsvg-2.26.3.orig/rsvg-image.c 2013-12-20 14:28:57.731991069 +0100
+++ librsvg-2.26.3/rsvg-image.c 2013-12-20 14:38:59.384692376 +0100
@@ -325,22 +325,7 @@ rsvg_acquire_vfs_resource (const char *f
file = g_file_new_for_uri (filename);
- if (!(res = g_file_load_contents (file, NULL, &data, &size, NULL, error))) {
- if (base_uri != NULL) {
- GFile *base;
-
- rsvg_free_error (error);
-
- g_object_unref (file);
-
- base = g_file_new_for_uri (base_uri);
- file = g_file_resolve_relative_path (base, filename);
- g_object_unref (base);
-
- res = g_file_load_contents (file, NULL, &data, &size, NULL, error);
- }
- }
-
+ res = g_file_load_contents (file, NULL, &data, &size, NULL, error);
g_object_unref (file);
if (res) {
@@ -356,23 +341,136 @@ rsvg_acquire_vfs_resource (const char *f
}
#endif
+/* Partial origin-based policy, based on the one implemented in f01aded72c38f0e1 */
+gboolean
+_rsvg_acquire_xlink_allow_load (const char *href, const char *base_uri, GError ** err)
+{
+ char *base_scheme = NULL, *href_scheme = NULL;
+
+ if (base_uri)
+ base_scheme = g_uri_parse_scheme (base_uri);
+ if (href)
+ href_scheme = g_uri_parse_scheme (href);
+
+ /* Not a valid URI */
+ if (href_scheme == NULL)
+ goto deny;
+
+ /* Allow loads of data: from any location */
+ if (g_str_equal (href_scheme, "data"))
+ goto allow;
+
+ /* no valid base URI */
+ if (base_scheme == NULL)
+ goto deny;
+
+ /* Deny loads from differing URI schemes */
+ if (href_scheme == NULL || !g_str_equal (href_scheme, base_scheme))
+ goto deny;
+
+ /* resource: is allowed to load anything from other resources */
+ if (g_str_equal (href_scheme, "resource"))
+ goto allow;
+
+ /* Non-file: isn't allowed to load anything */
+ if (!g_str_equal (href_scheme, "file"))
+ goto deny;
+
+ /* no local-file policy is applied here */
+
+allow:
+ free(base_scheme);
+ free(href_scheme);
+ return TRUE;
+
+deny:
+ free(base_scheme);
+ free(href_scheme);
+ g_set_error (err, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ "File may not link to URI \"%s\"", href);
+ return FALSE;
+}
+
GByteArray *
_rsvg_acquire_xlink_href_resource (const char *href, const char *base_uri, GError ** err)
{
GByteArray *arr = NULL;
+ char *base_scheme = NULL, *href_scheme = NULL;
+ char *href_uri = NULL;
+#ifndef HAVE_GIO
+ /* to be used ONLY for the policy check */
+ GString *href_uri_str = NULL;
+#endif
if (!(href && *href))
return NULL;
- if (!strncmp (href, "data:", 5))
+ if (base_uri)
+ base_scheme = g_uri_parse_scheme (base_uri);
+ if (href)
+ href_scheme = g_uri_parse_scheme (href);
+
+ if (href_scheme && g_str_equal (href_scheme, "data"))
arr = rsvg_acquire_base64_resource (href, NULL);
+ if (arr)
+ goto done;
- if (!arr)
+#ifdef HAVE_GIO
+ /* if href is not a URI already, turn it into one based on base_uri */
+ if (href_scheme == NULL) {
+ GFile *file, *base, *parentless_base;
+ base = g_file_new_for_uri (base_uri);
+ /* now strip the file name: */
+ parentless_base = g_file_get_parent (base);
+ file = g_file_resolve_relative_path (parentless_base, href);
+
+ g_object_unref (base);
+ g_object_unref (parentless_base);
+ href_uri = g_file_get_uri(file);
+ g_object_unref (file);
+ } else {
+ href_uri = strdup (href);
+ if (!href_uri) /* FIXME: better handling failure */
+ goto done;
+ }
+#else
+ if (href_scheme == NULL) {
+ href_uri_str = g_string_new(href);
+ if (base_scheme) {
+ /* try to turn href into a uri */
+ g_string_prepend (href_uri_str, "://");
+ g_string_prepend (href_uri_str, base_scheme);
+ /* no need to free, as href_scheme is NULL, remember? */
+ href_scheme = strdup (base_scheme);
+ if (!href_scheme) /* FIXME: better handling failure */
+ goto done;
+ } else
+ goto done;
+ } else {
+ href_uri_str = g_string_new(href);
+ }
+ href_uri = href_uri_str->str;
+#endif
+
+ if (!_rsvg_acquire_xlink_allow_load(href_uri, base_uri, err))
+ goto done;
+
+#ifdef HAVE_GIO
+ arr = rsvg_acquire_vfs_resource (href_uri, base_uri, NULL);
+#else
+ /* href must be a path for fopen() to work */
+ if (g_str_equal (href_scheme, "file"))
arr = rsvg_acquire_file_resource (href, base_uri, NULL);
+#endif
+
+done:
+ free(href_scheme);
+ free(base_scheme);
#ifdef HAVE_GIO
- if (!arr)
- arr = rsvg_acquire_vfs_resource (href, base_uri, NULL);
+ g_free(href_uri);
+#else
+ g_string_free (href_uri_str, TRUE);
#endif
return arr;
Index: librsvg-2.26.3/rsvg-base.c
===================================================================
--- librsvg-2.26.3.orig/rsvg-base.c 2013-12-20 14:28:57.731991069 +0100
+++ librsvg-2.26.3/rsvg-base.c 2013-12-20 14:37:44.868110116 +0100
@@ -1049,12 +1049,13 @@ rsvg_handle_set_base_uri (RsvgHandle * h
else
uri = rsvg_get_base_uri_from_filename (base_uri);
- if (uri) {
- if (handle->priv->base_uri)
- g_free (handle->priv->base_uri);
- handle->priv->base_uri = uri;
- rsvg_defs_set_base_uri (handle->priv->defs, handle->priv->base_uri);
- }
+ if (!uri)
+ uri = g_strdup("data:");
+
+ if (handle->priv->base_uri)
+ g_free (handle->priv->base_uri);
+ handle->priv->base_uri = uri;
+ rsvg_defs_set_base_uri (handle->priv->defs, handle->priv->base_uri);
}
/**
Index: librsvg-2.26.3/rsvg-base-file-util.c
===================================================================
--- librsvg-2.26.3.orig/rsvg-base-file-util.c 2013-12-20 14:28:57.731991069 +0100
+++ librsvg-2.26.3/rsvg-base-file-util.c 2013-12-20 14:37:44.868110116 +0100
@@ -87,11 +87,23 @@ rsvg_handle_new_from_file (const gchar *
gchar *base_uri;
GByteArray *f;
RsvgHandle *handle = NULL;
+ char *base_scheme;
+ gchar *final_file_name = NULL;
rsvg_return_val_if_fail (file_name != NULL, NULL, error);
- base_uri = rsvg_get_base_uri_from_filename (file_name);
- f = _rsvg_acquire_xlink_href_resource (file_name, base_uri, error);
+ /* turn the file name/path into a URI if it is not one already */
+ base_scheme = g_uri_parse_scheme (file_name);
+ if (base_scheme) {
+ free (base_scheme);
+ base_scheme = 0;
+ base_uri = g_strdup (file_name);
+ final_file_name = g_strdup (file_name);
+ } else {
+ base_uri = rsvg_get_base_uri_from_filename (file_name);
+ final_file_name = g_path_get_basename (file_name);
+ }
+ f = _rsvg_acquire_xlink_href_resource (final_file_name, base_uri, error);
if (f) {
handle = rsvg_handle_new ();
@@ -106,6 +118,7 @@ rsvg_handle_new_from_file (const gchar *
}
g_free (base_uri);
+ g_free (final_file_name);
return handle;
}
Reply to: