[librsvg] io: Implement strict load policy
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] io: Implement strict load policy
- Date: Fri, 16 Aug 2013 12:49:15 +0000 (UTC)
commit f01aded72c38f0e18bc7ff67dee800e380251c8e
Author: Christian Persch <chpe gnome org>
Date: Mon Feb 11 22:36:58 2013 +0100
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.
rsvg-base.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
rsvg-io.c | 2 +-
rsvg-private.h | 4 +-
3 files changed, 84 insertions(+), 11 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 1f88479..9d7c1ea 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -25,6 +25,7 @@
*/
#include "config.h"
+#define _GNU_SOURCE 1
#include "rsvg.h"
#include "rsvg-private.h"
@@ -1002,6 +1003,7 @@ void
rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
{
gchar *uri;
+ GFile *file;
g_return_if_fail (handle != NULL);
@@ -1013,11 +1015,10 @@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
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);
}
/**
@@ -2149,12 +2150,84 @@ _rsvg_handle_allow_load (RsvgHandle *handle,
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;
- 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);
+
+ /* FIXME portability */
+ cdir = canonicalize_file_name (dir);
+ g_free (dir);
+ if (cdir == NULL)
+ goto deny;
+
+ path = g_filename_from_uri (uri, NULL, NULL);
+ if (path == NULL)
+ goto deny;
+
+ /* FIXME portability */
+ cpath = canonicalize_file_name (path);
+ 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);
+ free (cpath);
+ free (cdir);
return TRUE;
+
+ deny:
+ g_free (scheme);
+ free (cpath);
+ free (cdir);
+
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ "File may not link to URI \"%s\"", uri);
+ return FALSE;
}
static char *
diff --git a/rsvg-io.c b/rsvg-io.c
index 3d6c8b5..818d2ec 100644
--- a/rsvg-io.c
+++ b/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
--- a/rsvg-private.h
+++ b/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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]