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

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