[glib2/f14/master] Fix a polkit problem

Matthias Clasen mclasen at fedoraproject.org
Wed Aug 18 17:03:09 UTC 2010


commit ce3f94fe4056fd4d2941b666782b0155523a0898
Author: Matthias Clasen <mclasen at redhat.com>
Date:   Wed Aug 18 13:00:04 2010 -0400

    Fix a polkit problem

 ...Call-into-well-known-name-if-no-name-owne.patch |  225 ++++++++++++++++++++
 glib2.spec                                         |    9 +-
 2 files changed, 233 insertions(+), 1 deletions(-)
---
diff --git a/0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch b/0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch
new file mode 100644
index 0000000..9f90160
--- /dev/null
+++ b/0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch
@@ -0,0 +1,225 @@
+From 5bb94348f4760352f6ae974002db48cb130343a4 Mon Sep 17 00:00:00 2001
+From: David Zeuthen <davidz at redhat.com>
+Date: Wed, 18 Aug 2010 11:35:25 -0400
+Subject: [PATCH 1/4] GDBusProxy: Call into well-known name if no name owner currently exists
+
+This is really what (API) users expect from GDBusProxy - in
+particular, mclasen and I ran into this problem while debugging a
+upower issue, see
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=624125
+
+In a nutshell, the problem is that polkitd crashes while upower holds
+a PolkitAuthority object (which in turns contains a GDBusProxy for the
+well-known name org.freedesktop.PolicyKit1). This means that
+subsequent calls on the PolkitAuthority (which is translated into
+calls into the GDBusProxy) fails since :g-name-owner is NULL.
+
+With this fix, we'll be requesting the bus daemon to launch polkitd
+since we will start calling into org.freedesktop.PolicyKit1 as soon as
+we notice that there is no owner for this name.
+
+Unfortunately our test suite doesn't cover service activation so there
+is no way to reliably test this. I will file a bug about this.
+
+Signed-off-by: David Zeuthen <davidz at redhat.com>
+---
+ gio/gdbusproxy.c |  108 ++++++++++++++++++++++++++++++++++++++++--------------
+ 1 files changed, 80 insertions(+), 28 deletions(-)
+
+diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
+index d47a4ad..17e6730 100644
+--- a/gio/gdbusproxy.c
++++ b/gio/gdbusproxy.c
+@@ -61,9 +61,13 @@
+  * name is tracked and can be read from
+  * #GDBusProxy:g-name-owner. Connect to the #GObject::notify signal to
+  * get notified of changes. Additionally, only signals and property
+- * changes emitted from the current name owner are considered. This
+- * avoids a number of race conditions when the name is lost by one
+- * owner and claimed by another.
++ * changes emitted from the current name owner are considered and
++ * calls are always sent to the current name owner. This avoids a
++ * number of race conditions when the name is lost by one owner and
++ * claimed by another. However, if no name owner currently exists,
++ * then calls will be sent to the well-known name which may result in
++ * the message bus launching an owner (unless
++ * %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is set).
+  *
+  * The generic #GDBusProxy::g-properties-changed and #GDBusProxy::g-signal
+  * signals are not very convenient to work with. Therefore, the recommended
+@@ -2179,6 +2183,31 @@ lookup_method_info_or_warn (GDBusProxy  *proxy,
+   return info;
+ }
+ 
++static const gchar *
++get_destination_for_call (GDBusProxy *proxy)
++{
++  const gchar *ret;
++
++  ret = NULL;
++
++  /* If proxy->priv->name is a unique name, then proxy->priv->name_owner
++   * is never NULL and always the same as proxy->priv->name. We use this
++   * knowledge to avoid checking if proxy->priv->name is a unique or
++   * well-known name.
++   */
++  ret = proxy->priv->name_owner;
++  if (ret != NULL)
++    goto out;
++
++  if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START)
++    goto out;
++
++  ret = proxy->priv->name;
++
++ out:
++  return ret;
++}
++
+ /**
+  * g_dbus_proxy_call:
+  * @proxy: A #GDBusProxy.
+@@ -2243,9 +2272,9 @@ g_dbus_proxy_call (GDBusProxy          *proxy,
+   gboolean was_split;
+   gchar *split_interface_name;
+   const gchar *split_method_name;
+-  const GDBusMethodInfo *expected_method_info;
+   const gchar *target_method_name;
+   const gchar *target_interface_name;
++  const gchar *destination;
+   GVariantType *reply_type;
+ 
+   g_return_if_fail (G_IS_DBUS_PROXY (proxy));
+@@ -2253,6 +2282,9 @@ g_dbus_proxy_call (GDBusProxy          *proxy,
+   g_return_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
+   g_return_if_fail (timeout_msec == -1 || timeout_msec >= 0);
+ 
++  reply_type = NULL;
++  split_interface_name = NULL;
++
+   simple = g_simple_async_result_new (G_OBJECT (proxy),
+                                       callback,
+                                       user_data,
+@@ -2265,17 +2297,30 @@ g_dbus_proxy_call (GDBusProxy          *proxy,
+   g_object_set_data_full (G_OBJECT (simple), "-gdbus-proxy-method-name", g_strdup (target_method_name), g_free);
+ 
+   /* Warn if method is unexpected (cf. :g-interface-info) */
+-  expected_method_info = NULL;
+   if (!was_split)
+-    expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
++    {
++      const GDBusMethodInfo *expected_method_info;
++      expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
++      if (expected_method_info != NULL)
++        reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
++    }
+ 
+-  if (expected_method_info)
+-    reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
+-  else
+-    reply_type = NULL;
++  destination = NULL;
++  if (proxy->priv->name != NULL)
++    {
++      destination = get_destination_for_call (proxy);
++      if (destination == NULL)
++        {
++          g_simple_async_result_set_error (simple,
++                                           G_IO_ERROR,
++                                           G_IO_ERROR_FAILED,
++                                           _("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
++          goto out;
++        }
++    }
+ 
+   g_dbus_connection_call (proxy->priv->connection,
+-                          proxy->priv->name_owner,
++                          destination,
+                           proxy->priv->object_path,
+                           target_interface_name,
+                           target_method_name,
+@@ -2287,6 +2332,7 @@ g_dbus_proxy_call (GDBusProxy          *proxy,
+                           (GAsyncReadyCallback) reply_cb,
+                           simple);
+ 
++ out:
+   if (reply_type != NULL)
+     g_variant_type_free (reply_type);
+ 
+@@ -2392,9 +2438,9 @@ g_dbus_proxy_call_sync (GDBusProxy      *proxy,
+   gboolean was_split;
+   gchar *split_interface_name;
+   const gchar *split_method_name;
+-  const GDBusMethodInfo *expected_method_info;
+   const gchar *target_method_name;
+   const gchar *target_interface_name;
++  const gchar *destination;
+   GVariantType *reply_type;
+ 
+   g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
+@@ -2403,32 +2449,37 @@ g_dbus_proxy_call_sync (GDBusProxy      *proxy,
+   g_return_val_if_fail (timeout_msec == -1 || timeout_msec >= 0, NULL);
+   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ 
++  reply_type = NULL;
++
+   was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name);
+   target_method_name = was_split ? split_method_name : method_name;
+   target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name;
+ 
+-  if (proxy->priv->expected_interface)
++  /* Warn if method is unexpected (cf. :g-interface-info) */
++  if (!was_split)
+     {
+-      expected_method_info = g_dbus_interface_info_lookup_method (proxy->priv->expected_interface, target_method_name);
+-      if (expected_method_info == NULL)
+-        {
+-          g_warning ("Trying to invoke method `%s' which isn't in expected interface `%s'",
+-                     target_method_name,
+-                     target_interface_name);
+-        }
++      const GDBusMethodInfo *expected_method_info;
++      expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
++      if (expected_method_info != NULL)
++        reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
+     }
+-  else
++
++  destination = NULL;
++  if (proxy->priv->name != NULL)
+     {
+-      expected_method_info = NULL;
++      destination = get_destination_for_call (proxy);
++      if (destination == NULL)
++        {
++          g_set_error_literal (error,
++                               G_IO_ERROR,
++                               G_IO_ERROR_FAILED,
++                               _("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
++          goto out;
++        }
+     }
+ 
+-  if (expected_method_info)
+-    reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
+-  else
+-    reply_type = NULL;
+-
+   ret = g_dbus_connection_call_sync (proxy->priv->connection,
+-                                     proxy->priv->name_owner,
++                                     destination,
+                                      proxy->priv->object_path,
+                                      target_interface_name,
+                                      target_method_name,
+@@ -2439,6 +2490,7 @@ g_dbus_proxy_call_sync (GDBusProxy      *proxy,
+                                      cancellable,
+                                      error);
+ 
++ out:
+   if (reply_type != NULL)
+     g_variant_type_free (reply_type);
+ 
+-- 
+1.7.2.1
+
diff --git a/glib2.spec b/glib2.spec
index 71599ac..9354168 100644
--- a/glib2.spec
+++ b/glib2.spec
@@ -3,7 +3,7 @@
 Summary: A library of handy utility functions
 Name: glib2
 Version: 2.25.14
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: LGPLv2+
 Group: System Environment/Libraries
 URL: http://www.gtk.org
@@ -27,6 +27,9 @@ BuildRequires: gtk-doc
 # required for GIO content-type support
 Requires: shared-mime-info
 
+# Upstream fix for a problem with PolicyKit problems
+Patch0: 0001-GDBusProxy-Call-into-well-known-name-if-no-name-owne.patch
+
 %description
 GLib is the low-level core library that forms the basis for projects
 such as GTK+ and GNOME. It provides data structure handling for C,
@@ -53,6 +56,7 @@ The glib2-static package includes static libraries of the GLib library.
 
 %prep
 %setup -q -n glib-%{version}
+%patch0 -p1 -b .wellknown-call
 
 %build
 # Support builds of both git snapshots and tarballs packed with autogoo
@@ -158,6 +162,9 @@ gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules
 %{_libdir}/lib*.a
 
 %changelog
+* Wed Aug 18 2010 Matthias Clasen <mclasen at redhat.com> - 2.25.14-2
+- Fix a PolicyKit problem
+
 * Tue Aug 17 2010 Matthias Clasen <mclasen at redhat.com> - 2.25.14-1
 - Update to 2.25.14
 4-1


More information about the scm-commits mailing list