mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-16 04:24:44 -04:00
system-helper: Only remove an ongoing pull if users match
The code would always remove a pull from the hashtable, and then check if the users match and abort if they don't. Either way, the pull gets dropped. Fix this by only removing the pull if the dir and the user match.
This commit is contained in:
committed by
Sebastian Wick
parent
4a678f463b
commit
a27ec46e8c
@@ -358,23 +358,31 @@ get_connection_uid (GDBusMethodInvocation *invocation, uid_t *out_uid, GError **
|
||||
}
|
||||
|
||||
static OngoingPull *
|
||||
take_ongoing_pull_by_dir (const gchar *src_dir)
|
||||
take_ongoing_pull_by_dir (const char *src_dir,
|
||||
uid_t uid)
|
||||
{
|
||||
OngoingPull *pull = NULL;
|
||||
gpointer key, value;
|
||||
char *cache_dir_name = NULL;
|
||||
|
||||
G_LOCK (cache_dirs_in_use);
|
||||
/* Keep src_dir key inside hashtable but remove its OngoingPull
|
||||
* value and set it to NULL. This way src_dir is still marked
|
||||
* as in-use (as Deploy or CancelPull might be executing on it,
|
||||
* whereas OngoingPull ownership is transferred to respective
|
||||
* callers. */
|
||||
if (g_hash_table_steal_extended (cache_dirs_in_use, src_dir, &key, &value))
|
||||
if (g_hash_table_steal_extended (cache_dirs_in_use, src_dir,
|
||||
(gpointer) &cache_dir_name,
|
||||
(gpointer) &pull))
|
||||
{
|
||||
if (value)
|
||||
if (pull && pull->uid == uid)
|
||||
{
|
||||
g_hash_table_insert (cache_dirs_in_use, key, NULL);
|
||||
pull = value;
|
||||
/* Keep src_dir key inside hashtable but remove its OngoingPull
|
||||
* value and set it to NULL. This way src_dir is still marked
|
||||
* as in-use (as Deploy or CancelPull might be executing on it,
|
||||
* whereas OngoingPull ownership is transferred to respective
|
||||
* callers. */
|
||||
g_hash_table_insert (cache_dirs_in_use, cache_dir_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, re-insert what is currently there and return NULL */
|
||||
g_hash_table_insert (cache_dirs_in_use, cache_dir_name, pull);
|
||||
pull = NULL;
|
||||
}
|
||||
}
|
||||
G_UNLOCK (cache_dirs_in_use);
|
||||
@@ -426,6 +434,9 @@ handle_deploy (FlatpakSystemHelper *object,
|
||||
|
||||
if (strlen (arg_repo_path) > 0)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
uid_t uid;
|
||||
|
||||
if (!g_file_query_exists (repo_file, NULL))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
|
||||
@@ -433,30 +444,17 @@ handle_deploy (FlatpakSystemHelper *object,
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
/* Ensure that pull's uid is same as the caller's uid */
|
||||
if (!get_connection_uid (invocation, &uid, &local_error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, local_error);
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
src_dir = g_path_get_dirname (arg_repo_path);
|
||||
ongoing_pull = take_ongoing_pull_by_dir (src_dir);
|
||||
ongoing_pull = take_ongoing_pull_by_dir (src_dir, uid);
|
||||
if (ongoing_pull != NULL)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
uid_t uid;
|
||||
|
||||
/* Ensure that pull's uid is same as the caller's uid */
|
||||
if (!get_connection_uid (invocation, &uid, &local_error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, local_error);
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ongoing_pull->uid != uid)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"Ongoing pull's uid(%d) does not match with peer uid(%d)",
|
||||
ongoing_pull->uid, uid);
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
terminate_revokefs_backend (ongoing_pull);
|
||||
|
||||
if (!flatpak_canonicalize_permissions (AT_FDCWD,
|
||||
@@ -738,7 +736,13 @@ handle_cancel_pull (FlatpakSystemHelper *object,
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
ongoing_pull = take_ongoing_pull_by_dir (arg_src_dir);
|
||||
if (!get_connection_uid (invocation, &uid, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
ongoing_pull = take_ongoing_pull_by_dir (arg_src_dir, uid);
|
||||
if (ongoing_pull == NULL)
|
||||
{
|
||||
g_set_error (&error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
@@ -747,23 +751,6 @@ handle_cancel_pull (FlatpakSystemHelper *object,
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
/* Ensure that pull's uid is same as the caller's uid */
|
||||
if (!get_connection_uid (invocation, &uid, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ongoing_pull->uid != uid)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"Ongoing pull's uid(%d) does not match with peer uid(%d)",
|
||||
ongoing_pull->uid, uid);
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
ongoing_pull->preserve_pull = (arg_flags & FLATPAK_HELPER_CANCEL_PULL_FLAGS_PRESERVE_PULL) != 0;
|
||||
ongoing_pull_free (ongoing_pull);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user