[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#964574: buster-pu: package file-roller/3.30.1-2+deb10u1



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


Reply to: