Blame SOURCES/polkit-0.112-CVE-2015-3256.patch

4c1d22
commit 983e8ec37b0ec1cc5114cb9ca49cf558dedfb31e
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Don't pass an uninitialized JS parameter
4c1d22
    
4c1d22
    Don't pass argc==3 when using a 2-member array in
4c1d22
    polkit_backend_js_authority_check_authorization_sync .  To avoid such
4c1d22
    problems in the future, use G_N_ELEMENTS in both similar callers.
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index c232573..c7a29e0 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -1074,7 +1074,7 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA
4c1d22
 
4c1d22
   if (!call_js_function_with_runaway_killer (authority,
4c1d22
                                              "_runAdminRules",
4c1d22
-                                             2,
4c1d22
+                                             G_N_ELEMENTS (argv),
4c1d22
                                              argv,
4c1d22
                                              &rval))
4c1d22
     {
4c1d22
@@ -1179,7 +1179,7 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu
4c1d22
 
4c1d22
   if (!call_js_function_with_runaway_killer (authority,
4c1d22
                                              "_runRules",
4c1d22
-                                             3,
4c1d22
+                                             G_N_ELEMENTS (argv),
4c1d22
                                              argv,
4c1d22
                                              &rval))
4c1d22
     {
4c1d22
4c1d22
commit a97672540c66c03ed392fc072f0c682281f08989
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Don't add extra NULL group to subject.groups
4c1d22
    
4c1d22
    The NULL “terminator” of ‘groups’ was being passed to JavaScript.  Drop
4c1d22
    it, and simplify by leting set_property_strv use the GPtrArray directly
4c1d22
    instead of the extra conversions “into” a strv and a completely dead
4c1d22
    g_strv_length().
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index c7a29e0..efb07a9 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -659,26 +659,22 @@ static void
4c1d22
 set_property_strv (PolkitBackendJsAuthority  *authority,
4c1d22
                    JSObject                  *obj,
4c1d22
                    const gchar               *name,
4c1d22
-                   const gchar *const        *value,
4c1d22
-                   gssize                     len)
4c1d22
+                   GPtrArray                 *value)
4c1d22
 {
4c1d22
   jsval value_jsval;
4c1d22
   JSObject *array_object;
4c1d22
   jsval *jsvals;
4c1d22
   guint n;
4c1d22
 
4c1d22
-  if (len < 0)
4c1d22
-    len = g_strv_length ((gchar **) value);
4c1d22
-
4c1d22
-  jsvals = g_new0 (jsval, len);
4c1d22
-  for (n = 0; n < len; n++)
4c1d22
+  jsvals = g_new0 (jsval, value->len);
4c1d22
+  for (n = 0; n < value->len; n++)
4c1d22
     {
4c1d22
       JSString *jsstr;
4c1d22
-      jsstr = JS_NewStringCopyZ (authority->priv->cx, value[n]);
4c1d22
+      jsstr = JS_NewStringCopyZ (authority->priv->cx, g_ptr_array_index(value, n));
4c1d22
       jsvals[n] = STRING_TO_JSVAL (jsstr);
4c1d22
     }
4c1d22
 
4c1d22
-  array_object = JS_NewArrayObject (authority->priv->cx, (gint32) len, jsvals);
4c1d22
+  array_object = JS_NewArrayObject (authority->priv->cx, value->len, jsvals);
4c1d22
 
4c1d22
   value_jsval = OBJECT_TO_JSVAL (array_object);
4c1d22
   JS_SetProperty (authority->priv->cx, obj, name, &value_jsval);
4c1d22
@@ -818,11 +814,9 @@ subject_to_jsval (PolkitBackendJsAuthority  *authority,
4c1d22
         }
4c1d22
     }
4c1d22
 
4c1d22
-  g_ptr_array_add (groups, NULL);
4c1d22
-
4c1d22
   set_property_int32 (authority, obj, "pid", pid);
4c1d22
   set_property_str (authority, obj, "user", user_name);
4c1d22
-  set_property_strv (authority, obj, "groups", (const gchar* const *) groups->pdata, groups->len);
4c1d22
+  set_property_strv (authority, obj, "groups", groups);
4c1d22
   set_property_str (authority, obj, "seat", seat_str);
4c1d22
   set_property_str (authority, obj, "session", session_str);
4c1d22
   set_property_bool (authority, obj, "local", subject_is_local);
4c1d22
4c1d22
commit cbad0d5721804a4b7c2d998b00da9e70dc623820
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Don't store unrooted jsvals on heap
4c1d22
    
4c1d22
    Don't create a temporary array of jsvals on heap; the GC is not looking
4c1d22
    for GC roots there.
4c1d22
    
4c1d22
    Compare
4c1d22
    https://developer.mozilla.org/en-US/docs/SpiderMonkey/GC_Rooting_Guide
4c1d22
    and
4c1d22
    https://web.archive.org/web/20140305233124/https://developer.mozilla.org/en-US/docs/SpiderMonkey_Garbage_Collection_Tips
4c1d22
    .
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index efb07a9..d02e5e3 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -663,23 +663,22 @@ set_property_strv (PolkitBackendJsAuthority  *authority,
4c1d22
 {
4c1d22
   jsval value_jsval;
4c1d22
   JSObject *array_object;
4c1d22
-  jsval *jsvals;
4c1d22
   guint n;
4c1d22
 
4c1d22
-  jsvals = g_new0 (jsval, value->len);
4c1d22
+  array_object = JS_NewArrayObject (authority->priv->cx, 0, NULL);
4c1d22
+
4c1d22
   for (n = 0; n < value->len; n++)
4c1d22
     {
4c1d22
       JSString *jsstr;
4c1d22
+      jsval val;
4c1d22
+
4c1d22
       jsstr = JS_NewStringCopyZ (authority->priv->cx, g_ptr_array_index(value, n));
4c1d22
-      jsvals[n] = STRING_TO_JSVAL (jsstr);
4c1d22
+      val = STRING_TO_JSVAL (jsstr);
4c1d22
+      JS_SetElement (authority->priv->cx, array_object, n, &val;;
4c1d22
     }
4c1d22
 
4c1d22
-  array_object = JS_NewArrayObject (authority->priv->cx, value->len, jsvals);
4c1d22
-
4c1d22
   value_jsval = OBJECT_TO_JSVAL (array_object);
4c1d22
   JS_SetProperty (authority->priv->cx, obj, name, &value_jsval);
4c1d22
-
4c1d22
-  g_free (jsvals);
4c1d22
 }
4c1d22
 
4c1d22
 
4c1d22
4c1d22
commit 0f5852a4bdabe377ddcdbed09a0c1f95710e17fe
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Fix a per-authorization memory leak
4c1d22
    
4c1d22
    We were leaking PolkitAuthorizationResult on every request, primarily on
4c1d22
    the success path, but also on various error paths as well.
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
4c1d22
index a09d667..14eea99 100644
4c1d22
--- a/src/polkitbackend/polkitbackendauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendauthority.c
4c1d22
@@ -714,6 +714,7 @@ check_auth_cb (GObject      *source_object,
4c1d22
       g_variant_ref_sink (value);
4c1d22
       g_dbus_method_invocation_return_value (data->invocation, g_variant_new ("(@(bba{ss}))", value));
4c1d22
       g_variant_unref (value);
4c1d22
+      g_object_unref (result);
4c1d22
     }
4c1d22
 
4c1d22
   check_auth_data_free (data);
4c1d22
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
4c1d22
index 96725f7..7019356 100644
4c1d22
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
4c1d22
@@ -1022,7 +1022,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority
4c1d22
 
4c1d22
   /* Otherwise just return the result */
4c1d22
   g_simple_async_result_set_op_res_gpointer (simple,
4c1d22
-                                             result,
4c1d22
+                                             g_object_ref (result),
4c1d22
                                              g_object_unref);
4c1d22
   g_simple_async_result_complete (simple);
4c1d22
   g_object_unref (simple);
4c1d22
@@ -1039,6 +1039,9 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority
4c1d22
   g_free (subject_str);
4c1d22
   g_free (user_of_caller_str);
4c1d22
   g_free (user_of_subject_str);
4c1d22
+
4c1d22
+  if (result != NULL)
4c1d22
+    g_object_unref (result);
4c1d22
 }
4c1d22
 
4c1d22
 /* ---------------------------------------------------------------------------------------------------- */
4c1d22
4c1d22
commit ec039f9d7ede5b839f5511e26d5cd6ae9107cb2e
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Fix a memory leak when registering an authentication agent
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
4c1d22
index 14eea99..64560e1 100644
4c1d22
--- a/src/polkitbackend/polkitbackendauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendauthority.c
4c1d22
@@ -900,6 +900,7 @@ server_handle_register_authentication_agent (Server                 *server,
4c1d22
   g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
4c1d22
 
4c1d22
  out:
4c1d22
+  g_variant_unref (subject_gvariant);
4c1d22
   if (subject != NULL)
4c1d22
     g_object_unref (subject);
4c1d22
 }
4c1d22
4c1d22
commit 57e2d86edc2630cac1812a3285715dad795a4bd6
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Wrap all JS usage within “requests”
4c1d22
    
4c1d22
    Required by
4c1d22
    https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_THREADSAFE
4c1d22
    ; lack of requests causes assertion failures with a debug build of
4c1d22
    mozjs17.
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index d02e5e3..88f31bd 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -239,6 +239,7 @@ rules_file_name_cmp (const gchar *a,
4c1d22
   return ret;
4c1d22
 }
4c1d22
 
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static void
4c1d22
 load_scripts (PolkitBackendJsAuthority  *authority)
4c1d22
 {
4c1d22
@@ -339,6 +340,8 @@ reload_scripts (PolkitBackendJsAuthority *authority)
4c1d22
   jsval argv[1] = {JSVAL_NULL};
4c1d22
   jsval rval = JSVAL_NULL;
4c1d22
 
4c1d22
+  JS_BeginRequest (authority->priv->cx);
4c1d22
+
4c1d22
   if (!JS_CallFunctionName(authority->priv->cx,
4c1d22
                            authority->priv->js_polkit,
4c1d22
                            "_deleteRules",
4c1d22
@@ -364,7 +367,7 @@ reload_scripts (PolkitBackendJsAuthority *authority)
4c1d22
   /* Let applications know we have new rules... */
4c1d22
   g_signal_emit_by_name (authority, "changed");
4c1d22
  out:
4c1d22
-  ;
4c1d22
+  JS_EndRequest (authority->priv->cx);
4c1d22
 }
4c1d22
 
4c1d22
 static void
4c1d22
@@ -447,6 +450,7 @@ static void
4c1d22
 polkit_backend_js_authority_constructed (GObject *object)
4c1d22
 {
4c1d22
   PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
4c1d22
+  gboolean entered_request = FALSE;
4c1d22
 
4c1d22
   authority->priv->rt = JS_NewRuntime (8L * 1024L * 1024L);
4c1d22
   if (authority->priv->rt == NULL)
4c1d22
@@ -466,6 +470,9 @@ polkit_backend_js_authority_constructed (GObject *object)
4c1d22
   JS_SetErrorReporter(authority->priv->cx, report_error);
4c1d22
   JS_SetContextPrivate (authority->priv->cx, authority);
4c1d22
 
4c1d22
+  JS_BeginRequest(authority->priv->cx);
4c1d22
+  entered_request = TRUE;
4c1d22
+
4c1d22
   authority->priv->js_global =
4c1d22
 #if JS_VERSION == 186
4c1d22
     JS_NewGlobalObject (authority->priv->cx, &js_global_class, NULL);
4c1d22
@@ -526,10 +533,15 @@ polkit_backend_js_authority_constructed (GObject *object)
4c1d22
   setup_file_monitors (authority);
4c1d22
   load_scripts (authority);
4c1d22
 
4c1d22
+  JS_EndRequest (authority->priv->cx);
4c1d22
+  entered_request = FALSE;
4c1d22
+
4c1d22
   G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->constructed (object);
4c1d22
   return;
4c1d22
 
4c1d22
  fail:
4c1d22
+  if (entered_request)
4c1d22
+    JS_EndRequest (authority->priv->cx);
4c1d22
   g_critical ("Error initializing JavaScript environment");
4c1d22
   g_assert_not_reached ();
4c1d22
 }
4c1d22
@@ -642,6 +654,7 @@ polkit_backend_js_authority_class_init (PolkitBackendJsAuthorityClass *klass)
4c1d22
 
4c1d22
 /* ---------------------------------------------------------------------------------------------------- */
4c1d22
 
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static void
4c1d22
 set_property_str (PolkitBackendJsAuthority  *authority,
4c1d22
                   JSObject                  *obj,
4c1d22
@@ -655,6 +668,7 @@ set_property_str (PolkitBackendJsAuthority  *authority,
4c1d22
   JS_SetProperty (authority->priv->cx, obj, name, &value_jsval);
4c1d22
 }
4c1d22
 
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static void
4c1d22
 set_property_strv (PolkitBackendJsAuthority  *authority,
4c1d22
                    JSObject                  *obj,
4c1d22
@@ -681,7 +695,7 @@ set_property_strv (PolkitBackendJsAuthority  *authority,
4c1d22
   JS_SetProperty (authority->priv->cx, obj, name, &value_jsval);
4c1d22
 }
4c1d22
 
4c1d22
-
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static void
4c1d22
 set_property_int32 (PolkitBackendJsAuthority  *authority,
4c1d22
                     JSObject                  *obj,
4c1d22
@@ -693,6 +707,7 @@ set_property_int32 (PolkitBackendJsAuthority  *authority,
4c1d22
   JS_SetProperty (authority->priv->cx, obj, name, &value_jsval);
4c1d22
 }
4c1d22
 
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static void
4c1d22
 set_property_bool (PolkitBackendJsAuthority  *authority,
4c1d22
                    JSObject                  *obj,
4c1d22
@@ -706,6 +721,7 @@ set_property_bool (PolkitBackendJsAuthority  *authority,
4c1d22
 
4c1d22
 /* ---------------------------------------------------------------------------------------------------- */
4c1d22
 
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static gboolean
4c1d22
 subject_to_jsval (PolkitBackendJsAuthority  *authority,
4c1d22
                   PolkitSubject             *subject,
4c1d22
@@ -838,6 +854,7 @@ subject_to_jsval (PolkitBackendJsAuthority  *authority,
4c1d22
 
4c1d22
 /* ---------------------------------------------------------------------------------------------------- */
4c1d22
 
4c1d22
+/* authority->priv->cx must be within a request */
4c1d22
 static gboolean
4c1d22
 action_and_details_to_jsval (PolkitBackendJsAuthority  *authority,
4c1d22
                              const gchar               *action_id,
4c1d22
@@ -1041,6 +1058,8 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA
4c1d22
   gchar *ret_str = NULL;
4c1d22
   gchar **ret_strs = NULL;
4c1d22
 
4c1d22
+  JS_BeginRequest (authority->priv->cx);
4c1d22
+
4c1d22
   if (!action_and_details_to_jsval (authority, action_id, details, &argv[0], &error))
4c1d22
     {
4c1d22
       polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
4c1d22
@@ -1120,6 +1139,8 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA
4c1d22
 
4c1d22
   JS_MaybeGC (authority->priv->cx);
4c1d22
 
4c1d22
+  JS_EndRequest (authority->priv->cx);
4c1d22
+
4c1d22
   return ret;
4c1d22
 }
4c1d22
 
4c1d22
@@ -1146,6 +1167,8 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu
4c1d22
   gchar *ret_str = NULL;
4c1d22
   gboolean good = FALSE;
4c1d22
 
4c1d22
+  JS_BeginRequest (authority->priv->cx);
4c1d22
+
4c1d22
   if (!action_and_details_to_jsval (authority, action_id, details, &argv[0], &error))
4c1d22
     {
4c1d22
       polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
4c1d22
@@ -1222,6 +1245,8 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu
4c1d22
 
4c1d22
   JS_MaybeGC (authority->priv->cx);
4c1d22
 
4c1d22
+  JS_EndRequest (authority->priv->cx);
4c1d22
+
4c1d22
   return ret;
4c1d22
 }
4c1d22
 
4c1d22
4c1d22
commit 5c668722320eb363f713a0998934aa48fecd56cb
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Register heap-based JSObject pointers to GC
4c1d22
    
4c1d22
    This is necessary so that the GC can move the objects (though I haven't
4c1d22
    so far encountered this in testing).
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index 88f31bd..39f7060 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -482,6 +482,7 @@ polkit_backend_js_authority_constructed (GObject *object)
4c1d22
 
4c1d22
   if (authority->priv->js_global == NULL)
4c1d22
     goto fail;
4c1d22
+  JS_AddObjectRoot (authority->priv->cx, &authority->priv->js_global);
4c1d22
 
4c1d22
   if (!JS_InitStandardClasses (authority->priv->cx, authority->priv->js_global))
4c1d22
     goto fail;
4c1d22
@@ -494,6 +495,7 @@ polkit_backend_js_authority_constructed (GObject *object)
4c1d22
                                                 JSPROP_ENUMERATE);
4c1d22
   if (authority->priv->js_polkit == NULL)
4c1d22
     goto fail;
4c1d22
+  JS_AddObjectRoot (authority->priv->cx, &authority->priv->js_polkit);
4c1d22
 
4c1d22
   if (!JS_DefineFunctions (authority->priv->cx,
4c1d22
                            authority->priv->js_polkit,
4c1d22
@@ -572,6 +574,11 @@ polkit_backend_js_authority_finalize (GObject *object)
4c1d22
   g_free (authority->priv->dir_monitors);
4c1d22
   g_strfreev (authority->priv->rules_dirs);
4c1d22
 
4c1d22
+  JS_BeginRequest (authority->priv->cx);
4c1d22
+  JS_RemoveObjectRoot (authority->priv->cx, &authority->priv->js_polkit);
4c1d22
+  JS_RemoveObjectRoot (authority->priv->cx, &authority->priv->js_global);
4c1d22
+  JS_EndRequest (authority->priv->cx);
4c1d22
+
4c1d22
   JS_DestroyContext (authority->priv->cx);
4c1d22
   JS_DestroyRuntime (authority->priv->rt);
4c1d22
   /* JS_ShutDown (); */
4c1d22
4c1d22
commit 2881f8b260c03df29afb0e35e6d1707240f95ad7
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Prevent builds against SpiderMonkey with exact stack rooting
4c1d22
    
4c1d22
    “Exact stack rooting” means that every on-stack pointer to a JavaScript
4c1d22
    value needs to be registered with the runtime.  The current code doesn't
4c1d22
    do this, so it is not safe to use against a runtime with this
4c1d22
    configuration.  Luckily this configuration is not default.
4c1d22
    
4c1d22
    See
4c1d22
    https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/GC/Exact_Stack_Rooting
4c1d22
    and other pages in the wiki for what the conversion would require.
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index 39f7060..22812a6 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -43,6 +43,13 @@
4c1d22
 
4c1d22
 #include "initjs.h" /* init.js */
4c1d22
 
4c1d22
+#ifdef JSGC_USE_EXACT_ROOTING
4c1d22
+/* See https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/GC/Exact_Stack_Rooting
4c1d22
+ * for more information about exact stack rooting.
4c1d22
+ */
4c1d22
+#error "This code is not safe in SpiderMonkey exact stack rooting configurations"
4c1d22
+#endif
4c1d22
+
4c1d22
 /**
4c1d22
  * SECTION:polkitbackendjsauthority
4c1d22
  * @title: PolkitBackendJsAuthority
4c1d22
4c1d22
commit b544f10dd469ae3cfedc026db71ee76e9ef511a2
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Clear the JS operation callback before invoking JS in the callback
4c1d22
    
4c1d22
    Setting the callback to NULL is required by
4c1d22
    https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_SetOperationCallback
4c1d22
    to avoid the possibility of recursion.
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index 22812a6..8a0a097 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -961,9 +961,11 @@ js_operation_callback (JSContext *cx)
4c1d22
   polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), "Terminating runaway script");
4c1d22
 
4c1d22
   /* Throw an exception - this way the JS code can ignore the runaway script handling */
4c1d22
+  JS_SetOperationCallback (authority->priv->cx, NULL);
4c1d22
   val_str = JS_NewStringCopyZ (cx, "Terminating runaway script");
4c1d22
   val = STRING_TO_JSVAL (val_str);
4c1d22
   JS_SetPendingException (authority->priv->cx, val);
4c1d22
+  JS_SetOperationCallback (authority->priv->cx, js_operation_callback);
4c1d22
   return JS_FALSE;
4c1d22
 }
4c1d22
 
4c1d22
4c1d22
commit d7da6a23766e9c95fa333a0a9c742f7397c0ad22
4c1d22
Author: Miloslav Trmač <mitr@redhat.com>
4c1d22
Date:   Tue Jul 1 20:00:48 2014 +0200
4c1d22
4c1d22
    Fix spurious timeout exceptions on GC
4c1d22
    
4c1d22
    The JS “Operation callback” can be called by the runtime for other
4c1d22
    reasons, not only when we trigger it by a timeout—notably as part of GC.
4c1d22
    So, make sure to only raise an exception if there actually was a
4c1d22
    timeout.
4c1d22
    
4c1d22
    Adding a whole extra mutex to protect a single boolean is somewhat of an
4c1d22
    overkill, but better than worrying about “subtle bugs and occasionally
4c1d22
    undefined behaviour” the g_atomic_* API is warning about.
4c1d22
    
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=69501
4c1d22
    also
4c1d22
    https://bugs.freedesktop.org/show_bug.cgi?id=77524
4c1d22
4c1d22
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
index 8a0a097..097dcc5 100644
4c1d22
--- a/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
+++ b/src/polkitbackend/polkitbackendjsauthority.c
4c1d22
@@ -80,6 +80,8 @@ struct _PolkitBackendJsAuthorityPrivate
4c1d22
   GMainContext *rkt_context;
4c1d22
   GMainLoop *rkt_loop;
4c1d22
   GSource *rkt_source;
4c1d22
+  GMutex rkt_timeout_pending_mutex;
4c1d22
+  gboolean rkt_timeout_pending;
4c1d22
 
4c1d22
   /* A list of JSObject instances */
4c1d22
   GList *scripts;
4c1d22
@@ -528,6 +530,7 @@ polkit_backend_js_authority_constructed (GObject *object)
4c1d22
 
4c1d22
   g_mutex_init (&authority->priv->rkt_init_mutex);
4c1d22
   g_cond_init (&authority->priv->rkt_init_cond);
4c1d22
+  g_mutex_init (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
 
4c1d22
   authority->priv->runaway_killer_thread = g_thread_new ("runaway-killer-thread",
4c1d22
                                                          runaway_killer_thread_func,
4c1d22
@@ -563,6 +566,7 @@ polkit_backend_js_authority_finalize (GObject *object)
4c1d22
 
4c1d22
   g_mutex_clear (&authority->priv->rkt_init_mutex);
4c1d22
   g_cond_clear (&authority->priv->rkt_init_cond);
4c1d22
+  g_mutex_clear (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
 
4c1d22
   /* shut down the killer thread */
4c1d22
   g_assert (authority->priv->rkt_loop != NULL);
4c1d22
@@ -957,6 +961,18 @@ js_operation_callback (JSContext *cx)
4c1d22
   JSString *val_str;
4c1d22
   jsval val;
4c1d22
 
4c1d22
+  /* This callback can be called by the runtime at any time without us causing
4c1d22
+   * it by JS_TriggerOperationCallback().
4c1d22
+   */
4c1d22
+  g_mutex_lock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
+  if (!authority->priv->rkt_timeout_pending)
4c1d22
+    {
4c1d22
+      g_mutex_unlock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
+      return JS_TRUE;
4c1d22
+    }
4c1d22
+  authority->priv->rkt_timeout_pending = FALSE;
4c1d22
+  g_mutex_unlock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
+
4c1d22
   /* Log that we are terminating the script */
4c1d22
   polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), "Terminating runaway script");
4c1d22
 
4c1d22
@@ -974,6 +990,10 @@ rkt_on_timeout (gpointer user_data)
4c1d22
 {
4c1d22
   PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data);
4c1d22
 
4c1d22
+  g_mutex_lock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
+  authority->priv->rkt_timeout_pending = TRUE;
4c1d22
+  g_mutex_unlock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
+
4c1d22
   /* Supposedly this is thread-safe... */
4c1d22
 #if JS_VERSION == 186
4c1d22
   JS_TriggerOperationCallback (authority->priv->rt);
4c1d22
@@ -993,6 +1013,9 @@ runaway_killer_setup (PolkitBackendJsAuthority *authority)
4c1d22
   g_assert (authority->priv->rkt_source == NULL);
4c1d22
 
4c1d22
   /* set-up timer for runaway scripts, will be executed in runaway_killer_thread */
4c1d22
+  g_mutex_lock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
+  authority->priv->rkt_timeout_pending = FALSE;
4c1d22
+  g_mutex_unlock (&authority->priv->rkt_timeout_pending_mutex);
4c1d22
   authority->priv->rkt_source = g_timeout_source_new_seconds (15);
4c1d22
   g_source_set_callback (authority->priv->rkt_source, rkt_on_timeout, authority, NULL);
4c1d22
   g_source_attach (authority->priv->rkt_source, authority->priv->rkt_context);