From 31a4b11f99c1ec53f7bb0809c9c94a3b703f9e3f Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 23 Aug 2019 23:51:56 -0400 Subject: [PATCH 1/2] sys-auth/polkit: bugfix for CVE-2018-19788 fix https://gitlab.freedesktop.org/polkit/polkit/issues/77 --- ...low-uid-of-1-for-a-PolkitUnixProcess.patch | 47 +++++++++++++++++++ ...0.113-r4.ebuild => polkit-0.113-r5.ebuild} | 1 + 2 files changed, 48 insertions(+) create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch rename sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/{polkit-0.113-r4.ebuild => polkit-0.113-r5.ebuild} (97%) diff --git a/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch new file mode 100644 index 0000000000..e9f5649532 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch @@ -0,0 +1,47 @@ +From 87aec8b7275665c85fe22bcc8e74d2a0422535ce Mon Sep 17 00:00:00 2001 +From: Matthew Leeds +Date: Tue, 11 Dec 2018 12:04:26 -0800 +Subject: [PATCH] Allow uid of -1 for a PolkitUnixProcess + +Commit 2cb40c4d5 changed PolkitUnixUser, PolkitUnixGroup, and +PolkitUnixProcess to allow negative values for their uid/gid properties, +since these are values above INT_MAX which wrap around but are still +valid, with the exception of -1 which is not valid. However, +PolkitUnixProcess allows a uid of -1 to be passed to +polkit_unix_process_new_for_owner() which means polkit is expected to +figure out the uid on its own (this happens in the _constructed +function). So this commit removes the check in +polkit_unix_process_set_property() so that new_for_owner() can be used +as documented without producing a critical error message. + +This does not affect the protection against CVE-2018-19788 which is +based on creating a user with a UID up to but not including 4294967295 +(-1). +--- + src/polkit/polkitunixprocess.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c +index 2c57813..93dea3c 100644 +--- a/src/polkit/polkitunixprocess.c ++++ b/src/polkit/polkitunixprocess.c +@@ -142,14 +142,9 @@ polkit_unix_process_set_property (GObject *object, + polkit_unix_process_set_pid (unix_process, g_value_get_int (value)); + break; + +- case PROP_UID: { +- gint val; +- +- val = g_value_get_int (value); +- g_return_if_fail (val != -1); +- polkit_unix_process_set_uid (unix_process, val); ++ 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)); +-- +2.21.0 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r4.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild similarity index 97% rename from sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r4.ebuild rename to sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild index a7653a5c1e..9278c76343 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r4.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild @@ -66,6 +66,7 @@ src_prepare() { sed -i -e 's|unix-group:wheel|unix-user:0|' src/polkitbackend/*-default.rules || die #401513 epatch ${FILESDIR}/polkit-0.113-gir-cross-compile.patch epatch ${FILESDIR}/polkit-0.113-allow-negative-uids-gids.patch + epatch ${FILESDIR}/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch } src_configure() { From 51337ab580a2985efaa2b6faf3a0c236cfd9baea Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 23 Aug 2019 23:55:03 -0400 Subject: [PATCH 2/2] sys-auth/polkit: fix CVE-2018-1116 Backported patch. --- ...18-1116-Trusting-client-supplied-UID.patch | 572 ++++++++++++++++++ .../sys-auth/polkit/polkit-0.113-r5.ebuild | 1 + 2 files changed, 573 insertions(+) create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch diff --git a/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch new file mode 100644 index 0000000000..983acf4723 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch @@ -0,0 +1,572 @@ +From 82494ed6bcff05b5a65c00bcf5212dcd2b559f70 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= +Date: Fri, 23 Aug 2019 20:31:11 -0400 +Subject: [PATCH] Fix CVE-2018-1116: Trusting client-supplied UID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As part of CVE-2013-4288, the D-Bus clients were allowed (and +encouraged) to submit the UID of the subject of authorization checks +to avoid races against UID changes (notably using executables +set-UID to root). + +However, that also allowed any client to submit an arbitrary UID, and +that could be used to bypass "can only ask about / affect the same UID" +checks in CheckAuthorization / RegisterAuthenticationAgent / +UnregisterAuthenticationAgent. This allowed an attacker: + +- With CheckAuthorization, to cause the registered authentication + agent in victim's session to pop up a dialog, or to determine whether + the victim currently has a temporary authorization to perform an + operation. + + (In principle, the attacker can also determine whether JavaScript + rules allow the victim process to perform an operation; however, + usually rules base their decisions on information determined from + the supplied UID, so the attacker usually won't learn anything new.) + +- With RegisterAuthenticationAgent, to prevent the victim's + authentication agent to work (for a specific victim process), + or to learn about which operations requiring authorization + the victim is attempting. + +To fix this, expose internal _polkit_unix_process_get_owner() / +obsolete polkit_unix_process_get_owner() as a private +polkit_unix_process_get_racy_uid__() (being more explicit about the +dangers on relying on it), and use it in +polkit_backend_session_monitor_get_user_for_subject() to return +a boolean indicating whether the subject UID may be caller-chosen. + +Then, in the permission checks that require the subject to be +equal to the caller, fail on caller-chosen UIDs (and continue +through the pre-existing code paths which allow root, or root-designated +server processes, to ask about arbitrary subjects.) + +Signed-off-by: Miloslav Trmač +--- + src/polkit/polkitprivate.h | 2 + + src/polkit/polkitunixprocess.c | 60 +++++++++++++++---- + .../polkitbackendinteractiveauthority.c | 39 +++++++----- + .../polkitbackendsessionmonitor-systemd.c | 38 ++++++++++-- + .../polkitbackendsessionmonitor.c | 40 +++++++++++-- + .../polkitbackendsessionmonitor.h | 1 + + 6 files changed, 147 insertions(+), 33 deletions(-) + +diff --git a/src/polkit/polkitprivate.h b/src/polkit/polkitprivate.h +index 9f07063..c80142d 100644 +--- a/src/polkit/polkitprivate.h ++++ b/src/polkit/polkitprivate.h +@@ -44,6 +44,8 @@ GVariant *polkit_action_description_to_gvariant (PolkitActionDescription *action + GVariant *polkit_subject_to_gvariant (PolkitSubject *subject); + GVariant *polkit_identity_to_gvariant (PolkitIdentity *identity); + ++gint polkit_unix_process_get_racy_uid__ (PolkitUnixProcess *process, GError **error); ++ + PolkitSubject *polkit_subject_new_for_gvariant (GVariant *variant, GError **error); + PolkitIdentity *polkit_identity_new_for_gvariant (GVariant *variant, GError **error); + +diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c +index 93dea3c..f799942 100644 +--- a/src/polkit/polkitunixprocess.c ++++ b/src/polkit/polkitunixprocess.c +@@ -49,6 +49,14 @@ + * To uniquely identify processes, both the process id and the start + * time of the process (a monotonic increasing value representing the + * time since the kernel was started) is used. ++ * ++ * NOTE: This object stores, and provides access to, the real UID of the ++ * process. That value can change over time (with set*uid*(2) and exec*(2)). ++ * Checks whether an operation is allowed need to take care to use the UID ++ * value as of the time when the operation was made (or, following the open() ++ * privilege check model, when the connection making the operation possible ++ * was initiated). That is usually done by initializing this with ++ * polkit_unix_process_new_for_owner() with trusted data. + */ + + /** +@@ -83,9 +91,6 @@ 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 +@@ -170,7 +175,7 @@ polkit_unix_process_constructed (GObject *object) + { + GError *error; + error = NULL; +- process->uid = _polkit_unix_process_get_owner (process, &error); ++ process->uid = polkit_unix_process_get_racy_uid__ (process, &error); + if (error != NULL) + { + process->uid = -1; +@@ -259,6 +264,12 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) + * Gets the user id for @process. Note that this is the real user-id, + * not the effective user-id. + * ++ * NOTE: The UID may change over time, so the returned value may not match the ++ * current state of the underlying process; or the UID may have been set by ++ * polkit_unix_process_new_for_owner() or polkit_unix_process_set_uid(), ++ * in which case it may not correspond to the actual UID of the referenced ++ * process at all (at any point in time). ++ * + * Returns: The user id for @process or -1 if unknown. + */ + gint +@@ -654,18 +665,26 @@ out: + return start_time; + } + +-static gint +-_polkit_unix_process_get_owner (PolkitUnixProcess *process, +- GError **error) ++/* ++ * Private: Return the "current" UID. Note that this is inherently racy, ++ * and the value may already be obsolete by the time this function returns; ++ * this function only guarantees that the UID was valid at some point during ++ * its execution. ++ */ ++gint ++polkit_unix_process_get_racy_uid__ (PolkitUnixProcess *process, ++ GError **error) + { + gint result; + gchar *contents; + gchar **lines; ++ guint64 start_time; + #ifdef HAVE_FREEBSD + struct kinfo_proc p; + #else + gchar filename[64]; + guint n; ++ GError *local_error; + #endif + + g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0); +@@ -688,6 +707,7 @@ _polkit_unix_process_get_owner (PolkitUnixProcess *process, + } + + result = p.ki_uid; ++ start_time = (guint64) p.ki_start.tv_sec; + #else + + /* see 'man proc' for layout of the status file +@@ -721,17 +741,37 @@ _polkit_unix_process_get_owner (PolkitUnixProcess *process, + else + { + result = real_uid; +- goto out; ++ goto found; + } + } +- + g_set_error (error, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "Didn't find any line starting with `Uid:' in file %s", + filename); ++ goto out; ++ ++found: ++ /* The UID and start time are, sadly, not available in a single file. So, ++ * read the UID first, and then the start time; if the start time is the same ++ * before and after reading the UID, it couldn't have changed. ++ */ ++ local_error = NULL; ++ start_time = get_start_time_for_pid (process->pid, &local_error); ++ if (local_error != NULL) ++ { ++ g_propagate_error (error, local_error); ++ goto out; ++ } + #endif + ++ if (process->start_time != start_time) ++ { ++ g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED, ++ "process with PID %d has been replaced", process->pid); ++ goto out; ++ } ++ + out: + g_strfreev (lines); + g_free (contents); +@@ -750,5 +790,5 @@ gint + polkit_unix_process_get_owner (PolkitUnixProcess *process, + GError **error) + { +- return _polkit_unix_process_get_owner (process, error); ++ return polkit_unix_process_get_racy_uid__ (process, error); + } +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index 7019356..0b587a3 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -572,7 +572,7 @@ log_result (PolkitBackendInteractiveAuthority *authority, + if (polkit_authorization_result_get_is_authorized (result)) + log_result_str = "ALLOWING"; + +- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); ++ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL, NULL); + + subject_str = polkit_subject_to_string (subject); + +@@ -844,6 +844,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + gchar *subject_str; + PolkitIdentity *user_of_caller; + PolkitIdentity *user_of_subject; ++ gboolean user_of_subject_matches; + gchar *user_of_caller_str; + gchar *user_of_subject_str; + PolkitAuthorizationResult *result; +@@ -889,7 +890,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + action_id); + + user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- caller, ++ caller, NULL, + &error); + if (error != NULL) + { +@@ -904,7 +905,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + g_debug (" user of caller is %s", user_of_caller_str); + + user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- subject, ++ subject, &user_of_subject_matches, + &error); + if (error != NULL) + { +@@ -934,7 +935,10 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + * We only allow this if, and only if, + * + * - processes may check for another process owned by the *same* user but not +- * if details are passed (otherwise you'd be able to spoof the dialog) ++ * if details are passed (otherwise you'd be able to spoof the dialog); ++ * the caller supplies the user_of_subject value, so we additionally ++ * require it to match at least at one point in time (via ++ * user_of_subject_matches). + * + * - processes running as uid 0 may check anything and pass any details + * +@@ -942,7 +946,9 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + * then any uid referenced by that annotation is also allowed to check + * to check anything and pass any details + */ +- if (!polkit_identity_equal (user_of_caller, user_of_subject) || has_details) ++ if (!user_of_subject_matches ++ || !polkit_identity_equal (user_of_caller, user_of_subject) ++ || has_details) + { + if (!may_identity_check_authorization (interactive_authority, action_id, user_of_caller)) + { +@@ -1107,9 +1113,10 @@ check_authorization_sync (PolkitBackendAuthority *authority, + goto out; + } + +- /* every subject has a user */ ++ /* every subject has a user; this is supplied by the client, so we rely ++ * on the caller to validate its acceptability. */ + user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- subject, ++ subject, NULL, + error); + if (user_of_subject == NULL) + goto out; +@@ -2475,6 +2482,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + PolkitSubject *session_for_caller; + PolkitIdentity *user_of_caller; + PolkitIdentity *user_of_subject; ++ gboolean user_of_subject_matches; + AuthenticationAgent *agent; + gboolean ret; + gchar *caller_cmdline; +@@ -2527,7 +2535,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + goto out; + } + +- user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL); ++ user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL, NULL); + if (user_of_caller == NULL) + { + g_set_error (error, +@@ -2536,7 +2544,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + "Cannot determine user of caller"); + goto out; + } +- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); ++ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, &user_of_subject_matches, NULL); + if (user_of_subject == NULL) + { + g_set_error (error, +@@ -2545,7 +2553,8 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + "Cannot determine user of subject"); + goto out; + } +- if (!polkit_identity_equal (user_of_caller, user_of_subject)) ++ if (!user_of_subject_matches ++ || !polkit_identity_equal (user_of_caller, user_of_subject)) + { + if (identity_is_root_user (user_of_caller)) + { +@@ -2638,6 +2647,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + PolkitSubject *session_for_caller; + PolkitIdentity *user_of_caller; + PolkitIdentity *user_of_subject; ++ gboolean user_of_subject_matches; + AuthenticationAgent *agent; + gboolean ret; + gchar *scope_str; +@@ -2686,7 +2696,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + goto out; + } + +- user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL); ++ user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL, NULL); + if (user_of_caller == NULL) + { + g_set_error (error, +@@ -2695,7 +2705,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + "Cannot determine user of caller"); + goto out; + } +- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); ++ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, &user_of_subject_matches, NULL); + if (user_of_subject == NULL) + { + g_set_error (error, +@@ -2704,7 +2714,8 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + "Cannot determine user of subject"); + goto out; + } +- if (!polkit_identity_equal (user_of_caller, user_of_subject)) ++ if (!user_of_subject_matches ++ || !polkit_identity_equal (user_of_caller, user_of_subject)) + { + if (identity_is_root_user (user_of_caller)) + { +@@ -2814,7 +2825,7 @@ polkit_backend_interactive_authority_authentication_agent_response (PolkitBacken + identity_str); + + user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- caller, ++ caller, NULL, + error); + if (user_of_caller == NULL) + goto out; +diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +index 2a6c739..b00cdbd 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +@@ -29,6 +29,7 @@ + #include + + #include ++#include + #include "polkitbackendsessionmonitor.h" + + /* +@@ -246,26 +247,40 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito + * polkit_backend_session_monitor_get_user: + * @monitor: A #PolkitBackendSessionMonitor. + * @subject: A #PolkitSubject. ++ * @result_matches: If not %NULL, set to indicate whether the return value matches current (RACY) state. + * @error: Return location for error. + * + * Gets the user corresponding to @subject or %NULL if no user exists. + * ++ * NOTE: For a #PolkitUnixProcess, the UID is read from @subject (which may ++ * come from e.g. a D-Bus client), so it may not correspond to the actual UID ++ * of the referenced process (at any point in time). This is indicated by ++ * setting @result_matches to %FALSE; the caller may reject such subjects or ++ * require additional privileges. @result_matches == %TRUE only indicates that ++ * the UID matched the underlying process at ONE point in time, it may not match ++ * later. ++ * + * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref(). + */ + PolkitIdentity * + polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, ++ gboolean *result_matches, + GError **error) + { + PolkitIdentity *ret; +- guint32 uid; ++ gboolean matches; + + ret = NULL; ++ matches = FALSE; + + if (POLKIT_IS_UNIX_PROCESS (subject)) + { +- uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); +- if ((gint) uid == -1) ++ gint subject_uid, current_uid; ++ GError *local_error; ++ ++ subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); ++ if (subject_uid == -1) + { + g_set_error (error, + POLKIT_ERROR, +@@ -273,14 +288,24 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + "Unix process subject does not have uid set"); + goto out; + } +- ret = polkit_unix_user_new (uid); ++ local_error = NULL; ++ current_uid = polkit_unix_process_get_racy_uid__ (POLKIT_UNIX_PROCESS (subject), &local_error); ++ if (local_error != NULL) ++ { ++ g_propagate_error (error, local_error); ++ goto out; ++ } ++ ret = polkit_unix_user_new (subject_uid); ++ matches = (subject_uid == current_uid); + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { + ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); ++ matches = TRUE; + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { ++ uid_t uid; + + if (sd_session_get_uid (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)), &uid) < 0) + { +@@ -292,9 +317,14 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + } + + ret = polkit_unix_user_new (uid); ++ matches = TRUE; + } + + out: ++ if (result_matches != NULL) ++ { ++ *result_matches = matches; ++ } + return ret; + } + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c +index e1a9ab3..ed30755 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor.c +@@ -27,6 +27,7 @@ + #include + + #include ++#include + #include "polkitbackendsessionmonitor.h" + + #define CKDB_PATH "/var/run/ConsoleKit/database" +@@ -273,28 +274,40 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito + * polkit_backend_session_monitor_get_user: + * @monitor: A #PolkitBackendSessionMonitor. + * @subject: A #PolkitSubject. ++ * @result_matches: If not %NULL, set to indicate whether the return value matches current (RACY) state. + * @error: Return location for error. + * + * Gets the user corresponding to @subject or %NULL if no user exists. + * ++ * NOTE: For a #PolkitUnixProcess, the UID is read from @subject (which may ++ * come from e.g. a D-Bus client), so it may not correspond to the actual UID ++ * of the referenced process (at any point in time). This is indicated by ++ * setting @result_matches to %FALSE; the caller may reject such subjects or ++ * require additional privileges. @result_matches == %TRUE only indicates that ++ * the UID matched the underlying process at ONE point in time, it may not match ++ * later. ++ * + * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref(). + */ + PolkitIdentity * + polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, ++ gboolean *result_matches, + GError **error) + { + PolkitIdentity *ret; ++ gboolean matches; + GError *local_error; +- gchar *group; +- guint32 uid; + + ret = NULL; ++ matches = FALSE; + + if (POLKIT_IS_UNIX_PROCESS (subject)) + { +- uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); +- if ((gint) uid == -1) ++ gint subject_uid, current_uid; ++ ++ subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); ++ if (subject_uid == -1) + { + g_set_error (error, + POLKIT_ERROR, +@@ -302,14 +315,26 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + "Unix process subject does not have uid set"); + goto out; + } +- ret = polkit_unix_user_new (uid); ++ local_error = NULL; ++ current_uid = polkit_unix_process_get_racy_uid__ (POLKIT_UNIX_PROCESS (subject), &local_error); ++ if (local_error != NULL) ++ { ++ g_propagate_error (error, local_error); ++ goto out; ++ } ++ ret = polkit_unix_user_new (subject_uid); ++ matches = (subject_uid == current_uid); + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { + ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); ++ matches = TRUE; + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { ++ gint uid; ++ gchar *group; ++ + if (!ensure_database (monitor, error)) + { + g_prefix_error (error, "Error getting user for session: Error ensuring CK database at " CKDB_PATH ": "); +@@ -328,9 +353,14 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + g_free (group); + + ret = polkit_unix_user_new (uid); ++ matches = TRUE; + } + + out: ++ if (result_matches != NULL) ++ { ++ *result_matches = matches; ++ } + return ret; + } + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.h b/src/polkitbackend/polkitbackendsessionmonitor.h +index 8f8a2ca..3972326 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.h ++++ b/src/polkitbackend/polkitbackendsessionmonitor.h +@@ -47,6 +47,7 @@ GList *polkit_backend_session_monitor_get_sessions (Polkit + + PolkitIdentity *polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, ++ gboolean *result_matches, + GError **error); + + PolkitSubject *polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor, +-- +2.21.0 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild index 9278c76343..4740f5f6a9 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-auth/polkit/polkit-0.113-r5.ebuild @@ -67,6 +67,7 @@ src_prepare() { epatch ${FILESDIR}/polkit-0.113-gir-cross-compile.patch epatch ${FILESDIR}/polkit-0.113-allow-negative-uids-gids.patch epatch ${FILESDIR}/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch + epatch ${FILESDIR}/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch } src_configure() {