File pacemaker-libservices-completed-ops-arent-on-blocked-ops-list.patch of Package pacemaker.14737

commit 94a4c58f675d163085a055f59fd6c3a2c9f57c43
Author: Ken Gaillot <kgaillot@redhat.com>
Date:   Mon Feb 27 14:17:01 2017 -0600

    Fix: libservices: ensure completed ops aren't on blocked ops list
    
    This refactors removal of a completed operation from the in-flight ops list
    into a new internal function services_untrack_op(), which allows the
    in-flight ops list and handle_blocked_ops() to be static to services.c.
    
    The new function also ensures the op isn't on the blocked ops list,
    which could otherwise result in a use-after-free bug.

Index: pacemaker/lib/services/services.c
===================================================================
--- pacemaker.orig/lib/services/services.c
+++ pacemaker/lib/services/services.c
@@ -55,7 +55,9 @@ GHashTable *recurring_actions = NULL;
 GList *blocked_ops = NULL;
 
 /* ops currently active (in-flight) */
-GList *inflight_ops = NULL;
+static GList *inflight_ops = NULL;
+
+static void handle_blocked_ops(void);
 
 svc_action_t *
 services_action_create(const char *name, const char *action, int interval, int timeout)
@@ -614,6 +616,23 @@ services_add_inflight_op(svc_action_t *
     }
 }
 
+/*!
+ * \internal
+ * \brief Stop tracking an operation that completed
+ *
+ * \param[in] op  Operation to stop tracking
+ */
+void
+services_untrack_op(svc_action_t *op)
+{
+    /* Op is no longer in-flight or blocked */
+    inflight_ops = g_list_remove(inflight_ops, op);
+    blocked_ops = g_list_remove(blocked_ops, op);
+
+    /* Op is no longer blocking other ops, so check if any need to run */
+    handle_blocked_ops();
+}
+
 gboolean
 services_action_async(svc_action_t * op, void (*action_callback) (svc_action_t *))
 {
@@ -658,7 +677,7 @@ is_op_blocked(const char *rsc)
     return FALSE;
 }
 
-void
+static void
 handle_blocked_ops(void)
 {
     GList *executed_ops = NULL;
Index: pacemaker/lib/services/services_linux.c
===================================================================
--- pacemaker.orig/lib/services/services_linux.c
+++ pacemaker/lib/services/services_linux.c
@@ -47,9 +47,6 @@
 #  include "crm/common/cib_secrets.h"
 #endif
 
-/* ops currently active (in-flight) */
-extern GList *inflight_ops;
-
 static inline void
 set_fd_opts(int fd, int opts)
 {
@@ -259,9 +256,7 @@ operation_finalize(svc_action_t * op)
 
     op->pid = 0;
 
-    inflight_ops = g_list_remove(inflight_ops, op);
-
-    handle_blocked_ops();
+    services_untrack_op(op);
 
     if (!recurring && op->synchronous == FALSE) {
         /*
Index: pacemaker/lib/services/services_private.h
===================================================================
--- pacemaker.orig/lib/services/services_private.h
+++ pacemaker/lib/services/services_private.h
@@ -61,7 +61,7 @@ gboolean operation_finalize(svc_action_t
 
 void services_add_inflight_op(svc_action_t *op);
 
-void handle_blocked_ops(void);
+void services_untrack_op(svc_action_t *op);
 
 gboolean is_op_blocked(const char *rsc);
 
openSUSE Build Service is sponsored by