From 357bbde5ca0942bb787b22cb83f6ae87fb298cb1 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Thu, 8 Jan 2009 16:25:07 -0500 Subject: [PATCH] polkit_caller_new_from_pid: use the real uid, as documented https://bugs.freedesktop.org/show_bug.cgi?id=19469 --- src/polkit-dbus/polkit-dbus.c | 33 ++++++++++++++++++++++++++------- 1 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/polkit-dbus/polkit-dbus.c b/src/polkit-dbus/polkit-dbus.c index f7be03f..2efbf2a 100644 --- a/src/polkit-dbus/polkit-dbus.c +++ b/src/polkit-dbus/polkit-dbus.c @@ -603,8 +603,9 @@ polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error) DBusMessage *reply; DBusMessageIter iter; char *str; - char *proc_path; - struct stat statbuf; + char *proc_status_path; + FILE *proc_status; + char proc_status_buf[128]; #ifdef HAVE_SELINUX security_context_t secon; #endif @@ -621,7 +622,7 @@ polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error) uid = (uid_t) -1; caller = NULL; session = NULL; - proc_path = NULL; + proc_status_path = NULL; #ifdef POLKIT_BUILD_TESTS char *pretend; @@ -642,12 +643,30 @@ polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error) #endif if (uid == (uid_t) -1) { - proc_path = kit_strdup_printf ("/proc/%d", pid); - if (proc_path && stat (proc_path, &statbuf) != 0) { + /* Extract the real uid from /proc/pid/status . */ + if ((proc_status_path = kit_strdup_printf ("/proc/%d/status", pid)) != NULL + && (proc_status = fopen (proc_status_path, "r")) != NULL) { + /* Successfully opened the file; now parse it. */ + while (fgets (proc_status_buf, sizeof (proc_status_buf), proc_status) != NULL) { + /* Abort if line was longer than we planned for (shouldn't happen on Linux). */ + size_t len = strlen (proc_status_buf); + if (len == 0 || proc_status_buf[len - 1] != '\n') + break; + if (strncmp (proc_status_buf, "Uid:", 4) == 0) { + /* The real uid is the first of the four numbers on the line. + * On error, the uid simply won't be set. */ + sscanf (proc_status_buf, "Uid: %d", &uid); + break; + } + } + fclose (proc_status); + } + if (uid == (uid_t) -1) { + /* For one reason or another, we didn't get the uid. */ kit_warning ("Cannot lookup information for pid %d: %s", pid, strerror (errno)); goto out; } - uid = statbuf.st_uid; + polkit_debug ("Got real uid %d for pid %d", uid, pid); } #ifdef HAVE_SELINUX @@ -769,7 +788,7 @@ not_in_session: out: kit_free (selinux_context); kit_free (ck_session_objpath); - kit_free (proc_path); + kit_free (proc_status_path); return caller; } -- 1.6.1.34.gf5a74