head 1.2; access; symbols pkgsrc-2013Q3:1.1.0.2; locks; strict; comment @# @; 1.2 date 2013.12.10.00.25.18; author prlw1; state dead; branches; next 1.1; commitid QSVrYsDRrPylgwgx; 1.1 date 2013.10.03.13.39.12; author tez; state Exp; branches 1.1.2.1; next ; commitid ZEx4sgWqcHISPQ7x; 1.1.2.1 date 2013.10.03.13.39.12; author tron; state dead; branches; next 1.1.2.2; commitid 7a98B6jcicFklE8x; 1.1.2.2 date 2013.10.09.18.44.39; author tron; state Exp; branches; next ; commitid 7a98B6jcicFklE8x; desc @@ 1.2 log @Rerevert librsvg update to 2.40.1 @ text @$NetBSD: patch-CVE-2013-1881,v 1.1 2013/10/03 13:39:12 tez Exp $ from https://git.gnome.org/browse/librsvg/patch/?id=f01aded72c38f0e18bc7ff67dee800e380251c8e From f01aded72c38f0e18bc7ff67dee800e380251c8e Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Mon, 11 Feb 2013 21:36:58 +0000 Subject: io: Implement strict load policy Allow any file to load from data:, and any resource to load from other resources. Only allow file: to load other file: URIs from below the path of the base file. Any other loads are denied. Bug #691708. --- diff --git a/rsvg-base.c b/rsvg-base.c index 1f88479..9d7c1ea 100644 --- rsvg-base.c.orig 2013-10-03 07:33:50.579625000 -0500 +++ rsvg-base.c 2013-10-03 07:35:26.518496200 -0500 @@@@ -25,6 +25,7 @@@@ */ #include "config.h" +#define _GNU_SOURCE 1 #include "rsvg.h" #include "rsvg-private.h" @@@@ -1001,6 +1002,7 @@@@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri) { gchar *uri; + GFile *file; g_return_if_fail (handle != NULL); @@@@ -1012,11 +1014,10 @@@@ 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; - } + file = g_file_new_for_uri (uri ? uri : "data:"); + rsvg_handle_set_base_gfile (handle, file); + g_object_unref (file); + g_free (uri); } /** @@@@ -2146,12 +2147,79 @@@@ const char *uri, GError **error) { - RsvgLoadPolicy policy = handle->priv->load_policy; + RsvgHandlePrivate *priv = handle->priv; + GFile *base; + char *path, *dir; + char *scheme = NULL, *cpath = NULL, *cdir = NULL; + char cpath_buffer[PATH_MAX], cdir_buffer[PATH_MAX]; - if (policy == RSVG_LOAD_POLICY_ALL_PERMISSIVE) - return TRUE; + g_assert (handle->priv->load_policy == RSVG_LOAD_POLICY_STRICT); + + scheme = g_uri_parse_scheme (uri); + + /* Not a valid URI */ + if (scheme == NULL) + goto deny; + + /* Allow loads of data: from any location */ + if (g_str_equal (scheme, "data")) + goto allow; + + /* No base to compare to? */ + if (priv->base_gfile == NULL) + goto deny; + + /* Deny loads from differing URI schemes */ + if (!g_file_has_uri_scheme (priv->base_gfile, scheme)) + goto deny; + + /* resource: is allowed to load anything from other resources */ + if (g_str_equal (scheme, "resource")) + goto allow; + /* Non-file: isn't allowed to load anything */ + if (!g_str_equal (scheme, "file")) + goto deny; + + base = g_file_get_parent (priv->base_gfile); + if (base == NULL) + goto deny; + + dir = g_file_get_path (base); + g_object_unref (base); + + cdir = realpath (dir,cdir_buffer); + g_free (dir); + if (cdir == NULL) + goto deny; + + path = g_filename_from_uri (uri, NULL, NULL); + if (path == NULL) + goto deny; + + cpath = realpath (path, cpath_buffer); + g_free (path); + + if (cpath == NULL) + goto deny; + + /* Now check that @@cpath is below @@cdir */ + if (!g_str_has_prefix (cpath, cdir) || + cpath[strlen (cdir)] != G_DIR_SEPARATOR) + goto deny; + + /* Allow load! */ + + allow: + g_free (scheme); return TRUE; + + deny: + g_free (scheme); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, + "File may not link to URI \"%s\"", uri); + return FALSE; } guint8* diff --git a/rsvg-io.c b/rsvg-io.c index 3d6c8b5..818d2ec 100644 --- rsvg-io.c +++ rsvg-io.c @@@@ -79,7 +79,7 @@@@ rsvg_acquire_data_data (const char *uri, gboolean base64 = FALSE; g_assert (out_len != NULL); - g_assert (g_str_has_prefix (uri, "data:")); + g_assert (strncmp (uri, "data:", 5) == 0); mime_type = NULL; start = uri + 5; diff --git a/rsvg-private.h b/rsvg-private.h index 25283d4..1961eaf 100644 --- rsvg-private.h +++ rsvg-private.h @@@@ -123,10 +123,10 @@@@ struct RsvgSaxHandler { }; typedef enum { - RSVG_LOAD_POLICY_ALL_PERMISSIVE + RSVG_LOAD_POLICY_STRICT } RsvgLoadPolicy; -#define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_ALL_PERMISSIVE) +#define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_STRICT) struct RsvgHandlePrivate { RsvgHandleFlags flags; -- cgit v0.9.2 @ 1.1 log @Fix for CVE-2013-1881 (SA55088) Modified (for portability) from https://git.gnome.org/browse/librsvg/patch/?id=f01aded72c38f0e18bc7ff67dee800e380251c8e @ text @d1 1 a1 1 $NetBSD$ @ 1.1.2.1 log @file patch-CVE-2013-1881 was added on branch pkgsrc-2013Q3 on 2013-10-09 18:44:39 +0000 @ text @d1 166 @ 1.1.2.2 log @Pullup ticket #4241 - requested by tez graphics/librsvg: security patch Revisions pulled up: - graphics/librsvg/Makefile 1.74 - graphics/librsvg/distinfo 1.26 - graphics/librsvg/patches/patch-CVE-2013-1881 1.1 --- Module Name: pkgsrc Committed By: tez Date: Thu Oct 3 13:39:13 UTC 2013 Modified Files: pkgsrc/graphics/librsvg: Makefile distinfo Added Files: pkgsrc/graphics/librsvg/patches: patch-CVE-2013-1881 Log Message: Fix for CVE-2013-1881 (SA55088) Modified (for portability) from https://git.gnome.org/browse/librsvg/patch/?id=f01aded72c38f0e18bc7ff67dee800e380251c8e @ text @a0 166 $NetBSD$ from https://git.gnome.org/browse/librsvg/patch/?id=f01aded72c38f0e18bc7ff67dee800e380251c8e From f01aded72c38f0e18bc7ff67dee800e380251c8e Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Mon, 11 Feb 2013 21:36:58 +0000 Subject: io: Implement strict load policy Allow any file to load from data:, and any resource to load from other resources. Only allow file: to load other file: URIs from below the path of the base file. Any other loads are denied. Bug #691708. --- diff --git a/rsvg-base.c b/rsvg-base.c index 1f88479..9d7c1ea 100644 --- rsvg-base.c.orig 2013-10-03 07:33:50.579625000 -0500 +++ rsvg-base.c 2013-10-03 07:35:26.518496200 -0500 @@@@ -25,6 +25,7 @@@@ */ #include "config.h" +#define _GNU_SOURCE 1 #include "rsvg.h" #include "rsvg-private.h" @@@@ -1001,6 +1002,7 @@@@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri) { gchar *uri; + GFile *file; g_return_if_fail (handle != NULL); @@@@ -1012,11 +1014,10 @@@@ 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; - } + file = g_file_new_for_uri (uri ? uri : "data:"); + rsvg_handle_set_base_gfile (handle, file); + g_object_unref (file); + g_free (uri); } /** @@@@ -2146,12 +2147,79 @@@@ const char *uri, GError **error) { - RsvgLoadPolicy policy = handle->priv->load_policy; + RsvgHandlePrivate *priv = handle->priv; + GFile *base; + char *path, *dir; + char *scheme = NULL, *cpath = NULL, *cdir = NULL; + char cpath_buffer[PATH_MAX], cdir_buffer[PATH_MAX]; - if (policy == RSVG_LOAD_POLICY_ALL_PERMISSIVE) - return TRUE; + g_assert (handle->priv->load_policy == RSVG_LOAD_POLICY_STRICT); + + scheme = g_uri_parse_scheme (uri); + + /* Not a valid URI */ + if (scheme == NULL) + goto deny; + + /* Allow loads of data: from any location */ + if (g_str_equal (scheme, "data")) + goto allow; + + /* No base to compare to? */ + if (priv->base_gfile == NULL) + goto deny; + + /* Deny loads from differing URI schemes */ + if (!g_file_has_uri_scheme (priv->base_gfile, scheme)) + goto deny; + + /* resource: is allowed to load anything from other resources */ + if (g_str_equal (scheme, "resource")) + goto allow; + /* Non-file: isn't allowed to load anything */ + if (!g_str_equal (scheme, "file")) + goto deny; + + base = g_file_get_parent (priv->base_gfile); + if (base == NULL) + goto deny; + + dir = g_file_get_path (base); + g_object_unref (base); + + cdir = realpath (dir,cdir_buffer); + g_free (dir); + if (cdir == NULL) + goto deny; + + path = g_filename_from_uri (uri, NULL, NULL); + if (path == NULL) + goto deny; + + cpath = realpath (path, cpath_buffer); + g_free (path); + + if (cpath == NULL) + goto deny; + + /* Now check that @@cpath is below @@cdir */ + if (!g_str_has_prefix (cpath, cdir) || + cpath[strlen (cdir)] != G_DIR_SEPARATOR) + goto deny; + + /* Allow load! */ + + allow: + g_free (scheme); return TRUE; + + deny: + g_free (scheme); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, + "File may not link to URI \"%s\"", uri); + return FALSE; } guint8* diff --git a/rsvg-io.c b/rsvg-io.c index 3d6c8b5..818d2ec 100644 --- rsvg-io.c +++ rsvg-io.c @@@@ -79,7 +79,7 @@@@ rsvg_acquire_data_data (const char *uri, gboolean base64 = FALSE; g_assert (out_len != NULL); - g_assert (g_str_has_prefix (uri, "data:")); + g_assert (strncmp (uri, "data:", 5) == 0); mime_type = NULL; start = uri + 5; diff --git a/rsvg-private.h b/rsvg-private.h index 25283d4..1961eaf 100644 --- rsvg-private.h +++ rsvg-private.h @@@@ -123,10 +123,10 @@@@ struct RsvgSaxHandler { }; typedef enum { - RSVG_LOAD_POLICY_ALL_PERMISSIVE + RSVG_LOAD_POLICY_STRICT } RsvgLoadPolicy; -#define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_ALL_PERMISSIVE) +#define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_STRICT) struct RsvgHandlePrivate { RsvgHandleFlags flags; -- cgit v0.9.2 @