File pacemaker-libcrmservice-avoid-infinite-loop-on-bad-DBus-reply.patch of Package pacemaker.14737
commit 9a6fee929fd1de5b81df9780a4aaa1cc81743fb4
Author: Ken Gaillot <kgaillot@redhat.com>
Date: Fri Oct 13 11:11:11 2017 -0500
Low: libcrmservice: avoid infinite loop on bad DBus reply
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
index 6d139eee6..6adac46c3 100644
--- a/lib/services/systemd.c
+++ b/lib/services/systemd.c
@@ -391,52 +391,68 @@ systemd_unit_listall(void)
}
dbus_message_iter_recurse(&args, &unit);
- while (dbus_message_iter_get_arg_type (&unit) != DBUS_TYPE_INVALID) {
+ for (; dbus_message_iter_get_arg_type(&unit) != DBUS_TYPE_INVALID;
+ dbus_message_iter_next(&unit)) {
+
DBusBasicValue value;
+ const char *match = NULL;
+ char *unit_name = NULL;
+ char *basename = NULL;
if(!pcmk_dbus_type_check(reply, &unit, DBUS_TYPE_STRUCT, __FUNCTION__, __LINE__)) {
+ crm_debug("ListUnitFiles reply has unexpected type");
continue;
}
dbus_message_iter_recurse(&unit, &elem);
if(!pcmk_dbus_type_check(reply, &elem, DBUS_TYPE_STRING, __FUNCTION__, __LINE__)) {
+ crm_debug("ListUnitFiles reply does not contain a string");
continue;
}
dbus_message_iter_get_basic(&elem, &value);
+ if (value.str == NULL) {
+ crm_debug("ListUnitFiles reply did not provide a string");
+ continue;
+ }
crm_trace("DBus ListUnitFiles listed: %s", value.str);
- if(value.str) {
- const char *match = systemd_unit_extension(value.str);
-
- if (match) {
- char *unit_name = NULL;
- char *basename = NULL;
-
- // ListUnitFiles returns full path names
- basename = strrchr(value.str, '/');
- if (basename) {
- basename = basename + 1;
- } else {
- basename = value.str;
- }
-
- if (!strcmp(match, ".service")) {
- // Service is the "default" unit type, so strip it
- unit_name = strndup(basename, match - basename);
-
- } else if (!strcmp(match, ".mount")
- || !strcmp(match, ".socket")) {
- // Only list things we can start and stop
- unit_name = strdup(basename);
- }
- if (unit_name) {
- nfiles++;
- // @TODO sort alphabetically
- units = g_list_prepend(units, unit_name);
- }
- }
+
+ match = systemd_unit_extension(value.str);
+ if (match == NULL) {
+ // Unit files always have an extension, so skip if not present
+ crm_debug("ListUnitFiles entry '%s' does not have an extension",
+ value.str);
+ continue;
+ }
+
+ // ListUnitFiles returns full path names
+ basename = strrchr(value.str, '/');
+ if (basename) {
+ basename = basename + 1;
+ } else {
+ basename = value.str;
+ }
+
+ /* Unit files will include types (such as .target) that we can't manage,
+ * so filter the replies here.
+ */
+ if (!strcmp(match, ".service")) {
+ // Service is the "default" unit type, so strip it
+ unit_name = strndup(basename, match - basename);
+
+ } else if (!strcmp(match, ".mount")
+ || !strcmp(match, ".socket")) {
+ unit_name = strdup(basename);
+ }
+ if (unit_name == NULL) {
+ crm_trace("ListUnitFiles entry '%s' is not manageable",
+ value.str);
+ continue;
}
- dbus_message_iter_next (&unit);
+
+ nfiles++;
+ // @TODO sort alphabetically
+ units = g_list_prepend(units, unit_name);
}
dbus_message_unref(reply);