mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-26 10:54:59 -04:00
dir: Check parental control authorization via system bus name
PIDs are pretty much always a bad idea because they can be racy. The authorization did use the PID though. We can replace it by a check via the system bus name. Closes: https://github.com/flatpak/flatpak/issues/6212
This commit is contained in:
@@ -60,6 +60,8 @@ GType flatpak_deploy_get_type (void);
|
|||||||
|
|
||||||
#define FLATPAK_CLI_UPDATE_INTERVAL_MS 300
|
#define FLATPAK_CLI_UPDATE_INTERVAL_MS 300
|
||||||
|
|
||||||
|
typedef struct _PolkitSubject PolkitSubject;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FlatpakDecomposed *ref;
|
FlatpakDecomposed *ref;
|
||||||
@@ -1022,9 +1024,8 @@ char ** flatpak_dir_get_default_locale_languages (Fla
|
|||||||
char ** flatpak_dir_get_locales (FlatpakDir *self);
|
char ** flatpak_dir_get_locales (FlatpakDir *self);
|
||||||
char ** flatpak_dir_get_locale_languages (FlatpakDir *self);
|
char ** flatpak_dir_get_locale_languages (FlatpakDir *self);
|
||||||
char ** flatpak_dir_get_locale_subpaths (FlatpakDir *self);
|
char ** flatpak_dir_get_locale_subpaths (FlatpakDir *self);
|
||||||
void flatpak_dir_set_source_pid (FlatpakDir *self,
|
void flatpak_dir_set_subject (FlatpakDir *self,
|
||||||
pid_t pid);
|
PolkitSubject *subject);
|
||||||
pid_t flatpak_dir_get_source_pid (FlatpakDir *self);
|
|
||||||
gboolean flatpak_dir_delete_mirror_refs (FlatpakDir *self,
|
gboolean flatpak_dir_delete_mirror_refs (FlatpakDir *self,
|
||||||
gboolean dry_run,
|
gboolean dry_run,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ struct FlatpakDir
|
|||||||
GFile *cache_dir;
|
GFile *cache_dir;
|
||||||
gboolean no_system_helper;
|
gboolean no_system_helper;
|
||||||
gboolean no_interaction;
|
gboolean no_interaction;
|
||||||
pid_t source_pid;
|
PolkitSubject *subject;
|
||||||
|
|
||||||
GDBusConnection *system_helper_bus;
|
GDBusConnection *system_helper_bus;
|
||||||
|
|
||||||
@@ -3216,6 +3216,7 @@ flatpak_dir_finalize (GObject *object)
|
|||||||
g_clear_pointer (&self->remote_filters, g_hash_table_unref);
|
g_clear_pointer (&self->remote_filters, g_hash_table_unref);
|
||||||
g_clear_pointer (&self->masked, g_regex_unref);
|
g_clear_pointer (&self->masked, g_regex_unref);
|
||||||
g_clear_pointer (&self->pinned, g_regex_unref);
|
g_clear_pointer (&self->pinned, g_regex_unref);
|
||||||
|
g_clear_object (&self->subject);
|
||||||
|
|
||||||
G_OBJECT_CLASS (flatpak_dir_parent_class)->finalize (object);
|
G_OBJECT_CLASS (flatpak_dir_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -9107,9 +9108,8 @@ flatpak_dir_check_parental_controls (FlatpakDir *self,
|
|||||||
/* Assume that root is allowed to install any ref and shouldn't have any
|
/* Assume that root is allowed to install any ref and shouldn't have any
|
||||||
* parental controls restrictions applied to them. Note that this branch
|
* parental controls restrictions applied to them. Note that this branch
|
||||||
* must not be taken if this code is running within the system-helper, as that
|
* must not be taken if this code is running within the system-helper, as that
|
||||||
* runs as root but on behalf of another process. If running within the
|
* runs as root but on behalf of another process. */
|
||||||
* system-helper, self->source_pid is non-zero. */
|
if (!self->subject && getuid () == 0)
|
||||||
if (self->source_pid == 0 && getuid () == 0)
|
|
||||||
{
|
{
|
||||||
g_info ("Skipping parental controls check for %s due to running as root", ref);
|
g_info ("Skipping parental controls check for %s due to running as root", ref);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -9141,13 +9141,25 @@ flatpak_dir_check_parental_controls (FlatpakDir *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->user || self->source_pid == 0)
|
if (self->subject)
|
||||||
subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
|
{
|
||||||
else
|
g_autoptr(PolkitSubject) process_subject = NULL;
|
||||||
subject = polkit_unix_process_new_for_owner (self->source_pid, 0, -1);
|
|
||||||
|
subject = g_object_ref (self->subject);
|
||||||
|
/* This internally uses dbus GetConnectionCredentials which ensures we
|
||||||
|
* get the right UID. We should *not* use it for authorization via the
|
||||||
|
* PID though! */
|
||||||
|
process_subject =
|
||||||
|
polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject),
|
||||||
|
cancellable, NULL);
|
||||||
|
subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (process_subject));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subject_uid = getuid ();
|
||||||
|
subject = polkit_unix_process_new_for_owner (getpid (), 0, subject_uid);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the parental controls for the invoking user. */
|
|
||||||
subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject));
|
|
||||||
if (subject_uid == -1)
|
if (subject_uid == -1)
|
||||||
{
|
{
|
||||||
g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_AUTH_FAILED,
|
g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_AUTH_FAILED,
|
||||||
@@ -9155,6 +9167,8 @@ flatpak_dir_check_parental_controls (FlatpakDir *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_assert (subject != NULL);
|
||||||
|
|
||||||
manager = mct_manager_new (dbus_connection);
|
manager = mct_manager_new (dbus_connection);
|
||||||
manager_flags = MCT_MANAGER_GET_VALUE_FLAGS_NONE;
|
manager_flags = MCT_MANAGER_GET_VALUE_FLAGS_NONE;
|
||||||
if (!flatpak_dir_get_no_interaction (self))
|
if (!flatpak_dir_get_no_interaction (self))
|
||||||
@@ -17016,16 +17030,10 @@ flatpak_dir_get_locale_subpaths (FlatpakDir *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flatpak_dir_set_source_pid (FlatpakDir *self,
|
flatpak_dir_set_subject (FlatpakDir *self,
|
||||||
pid_t pid)
|
PolkitSubject *subject)
|
||||||
{
|
{
|
||||||
self->source_pid = pid;
|
g_set_object (&self->subject, subject);
|
||||||
}
|
|
||||||
|
|
||||||
pid_t
|
|
||||||
flatpak_dir_get_source_pid (FlatpakDir *self)
|
|
||||||
{
|
|
||||||
return self->source_pid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -17045,7 +17053,7 @@ static void
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_LIBSYSTEMD
|
#ifdef HAVE_LIBSYSTEMD
|
||||||
const char *installation = source ? source : flatpak_dir_get_name_cached (self);
|
const char *installation = source ? source : flatpak_dir_get_name_cached (self);
|
||||||
pid_t source_pid = flatpak_dir_get_source_pid (self);
|
const char *subject = self->subject ? polkit_subject_to_string (self->subject) : "(none)";
|
||||||
char message[1024];
|
char message[1024];
|
||||||
int len;
|
int len;
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -17061,7 +17069,7 @@ static void
|
|||||||
*/
|
*/
|
||||||
sd_journal_send ("MESSAGE_ID=" FLATPAK_MESSAGE_ID,
|
sd_journal_send ("MESSAGE_ID=" FLATPAK_MESSAGE_ID,
|
||||||
"PRIORITY=5",
|
"PRIORITY=5",
|
||||||
"OBJECT_PID=%d", source_pid,
|
"SUBJECT=%s", subject,
|
||||||
"CODE_FILE=%s", file,
|
"CODE_FILE=%s", file,
|
||||||
"CODE_LINE=%d", line,
|
"CODE_LINE=%d", line,
|
||||||
"CODE_FUNC=%s", func,
|
"CODE_FUNC=%s", func,
|
||||||
|
|||||||
@@ -226,56 +226,6 @@ schedule_idle_callback (void)
|
|||||||
G_UNLOCK (idle);
|
G_UNLOCK (idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DBUS_NAME_DBUS "org.freedesktop.DBus"
|
|
||||||
#define DBUS_INTERFACE_DBUS DBUS_NAME_DBUS
|
|
||||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
|
||||||
|
|
||||||
static int
|
|
||||||
get_sender_pid (GDBusMethodInvocation *invocation)
|
|
||||||
{
|
|
||||||
g_autoptr(GDBusMessage) msg = NULL;
|
|
||||||
g_autoptr(GDBusMessage) reply = NULL;
|
|
||||||
GDBusConnection *connection;
|
|
||||||
const char *sender;
|
|
||||||
GVariant *body;
|
|
||||||
g_autoptr(GVariantIter) iter = NULL;
|
|
||||||
const char *key;
|
|
||||||
g_autoptr(GVariant) value = NULL;
|
|
||||||
|
|
||||||
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
||||||
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
||||||
|
|
||||||
msg = g_dbus_message_new_method_call (DBUS_NAME_DBUS,
|
|
||||||
DBUS_PATH_DBUS,
|
|
||||||
DBUS_INTERFACE_DBUS,
|
|
||||||
"GetConnectionCredentials");
|
|
||||||
g_dbus_message_set_body (msg, g_variant_new ("(s)", sender));
|
|
||||||
|
|
||||||
reply = g_dbus_connection_send_message_with_reply_sync (connection, msg,
|
|
||||||
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
|
||||||
30000,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (reply == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
body = g_dbus_message_get_body (reply);
|
|
||||||
|
|
||||||
g_variant_get (body, "(a{sv})", &iter);
|
|
||||||
while (g_variant_iter_loop (iter, "{&sv}", &key, &value))
|
|
||||||
{
|
|
||||||
if (strcmp (key, "ProcessID") == 0)
|
|
||||||
return g_variant_get_uint32 (value);
|
|
||||||
}
|
|
||||||
value = NULL; /* g_variant_iter_loop freed it */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FlatpakDir *
|
static FlatpakDir *
|
||||||
dir_get_system (const char *installation,
|
dir_get_system (const char *installation,
|
||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
@@ -283,7 +233,8 @@ dir_get_system (const char *installation,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FlatpakDir *system = NULL;
|
FlatpakDir *system = NULL;
|
||||||
pid_t source_pid = invocation ? get_sender_pid (invocation) : 0;
|
const char *sender;
|
||||||
|
g_autoptr(AutoPolkitSubject) subject = NULL;
|
||||||
|
|
||||||
if (installation != NULL && *installation != '\0')
|
if (installation != NULL && *installation != '\0')
|
||||||
system = flatpak_dir_get_system_by_id (installation, NULL, error);
|
system = flatpak_dir_get_system_by_id (installation, NULL, error);
|
||||||
@@ -294,7 +245,10 @@ dir_get_system (const char *installation,
|
|||||||
if (system == NULL)
|
if (system == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
flatpak_dir_set_source_pid (system, source_pid);
|
sender = g_dbus_method_invocation_get_sender (invocation);
|
||||||
|
subject = polkit_system_bus_name_new (sender);
|
||||||
|
|
||||||
|
flatpak_dir_set_subject (system, subject);
|
||||||
flatpak_dir_set_no_system_helper (system, TRUE);
|
flatpak_dir_set_no_system_helper (system, TRUE);
|
||||||
flatpak_dir_set_no_interaction (system, no_interaction);
|
flatpak_dir_set_no_interaction (system, no_interaction);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user