Fix: lib: add NULL check for destroy_listeners in destroy_component_class
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 31 Jan 2022 15:19:35 +0000 (10:19 -0500)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 16 Feb 2022 19:16:46 +0000 (14:16 -0500)
By doing this change, to simulate an allocation failure:

    @@ -99,6 +99,8 @@ int bt_component_class_init(struct bt_component_class *class,
      }

      class->description = g_string_new(NULL);
    + g_string_free(class->description, 1);
    + class->description = NULL;
      if (!class->description) {
      BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
      goto error;

... and trying to read a trace, we get this crash:

    ==2788787==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7f779199cd2b bp 0x7ffd04f1a300 sp 0x7ffd04f1a2c0 T0)
    ==2788787==The signal is caused by a READ memory access.
    ==2788787==Hint: address points to the zero page.
        #0 0x7f779199cd2b in destroy_component_class /home/simark/src/babeltrace/src/lib/graph/component-class.c:39
        #1 0x7f779199ca19 in bt_object_put_ref_no_null_check /home/simark/src/babeltrace/src/lib/object.h:307
        #2 0x7f779199cb85 in bt_object_put_ref /home/simark/src/babeltrace/src/lib/object.h:335
        #3 0x7f779199d57f in bt_component_class_init /home/simark/src/babeltrace/src/lib/graph/component-class.c:131

This is because destroy_component_class can be called before the
destroy_listeners field has been initialized.  Add a check for
destroy_listeners to be non-NULL in destroy_component_class.

Change-Id: I3616f608f05e2abed4a85a62bebe05b1efedeb2b
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/7185
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
src/lib/graph/component-class.c

index c3a47291ca0ec86d739e7169d0654015bc36a9fc..538cd77be1daff6a254ee80bffd03cf3ac087c6d 100644 (file)
@@ -36,15 +36,17 @@ void destroy_component_class(struct bt_object *obj)
        BT_LIB_LOGI("Destroying component class: %!+C", class);
 
        /* Call destroy listeners in reverse registration order */
-       for (i = class->destroy_listeners->len - 1; i >= 0; i--) {
-               struct bt_component_class_destroy_listener *listener =
-                       &g_array_index(class->destroy_listeners,
-                               struct bt_component_class_destroy_listener,
-                               i);
-
-               BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p",
-                       listener->func, listener->data);
-               listener->func(class, listener->data);
+       if (class->destroy_listeners) {
+               for (i = class->destroy_listeners->len - 1; i >= 0; i--) {
+                       struct bt_component_class_destroy_listener *listener =
+                               &g_array_index(class->destroy_listeners,
+                                       struct bt_component_class_destroy_listener,
+                                       i);
+
+                       BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p",
+                               listener->func, listener->data);
+                       listener->func(class, listener->data);
+               }
        }
 
        if (class->name) {
This page took 0.025208 seconds and 4 git commands to generate.