Hello community,

here is the log from the commit of package polkit for openSUSE:11.3
checked in at Wed Apr 27 09:55:41 CEST 2011.



--------
--- old-versions/11.3/all/polkit/polkit.changes 2010-04-14 15:46:06.000000000 
+0200
+++ 11.3/polkit/polkit.changes  2011-04-26 20:10:36.000000000 +0200
@@ -1,0 +2,5 @@
+Tue Apr 26 20:06:55 CEST 2011 - kay.siev...@novell.com
+
+- stat race condition (CVE-2011-1485) (bnc#688788)
+
+-------------------------------------------------------------------

Package does not exist at destination yet. Using Fallback 
old-versions/11.3/all/polkit
Destination is old-versions/11.3/UPDATES/all/polkit
calling whatdependson for 11.3-i586


New:
----
  polkit-CVE-2011-1485-1.patch
  polkit-CVE-2011-1485-2.patch
  polkit-CVE-2011-1485-3.patch
  polkit-CVE-2011-1485-4.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ polkit.spec ++++++
--- /var/tmp/diff_new_pack.IZRXj7/_old  2011-04-27 09:54:57.000000000 +0200
+++ /var/tmp/diff_new_pack.IZRXj7/_new  2011-04-27 09:54:57.000000000 +0200
@@ -1,7 +1,7 @@
 #
-# spec file for package polkit (Version 0.96)
+# spec file for package polkit
 #
-# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
 Name:           polkit
 Summary:        PolicyKit Authorization Framework
 Version:        0.96
-Release:        2
+Release:        5.<RELEASE2>
 License:        LGPLv2+
 Url:            http://www.freedesktop.org/wiki/Software/PolicyKit
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -36,7 +36,11 @@
 Source0:        http://hal.freedesktop.org/releases/%{name}-%{version}.tar.bz2
 Source99:       baselibs.conf
 Requires:       libpolkit0 = %{version}-%{release}
-Patch0:         pkexec-information-disclosure.patch
+Patch10:        polkit-CVE-2011-1485-1.patch
+Patch11:        polkit-CVE-2011-1485-2.patch
+Patch12:        polkit-CVE-2011-1485-3.patch
+Patch13:        polkit-CVE-2011-1485-4.patch
+Patch14:        pkexec-information-disclosure.patch
 
 %description
 PolicyKit is a toolkit for defining and handling authorizations.
@@ -80,7 +84,11 @@
 
 %prep
 %setup -q
-%patch0 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
 
 %build
 export V=1

++++++ pkexec-information-disclosure.patch ++++++
--- /var/tmp/diff_new_pack.IZRXj7/_old  2011-04-27 09:54:57.000000000 +0200
+++ /var/tmp/diff_new_pack.IZRXj7/_new  2011-04-27 09:54:57.000000000 +0200
@@ -1,4 +1,4 @@
-From 14bdfd816512a82b1ad258fa143ae5faa945df8a Mon Sep 17 00:00:00 2001
+From 28e485cac449c8eb37c21eecb95f5fa125def9d4 Mon Sep 17 00:00:00 2001
 From: Dan Rosenberg <dan.j.rosenb...@gmail.com>
 Date: Wed, 10 Mar 2010 17:46:19 +0000
 Subject: Bug 26982 – pkexec information disclosure vulnerability
@@ -34,18 +34,18 @@
 Signed-off-by: David Zeuthen <dav...@redhat.com>
 ---
 diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
-index 860e665..17c191e 100644
+index a7b7ba6..0c1dacd 100644
 --- a/src/programs/pkexec.c
 +++ b/src/programs/pkexec.c
-@@ -411,7 +411,6 @@ main (int argc, char *argv[])
+@@ -414,7 +414,6 @@ main (int argc, char *argv[])
+   GPtrArray *saved_env;
    gchar *opt_user;
    pid_t pid_of_caller;
-   uid_t uid_of_caller;
 -  struct stat statbuf;
  
    ret = 127;
    authority = NULL;
-@@ -520,9 +519,9 @@ main (int argc, char *argv[])
+@@ -523,9 +522,9 @@ main (int argc, char *argv[])
        g_free (path);
        argv[n] = path = s;
      }

