summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Kitt <steve@sk2.org>2015-01-05 06:28:00 +0000
committerMarc-André Lureau <marcandre.lureau@gmail.com>2015-01-05 10:53:01 +0100
commit0ccdf564b6a3e26522a8eb1858f1828844fa3536 (patch)
tree0b940321bdacac2985ef94cb8383b8a880097108
parent228998c9b4b4670ff35114b9bec6abeb335382fe (diff)
downloadgcab-0ccdf564b6a3e26522a8eb1858f1828844fa3536.tar.gz
Avoid path traversal
gcab suffers from a directory traversal bug: it doesn't filter leading slashes from paths in CAB files. (see https://bugs.debian.org/774580) The attached patch fixes this, at the cost of ugly paths when faced with relative traversals. At least all the CAB's contents can be extracted, without overwriting anything outside the extraction path. https://bugzilla.gnome.org/show_bug.cgi?id=742331
-rw-r--r--libgcab/gcab-folder.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/libgcab/gcab-folder.c b/libgcab/gcab-folder.c
index a140e2c..9510cf3 100644
--- a/libgcab/gcab-folder.c
+++ b/libgcab/gcab-folder.c
@@ -362,9 +362,25 @@ gcab_folder_extract (GCabFolder *self,
fname[i] = '/';
GFile *gfile = g_file_resolve_relative_path (path, fname);
- GFile *parent = g_file_get_parent (gfile);
g_free (fname);
+ if (!g_file_has_prefix (gfile, path)) {
+ // "Rebase" the file in the given path, to ensure we never escape it
+ char *rawpath = g_file_get_path (gfile);
+ if (rawpath != NULL) {
+ char *newpath = rawpath;
+ while (*newpath != 0 && *newpath == G_DIR_SEPARATOR) {
+ newpath++;
+ }
+ GFile *newgfile = g_file_resolve_relative_path (path, newpath);
+ g_free (rawpath);
+ g_object_unref (gfile);
+ gfile = newgfile;
+ }
+ }
+
+ GFile *parent = g_file_get_parent (gfile);
+
if (!g_file_make_directory_with_parents (parent, cancellable, &my_error)) {
if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
g_clear_error (&my_error);