Update to 3.39.1

epel9
Kalev Lember 4 years ago
parent 8f4237b428
commit f9b1d931de

@ -1,218 +0,0 @@
From e970f4966bf388f6e7c277357c8b186c645683ae Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 11 Mar 2021 16:24:35 +0100
Subject: [PATCH] libarchive: Skip files with symlinks in parents
Currently, it is still possible that some files are extracted outside of
the destination dir in case of malicious archives. The checks from commit
21dfcdbf can be still bypassed in certain cases. See GNOME/file-roller#108
for more details. After some investigation, I am convinced that it would be
best to simply disallow symlinks in parents. For example, `tar` fails to
extract such files with the `ENOTDIR` error. Let's do the same here.
Fixes: https://gitlab.gnome.org/GNOME/file-roller/-/issues/108
---
src/fr-archive-libarchive.c | 136 ++++++------------------------------
1 file changed, 20 insertions(+), 116 deletions(-)
diff --git a/src/fr-archive-libarchive.c b/src/fr-archive-libarchive.c
index 4f698ee4..e61f8821 100644
--- a/src/fr-archive-libarchive.c
+++ b/src/fr-archive-libarchive.c
@@ -697,115 +697,12 @@ _g_output_stream_add_padding (ExtractData *extract_data,
return success;
}
-
-static gboolean
-_symlink_is_external_to_destination (GFile *file,
- const char *symlink,
- GFile *destination,
- GHashTable *external_links);
-
-
-static gboolean
-_g_file_is_external_link (GFile *file,
- GFile *destination,
- GHashTable *external_links)
-{
- GFileInfo *info;
- gboolean external;
-
- if (g_hash_table_lookup (external_links, file) != NULL)
- return TRUE;
-
- info = g_file_query_info (file,
- G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL,
- NULL);
-
- if (info == NULL)
- return FALSE;
-
- external = FALSE;
-
- if (g_file_info_get_is_symlink (info)) {
- if (_symlink_is_external_to_destination (file,
- g_file_info_get_symlink_target (info),
- destination,
- external_links))
- {
- g_hash_table_insert (external_links, g_object_ref (file), GINT_TO_POINTER (1));
- external = TRUE;
- }
- }
-
- g_object_unref (info);
-
- return external;
-}
-
-
static gboolean
-_symlink_is_external_to_destination (GFile *file,
- const char *symlink,
- GFile *destination,
- GHashTable *external_links)
+_g_file_contains_symlinks_in_path (const char *relative_path,
+ GFile *destination,
+ GHashTable *symlinks)
{
- gboolean external = FALSE;
- GFile *parent;
- char **components;
- int i;
-
- if ((file == NULL) || (symlink == NULL))
- return FALSE;
-
- if (symlink[0] == '/')
- return TRUE;
-
- parent = g_file_get_parent (file);
- components = g_strsplit (symlink, "/", -1);
- for (i = 0; components[i] != NULL; i++) {
- char *name = components[i];
- GFile *tmp;
-
- if ((name[0] == 0) || ((name[0] == '.') && (name[1] == 0)))
- continue;
-
- if ((name[0] == '.') && (name[1] == '.') && (name[2] == 0)) {
- if (g_file_equal (parent, destination)) {
- external = TRUE;
- break;
- }
- else {
- tmp = g_file_get_parent (parent);
- g_object_unref (parent);
- parent = tmp;
- }
- }
- else {
- tmp = g_file_get_child (parent, components[i]);
- g_object_unref (parent);
- parent = tmp;
- }
-
- if (_g_file_is_external_link (parent, destination, external_links)) {
- external = TRUE;
- break;
- }
- }
-
- g_strfreev (components);
- g_object_unref (parent);
-
- return external;
-}
-
-
-static gboolean
-_g_path_is_external_to_destination (const char *relative_path,
- GFile *destination,
- GHashTable *external_links)
-{
- gboolean external = FALSE;
+ gboolean contains_symlinks = FALSE;
GFile *parent;
char **components;
int i;
@@ -828,8 +725,8 @@ _g_path_is_external_to_destination (const char *relative_path,
g_object_unref (parent);
parent = tmp;
- if (_g_file_is_external_link (parent, destination, external_links)) {
- external = TRUE;
+ if (g_hash_table_contains (symlinks, parent)) {
+ contains_symlinks = TRUE;
break;
}
}
@@ -837,7 +734,7 @@ _g_path_is_external_to_destination (const char *relative_path,
g_strfreev (components);
g_object_unref (parent);
- return external;
+ return contains_symlinks;
}
@@ -851,7 +748,7 @@ extract_archive_thread (GSimpleAsyncResult *result,
GHashTable *checked_folders;
GHashTable *created_files;
GHashTable *folders_created_during_extraction;
- GHashTable *external_links;
+ GHashTable *symlinks;
struct archive *a;
struct archive_entry *entry;
int r;
@@ -868,7 +765,7 @@ extract_archive_thread (GSimpleAsyncResult *result,
checked_folders = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
created_files = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, g_object_unref);
folders_created_during_extraction = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
- external_links = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
+ symlinks = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
fr_archive_progress_set_total_files (load_data->archive, extract_data->n_files_to_extract);
while ((r = archive_read_next_header (a, &entry)) == ARCHIVE_OK) {
@@ -902,7 +799,14 @@ extract_archive_thread (GSimpleAsyncResult *result,
continue;
}
- if (_g_path_is_external_to_destination (relative_path, extract_data->destination, external_links)) {
+ /* Symlinks in parents are dangerous as it can easily happen
+ * that files are written outside of the destination. The tar
+ * cmd fails to extract such archives with ENOTDIR. Let's skip
+ * those files here for sure. This is most probably malicious,
+ * or corrupted archive.
+ */
+ if (_g_file_contains_symlinks_in_path (relative_path, extract_data->destination, symlinks)) {
+ g_warning ("Skipping '%s' file as it has symlink in parents.", relative_path);
fr_archive_progress_inc_completed_files (load_data->archive, 1);
fr_archive_progress_inc_completed_bytes (load_data->archive, archive_entry_size_is_set (entry) ? archive_entry_size (entry) : 0);
archive_read_data_skip (a);
@@ -1123,8 +1027,8 @@ extract_archive_thread (GSimpleAsyncResult *result,
load_data->error = g_error_copy (local_error);
g_clear_error (&local_error);
}
- if ((load_data->error == NULL) && _symlink_is_external_to_destination (file, archive_entry_symlink (entry), extract_data->destination, external_links))
- g_hash_table_insert (external_links, g_object_ref (file), GINT_TO_POINTER (1));
+ if (load_data->error == NULL)
+ g_hash_table_add (symlinks, g_object_ref (file));
archive_read_data_skip (a);
break;
@@ -1159,7 +1063,7 @@ extract_archive_thread (GSimpleAsyncResult *result,
g_hash_table_unref (folders_created_during_extraction);
g_hash_table_unref (created_files);
g_hash_table_unref (checked_folders);
- g_hash_table_unref (external_links);
+ g_hash_table_unref (symlinks);
archive_read_free (a);
extract_data_free (extract_data);
}
--
GitLab

@ -1,13 +1,11 @@
Name: file-roller
Version: 3.38.0
Release: 3%{?dist}
Version: 3.39.1
Release: 1%{?dist}
Summary: Tool for viewing and creating archives
License: GPLv2+
URL: https://wiki.gnome.org/Apps/FileRoller
Source0: https://download.gnome.org/sources/%{name}/3.38/%{name}-%{version}.tar.xz
# https://bugzilla.redhat.com/show_bug.cgi?id=1947535
Patch1: file-roller-3.38.0-CVE-2020-36314.patch
Source0: https://download.gnome.org/sources/%{name}/3.39/%{name}-%{version}.tar.xz
BuildRequires: meson
BuildRequires: gcc
@ -54,10 +52,6 @@ or directories.
%install
%meson_install
# make the service filename match the bus name, flatpak doesn't like it otherwise
mv %{buildroot}%{_datadir}/dbus-1/services/org.gnome.FileRoller.ArchiveManager1.service \
%{buildroot}%{_datadir}/dbus-1/services/org.gnome.ArchiveManager1.service
%find_lang %{name} --with-gnome
%check
@ -86,6 +80,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.FileRoller.
%endif
%changelog
* Tue Apr 13 2021 Kalev Lember <klember@redhat.com> - 3.39.1-1
- Update to 3.39.1
* Thu Apr 08 2021 David King <amigadave@amigadave.com> - 3.38.0-3
- Fix CVE-2020-36314 (#1947535)

@ -1 +1 @@
SHA512 (file-roller-3.38.0.tar.xz) = 9c2e3c105397bceb08e30c9796b9242633fe49772aed2e7f67461c34a51be1493e922301b1fc29bdcb0fa50d220f4a7db2ee7642f629007ce2bef00334d7110e
SHA512 (file-roller-3.39.1.tar.xz) = 06e160cbc229497a915ea76408cb6ba47a1ed5e58c9e99eb64d9641eebb54c499977cefd6ff19d64899d2992b488163e04a8422eb42eadb9a316e31e565047bc

Loading…
Cancel
Save