summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2020-02-20 15:58:35 +0100
committerCarlos Garnacho <mrgarnacho@gmail.com>2020-02-29 21:13:51 +0000
commitc25c003152271fd42eb852da79a4b10be82c1c97 (patch)
tree780b9e684b76c52d32a3389af57d31c4f18d0064
parent2937c12d52df0eace05bc3a4373611e03ce97354 (diff)
downloadgnome-settings-daemon-benzea/gsd-housekeeping.tar.gz
housekeeping: Never cross into a different filesystembenzea/gsd-housekeeping
This stops us from crossing into another file system. The test simply uses the file system tag, which means that e.g. bind mounts to the same file system are not found. The exception to this is trash:, in that case, set filesystem to NULL and allow crossing over. This must be done as trash: is virtual and files might be coming from various locations. Fixes: #252
-rw-r--r--plugins/housekeeping/gsd-disk-space.c56
-rw-r--r--plugins/housekeeping/gsd-disk-space.h6
-rw-r--r--plugins/housekeeping/gsd-purge-temp-test.c4
3 files changed, 56 insertions, 10 deletions
diff --git a/plugins/housekeeping/gsd-disk-space.c b/plugins/housekeeping/gsd-disk-space.c
index 87c130af..9d57531f 100644
--- a/plugins/housekeeping/gsd-disk-space.c
+++ b/plugins/housekeeping/gsd-disk-space.c
@@ -251,13 +251,15 @@ delete_data_new (GFile *file,
GDateTime *old,
gboolean dry_run,
gboolean trash,
- gint depth)
+ gint depth,
+ const char *filesystem)
{
DeleteData *data;
data = g_new (DeleteData, 1);
data->ref_count = 1;
data->file = g_object_ref (file);
+ data->filesystem = g_strdup (filesystem);
data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
data->old = g_date_time_ref (old);
data->dry_run = dry_run;
@@ -268,6 +270,21 @@ delete_data_new (GFile *file,
return data;
}
+char*
+get_filesystem (GFile *file)
+{
+ g_autoptr(GFileInfo) info = NULL;
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_ID_FILESYSTEM,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+
+ return g_file_info_get_attribute_as_string (info,
+ G_FILE_ATTRIBUTE_ID_FILESYSTEM);
+}
+
static DeleteData *
delete_data_ref (DeleteData *data)
{
@@ -287,6 +304,7 @@ delete_data_unref (DeleteData *data)
g_object_unref (data->cancellable);
g_date_time_unref (data->old);
g_free (data->name);
+ g_free (data->filesystem);
g_free (data);
}
@@ -297,6 +315,7 @@ delete_batch (GObject *source,
{
GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source);
DeleteData *data = user_data;
+ const char *fs;
GList *files, *f;
GFile *child_file;
DeleteData *child;
@@ -313,13 +332,26 @@ delete_batch (GObject *source,
break;
info = f->data;
+ fs = g_file_info_get_attribute_string (info,
+ G_FILE_ATTRIBUTE_ID_FILESYSTEM);
+
+ /* Do not consider the file if it is on a different file system.
+ * Ignore data->filesystem if it is NULL (this only happens if
+ * it is the toplevel trash directory). */
+ if (data->filesystem && g_strcmp0 (fs, data->filesystem) != 0) {
+ g_debug ("GsdHousekeeping: skipping file \"%s\" as it is on a different file system",
+ g_file_info_get_name (info));
+ continue;
+ }
+
child_file = g_file_get_child (data->file, g_file_info_get_name (info));
child = delete_data_new (child_file,
data->cancellable,
data->old,
data->dry_run,
data->trash,
- data->depth + 1);
+ data->depth + 1,
+ fs);
delete_recursively_by_age (child);
delete_data_unref (child);
g_object_unref (child_file);
@@ -418,7 +450,8 @@ delete_subdir_check_symlink (GObject *source,
} else {
g_file_enumerate_children_async (data->file,
G_FILE_ATTRIBUTE_STANDARD_NAME ","
- G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+ G_FILE_ATTRIBUTE_ID_FILESYSTEM,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
0,
data->cancellable,
@@ -455,7 +488,7 @@ gsd_ldsm_purge_trash (GDateTime *old)
DeleteData *data;
file = g_file_new_for_uri ("trash:");
- data = delete_data_new (file, NULL, old, FALSE, TRUE, 0);
+ data = delete_data_new (file, NULL, old, FALSE, TRUE, 0, NULL);
delete_recursively_by_age (data);
delete_data_unref (data);
g_object_unref (file);
@@ -466,6 +499,7 @@ gsd_ldsm_purge_temp_files (GDateTime *old)
{
DeleteData *data;
GFile *file;
+ char *filesystem;
/* Never clean temporary files on a sane (i.e. systemd managed)
* system. In that case systemd already ships
@@ -482,14 +516,18 @@ gsd_ldsm_purge_temp_files (GDateTime *old)
return;
file = g_file_new_for_path (g_get_tmp_dir ());
- data = delete_data_new (file, NULL, old, FALSE, FALSE, 0);
+ filesystem = get_filesystem (file);
+ data = delete_data_new (file, NULL, old, FALSE, FALSE, 0, filesystem);
+ g_free (filesystem);
delete_recursively_by_age (data);
delete_data_unref (data);
g_object_unref (file);
if (g_strcmp0 (g_get_tmp_dir (), "/var/tmp") != 0) {
file = g_file_new_for_path ("/var/tmp");
- data = delete_data_new (file, NULL, old, FALSE, FALSE, 0);
+ filesystem = get_filesystem (file);
+ data = delete_data_new (file, NULL, old, FALSE, FALSE, 0, filesystem);
+ g_free (filesystem);
delete_recursively_by_age (data);
delete_data_unref (data);
g_object_unref (file);
@@ -497,7 +535,9 @@ gsd_ldsm_purge_temp_files (GDateTime *old)
if (g_strcmp0 (g_get_tmp_dir (), "/tmp") != 0) {
file = g_file_new_for_path ("/tmp");
- data = delete_data_new (file, NULL, old, FALSE, FALSE, 0);
+ filesystem = get_filesystem (file);
+ data = delete_data_new (file, NULL, old, FALSE, FALSE, 0, filesystem);
+ g_free (filesystem);
delete_recursively_by_age (data);
delete_data_unref (data);
g_object_unref (file);
@@ -513,7 +553,7 @@ gsd_ldsm_show_empty_trash (void)
old = g_date_time_new_now_local ();
file = g_file_new_for_uri ("trash:");
- data = delete_data_new (file, NULL, old, TRUE, TRUE, 0);
+ data = delete_data_new (file, NULL, old, TRUE, TRUE, 0, NULL);
g_object_unref (file);
g_date_time_unref (old);
diff --git a/plugins/housekeeping/gsd-disk-space.h b/plugins/housekeeping/gsd-disk-space.h
index 67e4a4a9..38c29639 100644
--- a/plugins/housekeeping/gsd-disk-space.h
+++ b/plugins/housekeeping/gsd-disk-space.h
@@ -35,6 +35,7 @@ typedef struct {
gboolean dry_run;
gboolean trash;
gchar *name;
+ gchar *filesystem;
gint depth;
} DeleteData;
@@ -44,7 +45,10 @@ DeleteData *delete_data_new (GFile *file,
GDateTime *old,
gboolean dry_run,
gboolean trash,
- gint depth);
+ gint depth,
+ const char *filesystem);
+char* get_filesystem (GFile *file);
+
void delete_recursively_by_age (DeleteData *data);
void gsd_ldsm_setup (gboolean check_now);
diff --git a/plugins/housekeeping/gsd-purge-temp-test.c b/plugins/housekeeping/gsd-purge-temp-test.c
index 2e789327..6ff2d5eb 100644
--- a/plugins/housekeeping/gsd-purge-temp-test.c
+++ b/plugins/housekeeping/gsd-purge-temp-test.c
@@ -33,6 +33,7 @@ main (int argc,
DeleteData *data;
GDateTime *old;
GMainLoop *loop;
+ g_autofree char *filesystem = NULL;
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
@@ -48,7 +49,8 @@ main (int argc,
}
old = g_date_time_new_now_local ();
- data = delete_data_new (file, NULL, old, FALSE, FALSE, 0);
+ filesystem = get_filesystem (file);
+ data = delete_data_new (file, NULL, old, FALSE, FALSE, 0, filesystem);
delete_recursively_by_age (data);
delete_data_unref (data);
g_object_unref (file);