Package: release.debian.org Severity: normal User: release.debian....@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 <j...@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; }