From 390c95ecb8097b6c68027dabecd6b76639ceb324 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Mar 2017 14:50:17 +0200 Subject: [PATCH] client-info: Replace desktop ID detection For newer (>= 0.6.10) versions of Flatpak, the way to export the desktop ID has changed from requiring cgroups to not requiring it. See https://github.com/flatpak/flatpak/releases/tag/0.6.10 https://bugs.freedesktop.org/show_bug.cgi?id=97776 --- src/gclue-client-info.c | 110 ++++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/gclue-client-info.c b/src/gclue-client-info.c index 1a47669..0854b53 100644 --- a/src/gclue-client-info.c +++ b/src/gclue-client-info.c @@ -21,6 +21,9 @@ */ #include +#include +#include +#include #include "gclue-client-info.h" @@ -181,52 +184,77 @@ on_name_vanished (GDBusConnection *connection, 0); } -/* Based on got_credentials_cb() from xdg-app source code */ +/* Based on xdp_get_app_id_from_pid() from xdg-desktop-portal */ +static GKeyFile * +parse_app_info_from_fileinfo (int pid) +{ + g_autofree char *root_path = NULL; + g_autofree char *path = NULL; + g_autofree char *content = NULL; + g_autofree char *app_id = NULL; + int root_fd = -1; + int info_fd = -1; + struct stat stat_buf; + g_autoptr(GError) local_error = NULL; + g_autoptr(GMappedFile) mapped = NULL; + g_autoptr(GKeyFile) metadata = NULL; + + root_path = g_strdup_printf ("/proc/%u/root", pid); + root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); + if (root_fd == -1) + { + /* Not able to open the root dir shouldn't happen. Probably the app died and + we're failing due to /proc/$pid not existing. In that case fail instead + of treating this as privileged. */ + return NULL; + } + + metadata = g_key_file_new (); + + info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY); + close (root_fd); + if (info_fd == -1) + { + /* No file => on the host or some weird error => failure */ + return NULL; + } + + if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) + { + /* Some weird fd => failure */ + close (info_fd); + return NULL; + } + + mapped = g_mapped_file_new_from_fd (info_fd, FALSE, &local_error); + if (mapped == NULL) + { + close (info_fd); + return NULL; + } + + if (!g_key_file_load_from_data (metadata, + g_mapped_file_get_contents (mapped), + g_mapped_file_get_length (mapped), + G_KEY_FILE_NONE, &local_error)) + { + close (info_fd); + return NULL; + } + + return g_steal_pointer (&metadata); +} + static char * get_xdg_id (guint32 pid) { - char *xdg_id = NULL; - g_autofree char *path = NULL; - g_autofree char *content = NULL; - gchar **lines; - int i; - - path = g_strdup_printf ("/proc/%u/cgroup", pid); - - if (!g_file_get_contents (path, &content, NULL, NULL)) - return NULL; - lines = g_strsplit (content, "\n", -1); - - for (i = 0; lines[i] != NULL; i++) { - const char *unit = lines[i] + strlen ("1:name=systemd:"); - g_autofree char *scope = NULL; - const char *name; - char *dash; - - if (!g_str_has_prefix (lines[i], "1:name=systemd:")) - continue; - - scope = g_path_get_basename (unit); - if ((!g_str_has_prefix (scope, "xdg-app-") && - !g_str_has_prefix (scope, "flatpak-")) || - !g_str_has_suffix (scope, ".scope")) - break; - - /* strlen("flatpak-") == strlen("xdg-app-") - * so all is good here */ - name = scope + strlen("xdg-app-"); - dash = strchr (name, '-'); - - if (dash == NULL) - break; - - *dash = 0; - xdg_id = g_strdup (name); - } + g_autoptr(GKeyFile) app_info = NULL; - g_strfreev (lines); + app_info = parse_app_info_from_fileinfo (pid); + if (app_info == NULL) + return NULL; - return xdg_id; + return g_key_file_get_string (app_info, "Application", "name", NULL); } static void -- 2.12.0