--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: buster-pu: package file-roller/3.30.1-2+deb10u1
- From: Moritz Muehlenhoff <jmm@debian.org>
- Date: Wed, 08 Jul 2020 22:54:08 +0200
- Message-id: <159424164815.182364.14311723873699499215.reportbug@hullmann.westfalen.local>
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu
Low severity issue in file-roller, I've verified with a reproducer
that the issue is fixed and did various tests to ensure that nothing
breaks functionality-wise. debdiff below.
Cheers,
Moritz
diff -Nru file-roller-3.30.1/debian/changelog file-roller-3.30.1/debian/changelog
--- file-roller-3.30.1/debian/changelog 2018-12-24 02:34:26.000000000 +0100
+++ file-roller-3.30.1/debian/changelog 2020-07-08 20:12:00.000000000 +0200
@@ -1,3 +1,9 @@
+file-roller (3.30.1-2+deb10u1) buster; urgency=medium
+
+ * CVE-2020-11736 (Closes: #956638)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Wed, 08 Jul 2020 20:12:00 +0200
+
file-roller (3.30.1-2) unstable; urgency=medium
* Restore -Wl,-O1 to our LDFLAGS
diff -Nru file-roller-3.30.1/debian/patches/02_CVE-2020-11736.patch file-roller-3.30.1/debian/patches/02_CVE-2020-11736.patch
--- file-roller-3.30.1/debian/patches/02_CVE-2020-11736.patch 1970-01-01 01:00:00.000000000 +0100
+++ file-roller-3.30.1/debian/patches/02_CVE-2020-11736.patch 2020-07-08 20:12:00.000000000 +0200
@@ -0,0 +1,201 @@
+--- file-roller-3.30.1.orig/src/fr-archive-libarchive.c
++++ file-roller-3.30.1/src/fr-archive-libarchive.c
+@@ -603,6 +603,149 @@ _g_output_stream_add_padding (ExtractDat
+ }
+
+
++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 (GSimpleAsyncResu
+ 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 (GSimpleAsyncResu
+ 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 (GSimpleAsyncResu
+ 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 (GSimpleAsyncResu
+ 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 (GSimpleAsyncResu
+ 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);
+ }
diff -Nru file-roller-3.30.1/debian/patches/series file-roller-3.30.1/debian/patches/series
--- file-roller-3.30.1/debian/patches/series 2018-12-24 02:34:26.000000000 +0100
+++ file-roller-3.30.1/debian/patches/series 2020-07-08 20:12:00.000000000 +0200
@@ -1 +1,3 @@
01_package_names.patch
+
+02_CVE-2020-11736.patch
--- End Message ---