Fix: sessiond: notification: use after free of trigger object
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Tue, 23 Mar 2021 23:50:30 +0000 (19:50 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 2 Apr 2021 19:38:59 +0000 (15:38 -0400)
commit091fa780af74dc1a93eaeff50d8c0baf1de8c41f
tree3c9c9081c14ece3cfe0b18829908a4f0d75d8a4e
parent6487ad53bfafc764c432a4378c06d0d840f000ea
Fix: sessiond: notification: use after free of trigger object

Background
==========
* Clients can subscribe to certain specific conditions (e.g. buffer
  usage) using the `lttng_notification_channel_subscribe()` function.

* This subscription is only useful once a trigger with that condition
  AND at least one notify action is registered.

* The sessiond keeps a list for client subscribed to each registered
  condition.

* More than one trigger with the same condition may be registered
  the sessiond at the same time if they have different actions.

Issue
=====
Currently, when registering a trigger (T1) the sessiond looks if there
is already a client list for the condition of this trigger. If not, the
sessiond links the newly created client list object to that trigger T1
by keeping a pointer to it.

This means that if another trigger (T2) is registered with the same
condition (but a different name, or different actions) it will reuse the
same client list object and use the pointer to the T1.

This causes problems if T1 is unregistered before T2. In that case, the
pointer to T1 in the client list object is pointing to a deallocated
trigger object.

This issue is not encountered with the current test suite, namely the
`test_notification_multi_app` test case, because triggers with the same
condition also had the same action, so they are considered identical and
are not registered.

This issue was first witnessed when adding a trigger name comparison in
the `lttng_trigger_is_equal()` function.

Fix
===
Change the client list object so that it has its own copy of the
condition and a list of dependent triggers. Each trigger with that
condition has a reference on this client list object.

When unregistering a trigger, the notification thread removes it for the
client list's triggers list and put its reference on the client list
object.

Tests
=====
This commit adds a parameter to the base_client that dictates if the
notify action should be in a group. This is a trick to create triggers
that are not equal but have the same behaviour.

The `test_notification_multi_app` test case is modified to turn on this
option every other trigger registration.

Semi-related cleanups
=====================
* Merge `notification_client_list_create()` and
  `publish_notification_client_list()` functions since they are used
  together anyway. This removes the need to call
  `notification_client_list_put()` at the end of the
  `_register_trigger()` function

* Rename `trigger_applies_to_client()` to `condition_applies_to_client()`.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I3ebb90a1a64236a440a085e6fc1b82726a0e5af9
src/bin/lttng-sessiond/condition-internal.c
src/bin/lttng-sessiond/condition-internal.h
src/bin/lttng-sessiond/notification-thread-events.c
src/bin/lttng-sessiond/notification-thread-internal.h
tests/regression/tools/notification/base_client.c
tests/regression/tools/notification/test_notification_multi_app
This page took 0.027241 seconds and 5 git commands to generate.