summaryrefslogtreecommitdiff
path: root/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch')
-rw-r--r--patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch97
1 files changed, 97 insertions, 0 deletions
diff --git a/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch b/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch
new file mode 100644
index 00000000..e17947a9
--- /dev/null
+++ b/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch
@@ -0,0 +1,97 @@
+--- ./src/programs/pkexec.c.orig 2010-03-10 11:46:19.000000000 -0600
++++ ./src/programs/pkexec.c 2011-04-19 23:14:40.505000017 -0500
+@@ -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 @@
+ GPtrArray *saved_env;
+ gchar *opt_user;
+ pid_t pid_of_caller;
+- uid_t uid_of_caller;
+
+ ret = 127;
+ authority = NULL;
+@@ -578,40 +581,49 @@
+ */
+ 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 ();
+