++++++ polkit-CVE-2011-1485-1.patch ++++++
>From 83a65f1255fc3eebfb4be1f80a5ab0b5f98eef7c Mon Sep 17 00:00:00 2001
From: David Zeuthen <dav...@redhat.com>
Date: Mon, 11 Apr 2011 15:38:22 +0000
Subject: 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 <nme...@google.com>. Thanks!

Signed-off-by: David Zeuthen <dav...@redhat.com>
---
diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
index e132387..868e3c5 100644
--- a/src/polkit/polkitunixprocess.c
+++ b/src/polkit/polkitunixprocess.c
@@ -34,6 +34,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <stdio.h>
 
 #include "polkitunixprocess.h"
 #include "polkitsubject.h"
@@ -207,6 +208,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
@@ -214,14 +217,18 @@ 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
 
   result = 0;
+  lines = NULL;
+  contents = NULL;
 
 #ifdef HAVE_FREEBSD
   if (get_kinfo_proc (process->pid, &p) == 0)
@@ -237,22 +244,51 @@ 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:
+  g_strfreev (lines);
+  g_free (contents);
 
   return result;
 }
--
cgit v0.8.3-6-g21f6
++++++ polkit-CVE-2011-1485-2.patch ++++++
++++ 658 lines (skipped)

++++++ polkit-CVE-2011-1485-3.patch ++++++
>From 55e6f92e7340d57a66f83bd69bdf26454fdf7533 Mon Sep 17 00:00:00 2001
From: David Zeuthen <dav...@redhat.com>
Date: Mon, 11 Apr 2011 16:41:35 +0000
Subject: Use polkit_unix_process_get_uid() to get the owner of a process

This avoids a TOCTTOU problem.

Signed-off-by: David Zeuthen <dav...@redhat.com>
---
diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c 
b/src/polkitbackend/polkitbackendsessionmonitor.c
index 2028250..d976514 100644
--- a/src/polkitbackend/polkitbackendsessionmonitor.c
+++ b/src/polkitbackend/polkitbackendsessionmonitor.c
@@ -418,14 +418,13 @@ polkit_backend_session_monitor_get_user_for_subject 
(PolkitBackendSessionMonitor
 
   if (POLKIT_IS_UNIX_PROCESS (subject))
     {
-      GError *local_error;
-
-      local_error = NULL;
-      uid = polkit_unix_process_get_owner (POLKIT_UNIX_PROCESS (subject), 
&local_error);
-      if (local_error != NULL)
+      uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject));
+      if ((gint) uid == -1)
         {
-          g_propagate_error (error, local_error);
-          g_error_free (local_error);
+          g_set_error (error,
+                       POLKIT_ERROR,
+                       POLKIT_ERROR_FAILED,
+                       "Unix process subject does not have uid set");
           goto out;
         }
       user = polkit_unix_user_new (uid);
--
cgit v0.8.3-6-g21f6
++++++ polkit-CVE-2011-1485-4.patch ++++++
>From 5d44f404809ab0bdf277c1f49387b5339d02122e Mon Sep 17 00:00:00 2001
From: David Zeuthen <dav...@redhat.com>
Date: Mon, 11 Apr 2011 16:45:13 +0000
Subject: pkexec: Avoid TOCTTOU problems with parent process

In a nutshell, the parent process may change its uid (either real- or
effective uid) after launching pkexec. It can do this by exec()'ing
e.g. a setuid root program.

To avoid this problem, just use the uid the parent process had when it
executed pkexec. This happens to be the same uid of the pkexec process
itself.

