import file-roller-3.28.1-3.el8

This commit is contained in:
CentOS Sources 2020-11-03 07:01:54 -05:00 committed by Andrew Lukoshko
parent 0e05800e2c
commit ad0a0c715f
3 changed files with 297 additions and 2 deletions

View File

@ -0,0 +1,28 @@
From 57268e51e59b61c9e3125eb0f65551c7084297e2 Mon Sep 17 00:00:00 2001
From: Paolo Bacchilega <paobac@src.gnome.org>
Date: Mon, 27 Aug 2018 15:15:42 +0200
Subject: [PATCH] Path traversal vulnerability
Do not extract files with relative paths.
[bug #794337]
---
src/glib-utils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/glib-utils.c b/src/glib-utils.c
index 6d345243..c3901410 100644
--- a/src/glib-utils.c
+++ b/src/glib-utils.c
@@ -1079,7 +1079,7 @@ sanitize_filename (const char *file_name)
prefix_len = 0;
for (p = file_name; *p; ) {
if (ISDOT (p[0]) && ISDOT (p[1]) && (ISSLASH (p[2]) || !p[2]))
- prefix_len = p + 2 - file_name;
+ return NULL;
do {
char c = *p++;
--
2.26.2

View File

@ -0,0 +1,259 @@
From 72ac9340d9fe9554ea5c3f0ea6d08d0afa04cbf5 Mon Sep 17 00:00:00 2001
From: Paolo Bacchilega <paobac@src.gnome.org>
Date: Sun, 12 Apr 2020 11:38:35 +0200
Subject: [PATCH 1/2] libarchive: do not follow external links when extracting
files
Do not extract a file if its parent is a symbolic link to a
directory external to the destination.
---
src/fr-archive-libarchive.c | 157 ++++++++++++++++++++++++++++++++++++
1 file changed, 157 insertions(+)
diff --git a/src/fr-archive-libarchive.c b/src/fr-archive-libarchive.c
index 70c07e23..8d84b2ea 100644
--- a/src/fr-archive-libarchive.c
+++ b/src/fr-archive-libarchive.c
@@ -601,6 +601,149 @@ _g_output_stream_add_padding (ExtractData *extract_data,
}
+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)
+{
+ 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;
+ GFile *parent;
+ char **components;
+ int i;
+
+ if (relative_path == NULL)
+ return FALSE;
+
+ if (destination == NULL)
+ return TRUE;
+
+ parent = g_object_ref (destination);
+ components = g_strsplit (relative_path, "/", -1);
+ for (i = 0; (components[i] != NULL) && (components[i + 1] != NULL); i++) {
+ GFile *tmp;
+
+ if (components[i][0] == 0)
+ continue;
+
+ 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 void
extract_archive_thread (GSimpleAsyncResult *result,
GObject *object,
@@ -611,6 +754,7 @@ extract_archive_thread (GSimpleAsyncResult *result,
GHashTable *checked_folders;
GHashTable *created_files;
GHashTable *folders_created_during_extraction;
+ GHashTable *external_links;
struct archive *a;
struct archive_entry *entry;
int r;
@@ -621,6 +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);
fr_archive_progress_set_total_files (load_data->archive, extract_data->n_files_to_extract);
a = archive_read_new ();
@@ -652,6 +797,15 @@ extract_archive_thread (GSimpleAsyncResult *result,
fullpath = (*pathname == '/') ? g_strdup (pathname) : g_strconcat ("/", pathname, NULL);
relative_path = _g_path_get_relative_basename_safe (fullpath, extract_data->base_dir, extract_data->junk_paths);
if (relative_path == NULL) {
+ 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);
+ continue;
+ }
+
+ if (_g_path_is_external_to_destination (relative_path, extract_data->destination, external_links)) {
+ 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);
continue;
}
@@ -860,6 +1014,8 @@ extract_archive_thread (GSimpleAsyncResult *result,
load_data->error = g_error_copy (local_error);
g_clear_error (&local_error);
}
+ else if (_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));
archive_read_data_skip (a);
break;
@@ -894,6 +1050,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);
archive_read_free (a);
extract_data_free (extract_data);
}
--
2.26.2
From 25f0759274f3be9480aaba01ed801d1308a00026 Mon Sep 17 00:00:00 2001
From: Paolo Bacchilega <paobac@src.gnome.org>
Date: Sun, 12 Apr 2020 12:19:18 +0200
Subject: [PATCH 2/2] libarchive: overwrite the symbolic link as well
---
src/fr-archive-libarchive.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/fr-archive-libarchive.c b/src/fr-archive-libarchive.c
index 8d84b2ea..07babbc4 100644
--- a/src/fr-archive-libarchive.c
+++ b/src/fr-archive-libarchive.c
@@ -1010,11 +1010,21 @@ extract_archive_thread (GSimpleAsyncResult *result,
case AE_IFLNK:
if (! g_file_make_symbolic_link (file, archive_entry_symlink (entry), cancellable, &local_error)) {
- if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ g_clear_error (&local_error);
+ if (g_file_delete (file, cancellable, &local_error)) {
+ g_clear_error (&local_error);
+ if (! g_file_make_symbolic_link (file, archive_entry_symlink (entry), cancellable, &local_error))
+ load_data->error = g_error_copy (local_error);
+ }
+ else
+ load_data->error = g_error_copy (local_error);
+ }
+ else
load_data->error = g_error_copy (local_error);
g_clear_error (&local_error);
}
- else if (_symlink_is_external_to_destination (file, archive_entry_symlink (entry), extract_data->destination, external_links))
+ 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));
archive_read_data_skip (a);
break;
--
2.26.2

View File

@ -1,11 +1,15 @@
Name: file-roller
Version: 3.28.1
Release: 2%{?dist}
Release: 3%{?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.28/%{name}-%{version}.tar.xz
# https://bugzilla.redhat.com/show_bug.cgi?id=1827395
Patch0: file-roller-3.28.1-CVE-2020-11736.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1767594
Patch1: file-roller-3.28.1-CVE-2019-16680.patch
BuildRequires: pkgconfig(gio-unix-2.0)
BuildRequires: pkgconfig(gtk+-3.0)
@ -48,7 +52,7 @@ File Roller is an application for creating and viewing archives files,
such as tar or zip files.
%prep
%setup -q
%autosetup -p1
%build
%meson
@ -80,6 +84,10 @@ desktop-file-validate $RPM_BUILD_ROOT%{_datadir}/applications/org.gnome.FileRoll
%{_datadir}/metainfo/org.gnome.FileRoller.appdata.xml
%changelog
* Mon Jun 01 2020 David King <dking@redhat.com> - 3.28.1-3
- Fix CVE-2020-11736 (#1827395)
- Fix CVE-2019-16680 (#1767594)
* Wed Jun 05 2019 David King <dking@redhat.com> - 3.28.1-2
- Remove nautilus extension subpackage (#1638813)