Fix CVE-2020-11736
(cherry picked from commit 626eec41afd5596c0f450d66c66c0467b0aa8c04)
This commit is contained in:
parent
c6472e1cb0
commit
b261d129e6
218
backport-CVE-2020-11736.patch
Normal file
218
backport-CVE-2020-11736.patch
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
From 8d48f633a48232c0ae8785a7388ae7e99faf3c5b 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] 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 1d45164..e86ed3d 100644
|
||||||
|
--- a/src/fr-archive-libarchive.c
|
||||||
|
+++ b/src/fr-archive-libarchive.c
|
||||||
|
@@ -603,6 +603,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,
|
||||||
|
@@ -613,6 +756,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;
|
||||||
|
@@ -623,6 +767,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 ();
|
||||||
|
@@ -654,6 +799,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;
|
||||||
|
}
|
||||||
|
@@ -862,6 +1016,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;
|
||||||
|
|
||||||
|
@@ -896,6 +1052,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.23.0
|
||||||
|
|
||||||
@ -1,11 +1,12 @@
|
|||||||
Name: file-roller
|
Name: file-roller
|
||||||
Version: 3.30.1
|
Version: 3.30.1
|
||||||
Release: 2
|
Release: 3
|
||||||
Summary: An archive manager utility for the GNOME Environment
|
Summary: An archive manager utility for the GNOME Environment
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: https://wiki.gnome.org/Apps/FileRoller
|
URL: https://wiki.gnome.org/Apps/FileRoller
|
||||||
Source0: https://download.gnome.org/sources/%{name}/3.30/%{name}-%{version}.tar.xz
|
Source0: https://download.gnome.org/sources/%{name}/3.30/%{name}-%{version}.tar.xz
|
||||||
|
Patch0: backport-CVE-2020-11736.patch
|
||||||
|
|
||||||
BuildRequires: cpio gettext gcc itstool file-devel pkgconfig(gthread-2.0)
|
BuildRequires: cpio gettext gcc itstool file-devel pkgconfig(gthread-2.0)
|
||||||
BuildRequires: meson >= 0.43 pkgconfig(glib-2.0) >= 2.36 pkgconfig(gtk+-3.0) >= 3.13.2 pkgconfig(libnautilus-extension) >= 2.22.2
|
BuildRequires: meson >= 0.43 pkgconfig(glib-2.0) >= 2.36 pkgconfig(gtk+-3.0) >= 3.13.2 pkgconfig(libnautilus-extension) >= 2.22.2
|
||||||
@ -58,5 +59,8 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.FileRoller.
|
|||||||
%{_libdir}/nautilus/extensions-3.0/libnautilus-fileroller.so
|
%{_libdir}/nautilus/extensions-3.0/libnautilus-fileroller.so
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jul 29 2021 wangyue <wangyue92@huawei.com> - 3.30.1-3
|
||||||
|
- Fix CVE-2020-11736
|
||||||
|
|
||||||
* Thu Oct 17 2019 Yiru Wang <wangyiru1@huawei.com> - 1.20.7-17
|
* Thu Oct 17 2019 Yiru Wang <wangyiru1@huawei.com> - 1.20.7-17
|
||||||
- Pakcage init
|
- Pakcage init
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user