Additionally, remove some dubious code that allowed pkexec to continue
when the parent process died as there is no reason to support
something like that. Also ensure that the pkexec process is killed if
the parent process dies.

This problem was pointed out by Neel Mehta <nme...@google.com>.

Signed-off-by: David Zeuthen <dav...@redhat.com>
---
diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
index 860e665..a7b7ba6 100644
--- a/src/programs/pkexec.c
+++ b/src/programs/pkexec.c
@@ -38,6 +38,10 @@
 #include <syslog.h>
 #include <stdarg.h>
 
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
 #include <polkit/polkit.h>
 
 static gchar *original_user_name = NULL;
@@ -410,7 +414,6 @@ main (int argc, char *argv[])
   GPtrArray *saved_env;
   gchar *opt_user;
   pid_t pid_of_caller;
-  uid_t uid_of_caller;
   struct stat statbuf;
 
   ret = 127;
@@ -579,40 +582,49 @@ main (int argc, char *argv[])
    */
   g_type_init ();
 
-  /* now check if the program that invoked us is authorized */
+  /* make sure we are nuked if the parent process dies */
+#ifdef __linux__
+  if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0)
+    {
+      g_printerr ("prctl(PR_SET_PDEATHSIG, SIGTERM) failed: %s\n", g_strerror 
(errno));
+      goto out;
+    }
+#else
+#warning "Please add OS specific code to catch when the parent dies"
+#endif
+
+  /* Figure out the parent process */
   pid_of_caller = getppid ();
   if (pid_of_caller == 1)
     {
       /* getppid() can return 1 if the parent died (meaning that we are reaped
-       * by /sbin/init); get process group leader instead - for example, this
-       * happens when launching via gnome-panel (alt+f2, then 'pkexec gedit').
+       * by /sbin/init); In that case we simpy bail.
        */
-      pid_of_caller = getpgrp ();
-    }
-
-  subject = polkit_unix_process_new (pid_of_caller);
-  if (subject == NULL)
-    {
-      g_printerr ("No such process for pid %d: %s\n", (gint) pid_of_caller, 
error->message);
-      g_error_free (error);
+      g_printerr ("Refusing to render service to dead parents.\n");
       goto out;
     }
 
-  /* paranoia: check that the uid of pid_of_caller matches getuid() */
-  error = NULL;
-  uid_of_caller = polkit_unix_process_get_owner (POLKIT_UNIX_PROCESS (subject),
-                                                 &error);
-  if (error != NULL)
-    {
-      g_printerr ("Error determing pid of caller (pid %d): %s\n", (gint) 
pid_of_caller, error->message);
-      g_error_free (error);
-      goto out;
-    }
-  if (uid_of_caller != getuid ())
-    {
-      g_printerr ("User of caller (%d) does not match our uid (%d)\n", 
uid_of_caller, getuid ());
-      goto out;
-    }
+  /* This process we want to check an authorization for is the process
+   * that launched us - our parent process.
+   *
+   * At the time the parent process fork()'ed and exec()'ed us, the
+   * process had the same real-uid that we have now. So we use this
+   * real-uid instead of of looking it up to avoid TOCTTOU issues
+   * (consider the parent process exec()'ing a setuid helper).
+   *
+   * On the other hand, the monotonic process start-time is guaranteed
+   * to never change so it's safe to look that up given only the PID
+   * since we are guaranteed to be nuked if the parent goes away
+   * (cf. the prctl(2) call above).
+   */
+  subject = polkit_unix_process_new_for_owner (pid_of_caller,
+                                               0, /* 0 means "look up 
start-time in /proc" */
+                                               getuid ());
+  /* really double-check the invariants guaranteed by the PolkitUnixProcess 
class */
+  g_assert (subject != NULL);
+  g_assert (polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject)) == 
pid_of_caller);
+  g_assert (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0);
+  g_assert (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) 
> 0);
 
   authority = polkit_authority_get ();
 
--
cgit v0.8.3-6-g21f6

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to