|
|
9dbb56 |
From a028743f5c88dd7c27c102c34535f25b42ea2c5f Mon Sep 17 00:00:00 2001
|
|
|
9dbb56 |
From: Kyle Walker <kwalker@redhat.com>
|
|
|
9dbb56 |
Date: Mon, 23 Apr 2018 13:07:37 -0400
|
|
|
9dbb56 |
Subject: [PATCH] Backport of:
|
|
|
9dbb56 |
https://bugs.freedesktop.org/attachment.cgi?id=138819
|
|
|
9dbb56 |
|
|
|
9dbb56 |
Signed-off-by: Kyle Walker <kwalker@redhat.com>
|
|
|
9dbb56 |
---
|
|
|
9dbb56 |
src/polkitbackend/polkitbackendjsauthority.c | 76 +++++++++++++++++++++++++++-
|
|
|
9dbb56 |
1 file changed, 74 insertions(+), 2 deletions(-)
|
|
|
9dbb56 |
|
|
|
9dbb56 |
diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c
|
|
|
9dbb56 |
index 39ed718..fd1dbfd 100644
|
|
|
9dbb56 |
--- a/src/polkitbackend/polkitbackendjsauthority.c
|
|
|
9dbb56 |
+++ b/src/polkitbackend/polkitbackendjsauthority.c
|
|
|
9dbb56 |
@@ -83,6 +83,13 @@ struct _PolkitBackendJsAuthorityPrivate
|
|
|
9dbb56 |
GMutex rkt_timeout_pending_mutex;
|
|
|
9dbb56 |
gboolean rkt_timeout_pending;
|
|
|
9dbb56 |
|
|
|
9dbb56 |
+ /* avoid zombies by reap child in a new thread */
|
|
|
9dbb56 |
+ GThread *child_reaper_thread;
|
|
|
9dbb56 |
+ GMutex crt_init_mutex;
|
|
|
9dbb56 |
+ GCond crt_init_cond;
|
|
|
9dbb56 |
+ GMainContext *crt_context;
|
|
|
9dbb56 |
+ GMainLoop *crt_loop;
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
/* A list of JSObject instances */
|
|
|
9dbb56 |
GList *scripts;
|
|
|
9dbb56 |
};
|
|
|
9dbb56 |
@@ -124,6 +131,7 @@ enum
|
|
|
9dbb56 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
9dbb56 |
|
|
|
9dbb56 |
static gpointer runaway_killer_thread_func (gpointer user_data);
|
|
|
9dbb56 |
+static gpointer child_reaper_thread_func (gpointer user_data);
|
|
|
9dbb56 |
|
|
|
9dbb56 |
static GList *polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
|
|
|
9dbb56 |
PolkitSubject *caller,
|
|
|
9dbb56 |
@@ -461,6 +469,18 @@ polkit_backend_js_authority_constructed (GObject *object)
|
|
|
9dbb56 |
PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
|
|
|
9dbb56 |
gboolean entered_request = FALSE;
|
|
|
9dbb56 |
|
|
|
9dbb56 |
+ g_mutex_init (&authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+ g_cond_init (&authority->priv->crt_init_cond);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ authority->priv->child_reaper_thread = g_thread_new ("reap-child-thread",
|
|
|
9dbb56 |
+ child_reaper_thread_func,
|
|
|
9dbb56 |
+ authority);
|
|
|
9dbb56 |
+ /* wait for child_reaper_thread to set up its GMainContext */
|
|
|
9dbb56 |
+ g_mutex_lock (&authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+ while (authority->priv->crt_context == NULL)
|
|
|
9dbb56 |
+ g_cond_wait (&authority->priv->crt_init_cond, &authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+ g_mutex_unlock (&authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
authority->priv->rt = JS_NewRuntime (8L * 1024L * 1024L);
|
|
|
9dbb56 |
if (authority->priv->rt == NULL)
|
|
|
9dbb56 |
goto fail;
|
|
|
9dbb56 |
@@ -585,6 +605,15 @@ polkit_backend_js_authority_finalize (GObject *object)
|
|
|
9dbb56 |
g_free (authority->priv->dir_monitors);
|
|
|
9dbb56 |
g_strfreev (authority->priv->rules_dirs);
|
|
|
9dbb56 |
|
|
|
9dbb56 |
+ g_mutex_clear (&authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+ g_cond_clear (&authority->priv->crt_init_cond);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ /* shut down the child reaper thread */
|
|
|
9dbb56 |
+ g_assert (authority->priv->crt_loop != NULL);
|
|
|
9dbb56 |
+ g_main_loop_quit (authority->priv->crt_loop);
|
|
|
9dbb56 |
+ g_thread_join (authority->priv->child_reaper_thread);
|
|
|
9dbb56 |
+ g_assert (authority->priv->crt_loop == NULL);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
JS_BeginRequest (authority->priv->cx);
|
|
|
9dbb56 |
JS_RemoveObjectRoot (authority->priv->cx, &authority->priv->js_polkit);
|
|
|
9dbb56 |
JS_RemoveObjectRoot (authority->priv->cx, &authority->priv->js_global);
|
|
|
9dbb56 |
@@ -1360,6 +1389,7 @@ get_signal_name (gint signal_number)
|
|
|
9dbb56 |
|
|
|
9dbb56 |
typedef struct
|
|
|
9dbb56 |
{
|
|
|
9dbb56 |
+ PolkitBackendJsAuthority *authority;
|
|
|
9dbb56 |
GMainLoop *loop;
|
|
|
9dbb56 |
GAsyncResult *res;
|
|
|
9dbb56 |
} SpawnData;
|
|
|
9dbb56 |
@@ -1379,7 +1409,7 @@ js_polkit_spawn (JSContext *cx,
|
|
|
9dbb56 |
unsigned js_argc,
|
|
|
9dbb56 |
jsval *vp)
|
|
|
9dbb56 |
{
|
|
|
9dbb56 |
- /* PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (JS_GetContextPrivate (cx)); */
|
|
|
9dbb56 |
+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (JS_GetContextPrivate (cx));
|
|
|
9dbb56 |
JSBool ret = JS_FALSE;
|
|
|
9dbb56 |
JSObject *array_object;
|
|
|
9dbb56 |
gchar *standard_output = NULL;
|
|
|
9dbb56 |
@@ -1424,6 +1454,8 @@ js_polkit_spawn (JSContext *cx,
|
|
|
9dbb56 |
JS_free (cx, s);
|
|
|
9dbb56 |
}
|
|
|
9dbb56 |
|
|
|
9dbb56 |
+ data.authority = authority;
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
context = g_main_context_new ();
|
|
|
9dbb56 |
loop = g_main_loop_new (context, FALSE);
|
|
|
9dbb56 |
|
|
|
9dbb56 |
@@ -1540,6 +1572,8 @@ js_polkit_user_is_in_netgroup (JSContext *cx,
|
|
|
9dbb56 |
|
|
|
9dbb56 |
typedef struct
|
|
|
9dbb56 |
{
|
|
|
9dbb56 |
+ PolkitBackendJsAuthority *authority;
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
GSimpleAsyncResult *simple; /* borrowed reference */
|
|
|
9dbb56 |
GMainContext *main_context; /* may be NULL */
|
|
|
9dbb56 |
|
|
|
9dbb56 |
@@ -1572,11 +1606,43 @@ utils_child_watch_from_release_cb (GPid pid,
|
|
|
9dbb56 |
gint status,
|
|
|
9dbb56 |
gpointer user_data)
|
|
|
9dbb56 |
{
|
|
|
9dbb56 |
+ g_print("Child(pid: %d) has been reaped!\n", pid);
|
|
|
9dbb56 |
+}
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+/* ---------------------------------------------------------------------------------------------------- */
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+static gpointer
|
|
|
9dbb56 |
+child_reaper_thread_func (gpointer user_data)
|
|
|
9dbb56 |
+{
|
|
|
9dbb56 |
+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ g_mutex_lock (&authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ authority->priv->crt_context = g_main_context_new ();
|
|
|
9dbb56 |
+ authority->priv->crt_loop = g_main_loop_new (authority->priv->crt_context, FALSE);
|
|
|
9dbb56 |
+ g_main_context_push_thread_default (authority->priv->crt_context);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ /* Signal the main thread that we're done constructing */
|
|
|
9dbb56 |
+ g_cond_signal (&authority->priv->crt_init_cond);
|
|
|
9dbb56 |
+ g_mutex_unlock (&authority->priv->crt_init_mutex);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ g_main_loop_run (authority->priv->crt_loop);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ g_main_context_pop_thread_default (authority->priv->crt_context);
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ g_main_loop_unref (authority->priv->crt_loop);
|
|
|
9dbb56 |
+ authority->priv->crt_loop = NULL;
|
|
|
9dbb56 |
+ g_main_context_unref (authority->priv->crt_context);
|
|
|
9dbb56 |
+ authority->priv->crt_context = NULL;
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ return NULL;
|
|
|
9dbb56 |
}
|
|
|
9dbb56 |
|
|
|
9dbb56 |
+/* ---------------------------------------------------------------------------------------------------- */
|
|
|
9dbb56 |
static void
|
|
|
9dbb56 |
utils_spawn_data_free (UtilsSpawnData *data)
|
|
|
9dbb56 |
{
|
|
|
9dbb56 |
+ PolkitBackendJsAuthority *authority = data->authority;
|
|
|
9dbb56 |
if (data->timeout_source != NULL)
|
|
|
9dbb56 |
{
|
|
|
9dbb56 |
g_source_destroy (data->timeout_source);
|
|
|
9dbb56 |
@@ -1604,12 +1670,17 @@ utils_spawn_data_free (UtilsSpawnData *data)
|
|
|
9dbb56 |
* Avoid taking a references to ourselves. but note that we need
|
|
|
9dbb56 |
* to pass the GSource so we can nuke it once handled.
|
|
|
9dbb56 |
*/
|
|
|
9dbb56 |
+
|
|
|
9dbb56 |
+ /* avoid zombies by reaping child in a new thread
|
|
|
9dbb56 |
+ * add source to reap thread context
|
|
|
9dbb56 |
+ */
|
|
|
9dbb56 |
+ GMainContext *reap_context = authority->priv->crt_context;
|
|
|
9dbb56 |
source = g_child_watch_source_new (data->child_pid);
|
|
|
9dbb56 |
g_source_set_callback (source,
|
|
|
9dbb56 |
(GSourceFunc) utils_child_watch_from_release_cb,
|
|
|
9dbb56 |
source,
|
|
|
9dbb56 |
(GDestroyNotify) g_source_destroy);
|
|
|
9dbb56 |
- g_source_attach (source, data->main_context);
|
|
|
9dbb56 |
+ g_source_attach (source, reap_context);
|
|
|
9dbb56 |
g_source_unref (source);
|
|
|
9dbb56 |
data->child_pid = 0;
|
|
|
9dbb56 |
}
|
|
|
9dbb56 |
@@ -1776,6 +1847,7 @@ utils_spawn (const gchar *const *argv,
|
|
|
9dbb56 |
GError *error;
|
|
|
9dbb56 |
|
|
|
9dbb56 |
data = g_slice_new0 (UtilsSpawnData);
|
|
|
9dbb56 |
+ data->authority = ((SpawnData *)user_data)->authority;
|
|
|
9dbb56 |
data->timeout_seconds = timeout_seconds;
|
|
|
9dbb56 |
data->simple = g_simple_async_result_new (NULL,
|
|
|
9dbb56 |
callback,
|
|
|
9dbb56 |
--
|
|
|
9dbb56 |
2.14.3
|
|
|
9dbb56 |
|