diff options
Diffstat (limited to 'source/l/polkit')
8 files changed, 43 insertions, 942 deletions
diff --git a/source/l/polkit/10-org.freedesktop.NetworkManager.pkla b/source/l/polkit/10-org.freedesktop.NetworkManager.pkla new file mode 100644 index 00000000..b2491602 --- /dev/null +++ b/source/l/polkit/10-org.freedesktop.NetworkManager.pkla @@ -0,0 +1,6 @@ +[nm-applet] +Identity=unix-group:netdev +Action=org.freedesktop.NetworkManager.* +ResultAny=yes +ResultInactive=no +ResultActive=yes diff --git a/source/l/polkit/20-plugdev-group-mount-override.pkla b/source/l/polkit/20-plugdev-group-mount-override.pkla new file mode 100644 index 00000000..8149de67 --- /dev/null +++ b/source/l/polkit/20-plugdev-group-mount-override.pkla @@ -0,0 +1,6 @@ +[plugdev group mount override] +Identity=unix-group:plugdev +Action=org.freedesktop.udisks2.filesystem-*;org.freedesktop.udisks2.eject-* +ResultAny=yes +ResultInactive=yes +ResultActive=yes diff --git a/source/l/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch b/source/l/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch deleted file mode 100644 index 9431056b..00000000 --- a/source/l/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch +++ /dev/null @@ -1,139 +0,0 @@ -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 - diff --git a/source/l/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch b/source/l/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch deleted file mode 100644 index 81a163c6..00000000 --- a/source/l/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch +++ /dev/null @@ -1,623 +0,0 @@ -From 129b6223a19e7fb2753f8cad7957ac5402394076 Mon Sep 17 00:00:00 2001 -From: David Zeuthen <davidz@redhat.com> -Date: Fri, 1 Apr 2011 12:09:45 -0400 -Subject: [PATCH 2/4] Make PolkitUnixProcess also record the uid of the - process - -This is needed to avoid possible TOCTTOU issues since a process can -change both its real uid and effective uid. - -Signed-off-by: David Zeuthen <davidz@redhat.com> ---- - docs/polkit/polkit-1-sections.txt | 7 +- - src/polkit/polkitsubject.c | 25 +++- - src/polkit/polkitunixprocess.c | 346 +++++++++++++++++++++++++------------ - src/polkit/polkitunixprocess.h | 18 ++- - 4 files changed, 278 insertions(+), 118 deletions(-) - -diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt -index 12141e3..9f4fcf8 100644 ---- a/docs/polkit/polkit-1-sections.txt -+++ b/docs/polkit/polkit-1-sections.txt -@@ -145,10 +145,13 @@ POLKIT_UNIX_SESSION_GET_CLASS - PolkitUnixProcess - polkit_unix_process_new - polkit_unix_process_new_full -+polkit_unix_process_new_for_owner -+polkit_unix_process_set_pid - polkit_unix_process_get_pid -+polkit_unix_process_set_start_time - polkit_unix_process_get_start_time --polkit_unix_process_set_pid --polkit_unix_process_get_owner -+polkit_unix_process_set_uid -+polkit_unix_process_get_uid - <SUBSECTION Standard> - PolkitUnixProcessClass - POLKIT_UNIX_PROCESS -diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c -index 577afec..d2c4c20 100644 ---- a/src/polkit/polkitsubject.c -+++ b/src/polkit/polkitsubject.c -@@ -238,13 +238,18 @@ polkit_subject_from_string (const gchar *str, - { - gint scanned_pid; - guint64 scanned_starttime; -- if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT, &scanned_pid, &scanned_starttime) == 2) -+ gint scanned_uid; -+ if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT ":%d", &scanned_pid, &scanned_starttime, &scanned_uid) == 3) -+ { -+ subject = polkit_unix_process_new_for_owner (scanned_pid, scanned_starttime, scanned_uid); -+ } -+ else if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT, &scanned_pid, &scanned_starttime) == 2) - { - subject = polkit_unix_process_new_full (scanned_pid, scanned_starttime); - } - else if (sscanf (str, "unix-process:%d", &scanned_pid) == 1) - { -- subject = polkit_unix_process_new_full (scanned_pid, 0); -+ subject = polkit_unix_process_new (scanned_pid); - if (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) == 0) - { - g_object_unref (subject); -@@ -297,6 +302,8 @@ polkit_subject_to_gvariant (PolkitSubject *subject) - g_variant_new_uint32 (polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject)))); - g_variant_builder_add (&builder, "{sv}", "start-time", - g_variant_new_uint64 (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)))); -+ g_variant_builder_add (&builder, "{sv}", "uid", -+ g_variant_new_int32 (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)))); - } - else if (POLKIT_IS_UNIX_SESSION (subject)) - { -@@ -395,6 +402,7 @@ polkit_subject_new_for_gvariant (GVariant *variant, - GVariant *v; - guint32 pid; - guint64 start_time; -+ gint32 uid; - - v = lookup_asv (details_gvariant, "pid", G_VARIANT_TYPE_UINT32, error); - if (v == NULL) -@@ -414,7 +422,18 @@ polkit_subject_new_for_gvariant (GVariant *variant, - start_time = g_variant_get_uint64 (v); - g_variant_unref (v); - -- ret = polkit_unix_process_new_full (pid, start_time); -+ v = lookup_asv (details_gvariant, "uid", G_VARIANT_TYPE_INT32, error); -+ if (v != NULL) -+ { -+ uid = g_variant_get_int32 (v); -+ g_variant_unref (v); -+ } -+ else -+ { -+ uid = -1; -+ } -+ -+ ret = polkit_unix_process_new_for_owner (pid, start_time, uid); - } - else if (g_strcmp0 (kind, "unix-session") == 0) - { -diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c -index 876da69..913be3a 100644 ---- a/src/polkit/polkitunixprocess.c -+++ b/src/polkit/polkitunixprocess.c -@@ -62,6 +62,7 @@ struct _PolkitUnixProcess - - gint pid; - guint64 start_time; -+ gint uid; - }; - - struct _PolkitUnixProcessClass -@@ -74,6 +75,7 @@ enum - PROP_0, - PROP_PID, - PROP_START_TIME, -+ PROP_UID - }; - - static void subject_iface_init (PolkitSubjectIface *subject_iface); -@@ -81,6 +83,9 @@ static void subject_iface_init (PolkitSubjectIface *subject_iface); - static guint64 get_start_time_for_pid (gint pid, - GError **error); - -+static gint _polkit_unix_process_get_owner (PolkitUnixProcess *process, -+ GError **error); -+ - #ifdef HAVE_FREEBSD - static gboolean get_kinfo_proc (gint pid, struct kinfo_proc *p); - #endif -@@ -92,6 +97,7 @@ G_DEFINE_TYPE_WITH_CODE (PolkitUnixProcess, polkit_unix_process, G_TYPE_OBJECT, - static void - polkit_unix_process_init (PolkitUnixProcess *unix_process) - { -+ unix_process->uid = -1; - } - - static void -@@ -108,6 +114,10 @@ polkit_unix_process_get_property (GObject *object, - g_value_set_int (value, unix_process->pid); - break; - -+ case PROP_UID: -+ g_value_set_int (value, unix_process->uid); -+ break; -+ - case PROP_START_TIME: - g_value_set_uint64 (value, unix_process->start_time); - break; -@@ -132,6 +142,14 @@ polkit_unix_process_set_property (GObject *object, - polkit_unix_process_set_pid (unix_process, g_value_get_int (value)); - break; - -+ case PROP_UID: -+ polkit_unix_process_set_uid (unix_process, g_value_get_int (value)); -+ break; -+ -+ case PROP_START_TIME: -+ polkit_unix_process_set_start_time (unix_process, g_value_get_uint64 (value)); -+ break; -+ - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; -@@ -139,12 +157,39 @@ polkit_unix_process_set_property (GObject *object, - } - - static void -+polkit_unix_process_constructed (GObject *object) -+{ -+ PolkitUnixProcess *process = POLKIT_UNIX_PROCESS (object); -+ -+ /* sets start_time and uid in case they are unset */ -+ -+ if (process->start_time == 0) -+ process->start_time = get_start_time_for_pid (process->pid, NULL); -+ -+ if (process->uid == -1) -+ { -+ GError *error; -+ error = NULL; -+ process->uid = _polkit_unix_process_get_owner (process, &error); -+ if (error != NULL) -+ { -+ process->uid = -1; -+ g_error_free (error); -+ } -+ } -+ -+ if (G_OBJECT_CLASS (polkit_unix_process_parent_class)->constructed != NULL) -+ G_OBJECT_CLASS (polkit_unix_process_parent_class)->constructed (object); -+} -+ -+static void - polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->get_property = polkit_unix_process_get_property; - gobject_class->set_property = polkit_unix_process_set_property; -+ gobject_class->constructed = polkit_unix_process_constructed; - - /** - * PolkitUnixProcess:pid: -@@ -156,7 +201,7 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - g_param_spec_int ("pid", - "Process ID", - "The UNIX process ID", -- -1, -+ 0, - G_MAXINT, - 0, - G_PARAM_CONSTRUCT | -@@ -166,6 +211,27 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - G_PARAM_STATIC_NICK)); - - /** -+ * PolkitUnixProcess:uid: -+ * -+ * The UNIX user id of the process or -1 if unknown. -+ * -+ * Note that this is the real user-id, not the effective user-id. -+ */ -+ g_object_class_install_property (gobject_class, -+ PROP_UID, -+ g_param_spec_int ("uid", -+ "User ID", -+ "The UNIX user ID", -+ -1, -+ G_MAXINT, -+ -1, -+ G_PARAM_CONSTRUCT | -+ G_PARAM_READWRITE | -+ G_PARAM_STATIC_NAME | -+ G_PARAM_STATIC_BLURB | -+ G_PARAM_STATIC_NICK)); -+ -+ /** - * PolkitUnixProcess:start-time: - * - * The start time of the process. -@@ -178,7 +244,8 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - 0, - G_MAXUINT64, - 0, -- G_PARAM_READABLE | -+ G_PARAM_CONSTRUCT | -+ G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_BLURB | - G_PARAM_STATIC_NICK)); -@@ -186,113 +253,50 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - } - - /** -- * polkit_unix_process_get_pid: -+ * polkit_unix_process_get_uid: - * @process: A #PolkitUnixProcess. - * -- * Gets the process id for @process. -+ * Gets the user id for @process. Note that this is the real user-id, -+ * not the effective user-id. - * -- * Returns: The process id for @process. -+ * Returns: The user id for @process or -1 if unknown. - */ - gint --polkit_unix_process_get_pid (PolkitUnixProcess *process) -+polkit_unix_process_get_uid (PolkitUnixProcess *process) - { -- g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0); -- return process->pid; -+ g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), -1); -+ return process->uid; - } - - /** -- * polkit_unix_process_get_owner: -+ * polkit_unix_process_set_uid: - * @process: A #PolkitUnixProcess. -- * @error: (allow-none): Return location for error or %NULL. -+ * @uid: The user id to set for @process or -1 to unset it. - * -- * Gets the uid of the owner of @process. -+ * Sets the (real, not effective) user id for @process. -+ */ -+void -+polkit_unix_process_set_uid (PolkitUnixProcess *process, -+ gint uid) -+{ -+ g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process)); -+ g_return_if_fail (uid >= -1); -+ process->uid = uid; -+} -+ -+/** -+ * polkit_unix_process_get_pid: -+ * @process: A #PolkitUnixProcess. - * -- * Note that this returns the real user-id (not the effective user-id) of @process. -+ * Gets the process id for @process. - * -- * Returns: The UNIX user id of the owner for @process or 0 if @error is set. -- **/ -+ * Returns: The process id for @process. -+ */ - gint --polkit_unix_process_get_owner (PolkitUnixProcess *process, -- GError **error) -+polkit_unix_process_get_pid (PolkitUnixProcess *process) - { -- gint result; -- gchar *contents; -- gchar **lines; --#ifdef HAVE_FREEBSD -- struct kinfo_proc p; --#else -- 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) -- { -- g_set_error (error, -- POLKIT_ERROR, -- POLKIT_ERROR_FAILED, -- "get_kinfo_proc() failed for pid %d: %s", -- process->pid, -- g_strerror (errno)); -- goto out; -- } -- -- result = p.ki_uid; --#else -- -- /* 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)) -- { -- 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; -- } -- } -- -- 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; -+ return process->pid; - } - - /** -@@ -311,6 +315,21 @@ polkit_unix_process_get_start_time (PolkitUnixProcess *process) - } - - /** -+ * polkit_unix_process_set_start_time: -+ * @process: A #PolkitUnixProcess. -+ * @start_time: The start time for @pid. -+ * -+ * Set the start time of @process. -+ */ -+void -+polkit_unix_process_set_start_time (PolkitUnixProcess *process, -+ guint64 start_time) -+{ -+ g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process)); -+ process->start_time = start_time; -+} -+ -+/** - * polkit_unix_process_set_pid: - * @process: A #PolkitUnixProcess. - * @pid: A process id. -@@ -323,18 +342,17 @@ polkit_unix_process_set_pid (PolkitUnixProcess *process, - { - g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process)); - process->pid = pid; -- if (pid != (gint) -1) -- process->start_time = get_start_time_for_pid (pid, NULL); - } - - /** - * polkit_unix_process_new: - * @pid: The process id. - * -- * Creates a new #PolkitUnixProcess for @pid. The start time of the -- * process will be looked up in using e.g. the -- * <filename>/proc</filename> filesystem depending on the platform in -- * use. -+ * Creates a new #PolkitUnixProcess for @pid. -+ * -+ * The uid and start time of the process will be looked up in using -+ * e.g. the <filename>/proc</filename> filesystem depending on the -+ * platform in use. - * - * Returns: (transfer full): A #PolkitSubject. Free with g_object_unref(). - */ -@@ -353,22 +371,42 @@ polkit_unix_process_new (gint pid) - * - * Creates a new #PolkitUnixProcess object for @pid and @start_time. - * -+ * The uid of the process will be looked up in using e.g. the -+ * <filename>/proc</filename> filesystem depending on the platform in -+ * use. -+ * - * Returns: (transfer full): A #PolkitSubject. Free with g_object_unref(). - */ - PolkitSubject * - polkit_unix_process_new_full (gint pid, - guint64 start_time) - { -- PolkitUnixProcess *process; -- -- process = POLKIT_UNIX_PROCESS (polkit_unix_process_new ((gint) -1)); -- process->pid = pid; -- if (start_time != 0) -- process->start_time = start_time; -- else -- process->start_time = get_start_time_for_pid (pid, NULL); -+ return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_UNIX_PROCESS, -+ "pid", pid, -+ "start_time", start_time, -+ NULL)); -+} - -- return POLKIT_SUBJECT (process); -+/** -+ * polkit_unix_process_new_for_owner: -+ * @pid: The process id. -+ * @start_time: The start time for @pid or 0 to look it up in e.g. <filename>/proc</filename>. -+ * @uid: The (real, not effective) uid of the owner of @pid or -1 to look it up in e.g. <filename>/proc</filename>. -+ * -+ * Creates a new #PolkitUnixProcess object for @pid, @start_time and @uid. -+ * -+ * Returns: (transfer full): A #PolkitSubject. Free with g_object_unref(). -+ */ -+PolkitSubject * -+polkit_unix_process_new_for_owner (gint pid, -+ guint64 start_time, -+ gint uid) -+{ -+ return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_UNIX_PROCESS, -+ "pid", pid, -+ "start_time", start_time, -+ "uid", uid, -+ NULL)); - } - - static guint -@@ -616,3 +654,95 @@ out: - - return start_time; - } -+ -+static gint -+_polkit_unix_process_get_owner (PolkitUnixProcess *process, -+ GError **error) -+{ -+ gint result; -+ gchar *contents; -+ gchar **lines; -+#ifdef HAVE_FREEBSD -+ struct kinfo_proc p; -+#else -+ 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) -+ { -+ g_set_error (error, -+ POLKIT_ERROR, -+ POLKIT_ERROR_FAILED, -+ "get_kinfo_proc() failed for pid %d: %s", -+ process->pid, -+ g_strerror (errno)); -+ goto out; -+ } -+ -+ result = p.ki_uid; -+#else -+ -+ /* 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)) -+ { -+ 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; -+ } -+ } -+ -+ 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; -+} -+ -+/* deprecated public method */ -+gint -+polkit_unix_process_get_owner (PolkitUnixProcess *process, -+ GError **error) -+{ -+ return _polkit_unix_process_get_owner (process, error); -+} -diff --git a/src/polkit/polkitunixprocess.h b/src/polkit/polkitunixprocess.h -index b88cd03..531a57d 100644 ---- a/src/polkit/polkitunixprocess.h -+++ b/src/polkit/polkitunixprocess.h -@@ -47,16 +47,24 @@ typedef struct _PolkitUnixProcess PolkitUnixProcess; - typedef struct _PolkitUnixProcessClass PolkitUnixProcessClass; - - GType polkit_unix_process_get_type (void) G_GNUC_CONST; --PolkitSubject *polkit_unix_process_new (gint pid); --PolkitSubject *polkit_unix_process_new_full (gint pid, -- guint64 start_time); -- -+PolkitSubject *polkit_unix_process_new (gint pid); -+PolkitSubject *polkit_unix_process_new_full (gint pid, -+ guint64 start_time); -+PolkitSubject *polkit_unix_process_new_for_owner (gint pid, -+ guint64 start_time, -+ gint uid); - gint polkit_unix_process_get_pid (PolkitUnixProcess *process); - guint64 polkit_unix_process_get_start_time (PolkitUnixProcess *process); -+gint polkit_unix_process_get_uid (PolkitUnixProcess *process); - void polkit_unix_process_set_pid (PolkitUnixProcess *process, - gint pid); -+void polkit_unix_process_set_uid (PolkitUnixProcess *process, -+ gint uid); -+void polkit_unix_process_set_start_time (PolkitUnixProcess *process, -+ guint64 start_time); -+ - gint polkit_unix_process_get_owner (PolkitUnixProcess *process, -- GError **error); -+ GError **error) G_GNUC_DEPRECATED_FOR (polkit_unix_process_get_uid); - - G_END_DECLS - --- -1.7.4.4 - diff --git a/source/l/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch b/source/l/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch deleted file mode 100644 index 90d9352e..00000000 --- a/source/l/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c23d74447c7615dc74dae259f0fc3688ec988867 Mon Sep 17 00:00:00 2001 -From: David Zeuthen <davidz@redhat.com> -Date: Fri, 1 Apr 2011 12:12:27 -0400 -Subject: [PATCH 3/4] Use polkit_unix_process_get_uid() to get the owner of a - process - -This avoids a TOCTTOU problem. - -Signed-off-by: David Zeuthen <davidz@redhat.com> ---- - src/polkitbackend/polkitbackendsessionmonitor.c | 11 ++++++----- - 1 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c -index 495f752..9c331b6 100644 ---- a/src/polkitbackend/polkitbackendsessionmonitor.c -+++ b/src/polkitbackend/polkitbackendsessionmonitor.c -@@ -293,14 +293,15 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor - - if (POLKIT_IS_UNIX_PROCESS (subject)) - { -- 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_prefixed_error (error, local_error, "Error getting user for process: "); -+ g_set_error (error, -+ POLKIT_ERROR, -+ POLKIT_ERROR_FAILED, -+ "Unix process subject does not have uid set"); - goto out; - } -- - ret = polkit_unix_user_new (uid); - } - else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) --- -1.7.4.4 - diff --git a/source/l/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch b/source/l/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch deleted file mode 100644 index 8572f732..00000000 --- a/source/l/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 3b12cfac29dddd27f1f166a7574d8374cc1dccf2 Mon Sep 17 00:00:00 2001 -From: David Zeuthen <davidz@redhat.com> -Date: Fri, 1 Apr 2011 12:13:15 -0400 -Subject: [PATCH 4/4] 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 <nmehta@google.com>. - -Signed-off-by: David Zeuthen <davidz@redhat.com> ---- - src/programs/pkexec.c | 66 +++++++++++++++++++++++++++++-------------------- - 1 files changed, 39 insertions(+), 27 deletions(-) - -diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c -index 9217954..3e656be 100644 ---- a/src/programs/pkexec.c -+++ b/src/programs/pkexec.c -@@ -35,6 +35,10 @@ - #include <pwd.h> - #include <errno.h> - -+#ifdef __linux__ -+#include <sys/prctl.h> -+#endif -+ - #include <glib/gi18n.h> - - #ifdef POLKIT_AUTHFW_PAM -@@ -423,7 +427,6 @@ main (int argc, char *argv[]) - GPtrArray *saved_env; - gchar *opt_user; - pid_t pid_of_caller; -- uid_t uid_of_caller; - gpointer local_agent_handle; - - ret = 127; -@@ -598,40 +601,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); - - error = NULL; - authority = polkit_authority_get_sync (NULL /* GCancellable* */, &error); --- -1.7.4.4 - diff --git a/source/l/polkit/doinst.sh b/source/l/polkit/doinst.sh new file mode 100644 index 00000000..bce9ca90 --- /dev/null +++ b/source/l/polkit/doinst.sh @@ -0,0 +1,13 @@ +config() { + NEW="$1" + OLD="`dirname $NEW`/`basename $NEW .new`" + # If there's no config file by that name, mv it over: + if [ ! -r $OLD ]; then + mv $NEW $OLD + elif [ "`cat $OLD | md5sum`" = "`cat $NEW | md5sum`" ]; then # toss the redundant copy + rm $NEW + fi + # Otherwise, we leave the .new copy for the admin to consider... +} +config etc/polkit-1/localauthority/50-local.d/20-plugdev-group-mount-override.pkla.new +config etc/polkit-1/localauthority/50-local.d/10-org.freedesktop.NetworkManager.pkla.new diff --git a/source/l/polkit/polkit.SlackBuild b/source/l/polkit/polkit.SlackBuild index 7aa40f5d..a4bb9fc1 100755 --- a/source/l/polkit/polkit.SlackBuild +++ b/source/l/polkit/polkit.SlackBuild @@ -2,7 +2,7 @@ # Copyright 2009, 2011 Robby Workman, Northport, Alabama, USA # Copyright 2010 Eric Hameleers, Eindhoven, NL -# Copyright 2009, 2010, 2011 Patrick J. Volkerding, Sebeka, MN, USA +# Copyright 2009, 2010, 2011, 2012 Patrick J. Volkerding, Sebeka, MN, USA # All rights reserved. # Redistribution and use of this script, with or without modification, is @@ -25,7 +25,7 @@ PKGNAM=polkit VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z* | rev | cut -f 3- -d . | cut -f 1 -d - | rev)} -BUILD=${BUILD:-2} +BUILD=${BUILD:-3} # Automatically determine the architecture we're building on: if [ -z "$ARCH" ]; then @@ -72,12 +72,6 @@ find . \ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \ -exec chmod 644 {} \; -# https://bugzilla.redhat.com/show_bug.cgi?id=692922 -patch -p1 < $CWD/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch || exit 1 -patch -p1 < $CWD/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch || exit 1 -patch -p1 < $CWD/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch || exit 1 -patch -p1 < $CWD/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch || exit 1 - CFLAGS="$SLKCFLAGS" \ CXXFLAGS="$SLKCFLAGS" \ ./configure \ @@ -90,7 +84,7 @@ CXXFLAGS="$SLKCFLAGS" \ --enable-gtk-doc \ --mandir=/usr/man \ --disable-static \ - --disable-introspection \ + --enable-introspection \ --with-authfw=shadow \ --enable-verbose-mode \ --with-os-type=Slackware \ @@ -109,6 +103,10 @@ CXXFLAGS="$SLKCFLAGS" \ make $NUMJOBS || make || exit 1 make install DESTDIR=$PKG || exit 1 +# Add default policy files for udisks2 and NetworkManager events: +cat $CWD/20-plugdev-group-mount-override.pkla > $PKG/etc/polkit-1/localauthority/50-local.d/20-plugdev-group-mount-override.pkla.new +cat $CWD/10-org.freedesktop.NetworkManager.pkla > $PKG/etc/polkit-1/localauthority/50-local.d/10-org.freedesktop.NetworkManager.pkla.new + # Strip binaries: find $PKG | xargs file | grep -e "executable" -e "shared object" \ | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null @@ -131,12 +129,20 @@ fi # Add a documentation directory: mkdir -p $PKG/usr/doc/$PKGNAM-$VERSION cp -a \ - AUTHORS COPYING ChangeLog HACKING INSTALL NEWS README \ + AUTHORS COPYING HACKING INSTALL NEWS README \ $PKG/usr/doc/$PKGNAM-$VERSION -( cd $PKG/usr/doc/$PKGNAM-$VERSION; ln -s ../../share/gtk-doc/html/polkit-1 html -) +( cd $PKG/usr/doc/$PKGNAM-$VERSION; ln -s ../../share/gtk-doc/html/polkit-1 html ) + +# If there's a ChangeLog, installing at least part of the recent history +# is useful, but don't let it get totally out of control: +if [ -r ChangeLog ]; then + DOCSDIR=$(echo $PKG/usr/doc/*-$VERSION) + cat ChangeLog | head -n 1000 > $DOCSDIR/ChangeLog + touch -r ChangeLog $DOCSDIR/ChangeLog +fi mkdir -p $PKG/install +zcat $CWD/doinst.sh > $PKG/install/doinst.sh cat $CWD/slack-desc > $PKG/install/slack-desc cd $PKG |