summaryrefslogblamecommitdiffstats
path: root/source/l/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch
blob: 9431056bc1749051437533ef5a09f4ec70c36cb5 (plain) (tree)










































































































































                                                                                    
From dd848a42a64a3b22a0cc60f6657b56ce9b6010ae Mon Sep 17 00:00:00 2001
From: David Zeuthen <davidz@redhat.com>
Date: Thu, 31 Mar 2011 12:59:09 -0400
Subject: [PATCH 1/4] PolkitUnixProcess: Clarify that the real uid is
 returned, not the effective one

On Linux, also switch to parsing /proc/<pid>/status instead of relying
on the st_uid returned by stat(2) to be the uid we want.

This was pointed out by Neel Mehta <nmehta@google.com>. Thanks!

Signed-off-by: David Zeuthen <davidz@redhat.com>
---
 src/polkit/polkitunixprocess.c |   66 ++++++++++++++++++++++++++++++----------
 1 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
index d95a1d4..876da69 100644
--- a/src/polkit/polkitunixprocess.c
+++ b/src/polkit/polkitunixprocess.c
@@ -24,9 +24,7 @@
 #endif
 
 #include <sys/types.h>
-#ifndef HAVE_FREEBSD
-#include <sys/stat.h>
-#else
+#ifdef HAVE_FREEBSD
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/user.h>
@@ -34,6 +32,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <stdio.h>
 
 #include "polkitunixprocess.h"
 #include "polkitsubject.h"
@@ -208,6 +207,8 @@ polkit_unix_process_get_pid (PolkitUnixProcess *process)
  *
  * Gets the uid of the owner of @process.
  *
+ * Note that this returns the real user-id (not the effective user-id) of @process.
+ *
  * Returns: The UNIX user id of the owner for @process or 0 if @error is set.
  **/
 gint
@@ -215,17 +216,21 @@ polkit_unix_process_get_owner (PolkitUnixProcess  *process,
                                GError            **error)
 {
   gint result;
+  gchar *contents;
+  gchar **lines;
 #ifdef HAVE_FREEBSD
   struct kinfo_proc p;
 #else
-  struct stat statbuf;
-  char procbuf[32];
+  gchar filename[64];
+  guint n;
 #endif
 
   g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
   g_return_val_if_fail (error == NULL || *error == NULL, 0);
 
   result = 0;
+  lines = NULL;
+  contents = NULL;
 
 #ifdef HAVE_FREEBSD
   if (get_kinfo_proc (process->pid, &p) == 0)
@@ -241,23 +246,52 @@ polkit_unix_process_get_owner (PolkitUnixProcess  *process,
 
   result = p.ki_uid;
 #else
-  g_snprintf (procbuf, sizeof procbuf, "/proc/%d", process->pid);
-  if (stat (procbuf, &statbuf) != 0)
+
+  /* see 'man proc' for layout of the status file
+   *
+   * Uid, Gid: Real, effective, saved set,  and  file  system  UIDs (GIDs).
+   */
+  g_snprintf (filename, sizeof filename, "/proc/%d/status", process->pid);
+  if (!g_file_get_contents (filename,
+                            &contents,
+                            NULL,
+                            error))
     {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "stat() failed for /proc/%d: %s",
-                   process->pid,
-                   g_strerror (errno));
       goto out;
     }
+  lines = g_strsplit (contents, "\n", -1);
+  for (n = 0; lines != NULL && lines[n] != NULL; n++)
+    {
+      gint real_uid, effective_uid;
+      if (!g_str_has_prefix (lines[n], "Uid:"))
+        continue;
+      if (sscanf (lines[n] + 4, "%d %d", &real_uid, &effective_uid) != 2)
+        {
+          g_set_error (error,
+                       POLKIT_ERROR,
+                       POLKIT_ERROR_FAILED,
+                       "Unexpected line `%s' in file %s",
+                       lines[n],
+                       filename);
+          goto out;
+        }
+      else
+        {
+          result = real_uid;
+          goto out;
+        }
+    }
 
-  result = statbuf.st_uid;
+  g_set_error (error,
+               POLKIT_ERROR,
+               POLKIT_ERROR_FAILED,
+               "Didn't find any line starting with `Uid:' in file %s",
+               filename);
 #endif
 
- out:
-
+out:
+  g_strfreev (lines);
+  g_free (contents);
   return result;
 }
 
-- 
1.7.4.4