Fix: sessiond: notification: use after free of trigger object
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-internal.h
CommitLineData
8abe313a 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8abe313a 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
8abe313a 5 *
8abe313a
JG
6 */
7
8#ifndef NOTIFICATION_THREAD_INTERNAL_H
9#define NOTIFICATION_THREAD_INTERNAL_H
10
f2b3ef9f
JG
11#include <common/compat/socket.h>
12#include <common/credentials.h>
882093ee 13#include <common/payload.h>
f2b3ef9f 14#include <lttng/notification/channel-internal.h>
8abe313a 15#include <lttng/ref-internal.h>
f2b3ef9f 16#include <stdbool.h>
ae0a823f 17#include <unistd.h>
f2b3ef9f
JG
18#include <urcu/rculfhash.h>
19#include <urcu/ref.h>
20#include <urcu/call-rcu.h>
21#include "notification-thread.h"
22
23struct lttng_evaluation;
24struct notification_thread_handle;
8abe313a
JG
25
26struct channel_key {
27 uint64_t key;
28 enum lttng_domain_type domain;
29};
30
31struct session_info {
32 struct lttng_ref ref;
33 char *name;
34 uid_t uid;
35 gid_t gid;
36 /*
c7283958 37 * Hashtable containing back-refs (weak) to all channels in this session.
8abe313a
JG
38 * The hashtable's key is a hash of (struct channel_key) and
39 * the value is of type (struct channel_info *).
40 */
41 struct cds_lfht *channel_infos_ht;
ea9a44f0 42 struct lttng_session_trigger_list *trigger_list;
8abe313a
JG
43 /* Node in the notification thread state's sessions_ht. */
44 struct cds_lfht_node sessions_ht_node;
1eee26c5
JG
45 /*
46 * Weak reference to the thread state's sessions_ht. Used for removal on
47 * destruction.
48 */
49 struct cds_lfht *sessions_ht;
e8360425 50 uint64_t consumed_data_size;
51eab943
JG
51 struct {
52 /* Whether a rotation is ongoing for this session. */
53 bool ongoing;
54 /* Identifier of the currently ongoing rotation. */
55 uint64_t id;
56 } rotation;
83b934ad
MD
57 /* call_rcu delayed reclaim. */
58 struct rcu_head rcu_node;
8abe313a
JG
59};
60
61struct channel_info {
62 struct channel_key key;
63 char *name;
64 uint64_t capacity;
65 /*
66 * A channel info holds a reference (lttng_ref) on session_info.
67 * session_info, in return, holds a weak reference to the channel.
68 */
69 struct session_info *session_info;
70 /* Node in the notification thread state's channels_ht. */
71 struct cds_lfht_node channels_ht_node;
72 /* Node in the session_info's channels_ht. */
73 struct cds_lfht_node session_info_channels_ht_node;
83b934ad
MD
74 /* call_rcu delayed reclaim. */
75 struct rcu_head rcu_node;
8abe313a
JG
76};
77
b9a8d78f
FD
78/*
79 * Facilities to carry the different notifications type in the action
80 * processing code path.
81 */
82struct lttng_event_notifier_notification {
83 uint64_t tracer_token;
84 enum lttng_domain_type type;
82b3cbf4
JR
85 size_t capture_buf_size;
86 char *capture_buffer;
b9a8d78f
FD
87};
88
f2b3ef9f
JG
89struct notification_client_list_element {
90 struct notification_client *client;
91 struct cds_list_head node;
92};
93
94/*
95 * Thread safety of notification_client and notification_client_list.
96 *
97 * The notification thread (main thread) and the action executor
98 * interact through client lists. Hence, when the action executor
99 * thread looks-up the list of clients subscribed to a given
100 * condition, it will acquire a reference to the list and lock it
101 * while attempting to communicate with the various clients.
102 *
103 * It is not necessary to reference-count clients as they are guaranteed
104 * to be 'alive' if they are present in a list and that list is locked. Indeed,
105 * removing references to the client from those subscription lists is part of
106 * the work performed on destruction of a client.
107 *
108 * No provision for other access scenarios are taken into account;
109 * this is the bare minimum to make these accesses safe and the
110 * notification thread's state is _not_ "thread-safe" in any general
111 * sense.
112 */
113struct notification_client_list {
114 pthread_mutex_t lock;
115 struct urcu_ref ref;
091fa780
FD
116 struct lttng_condition *condition;
117 struct cds_list_head triggers_list;
118 struct cds_list_head clients_list;
f2b3ef9f
JG
119 /* Weak reference to container. */
120 struct cds_lfht *notification_trigger_clients_ht;
121 struct cds_lfht_node notification_trigger_clients_ht_node;
122 /* call_rcu delayed reclaim. */
123 struct rcu_head rcu_node;
124};
125
126struct notification_client {
6c24d3fd
JG
127 /*
128 * Nests within the notification_client_list lock.
129 *
130 * Protects the outbound communication and the active flag which
131 * is used by both the notification and action executor threads.
132 *
133 * The remaining fields of the object can be used without any
134 * synchronization as they are either immutable (id, creds, version) or
135 * only accessed by the notification thread.
136 */
f2b3ef9f
JG
137 pthread_mutex_t lock;
138 notification_client_id id;
139 int socket;
140 /* Client protocol version. */
141 uint8_t major, minor;
142 uid_t uid;
143 gid_t gid;
144 /*
145 * Indicates if the credentials and versions of the client have been
146 * checked.
147 */
148 bool validated;
149 /*
150 * Conditions to which the client's notification channel is subscribed.
151 * List of struct lttng_condition_list_node. The condition member is
152 * owned by the client.
153 */
154 struct cds_list_head condition_list;
155 struct cds_lfht_node client_socket_ht_node;
156 struct cds_lfht_node client_id_ht_node;
157 struct {
158 /*
159 * If a client's communication is inactive, it means that a
160 * fatal error has occurred (could be either a protocol error or
161 * the socket API returned a fatal error). No further
162 * communication should be attempted; the client is queued for
163 * clean-up.
164 */
165 bool active;
166 struct {
167 /*
168 * During the reception of a message, the reception
169 * buffers' "size" is set to contain the current
170 * message's complete payload.
171 */
882093ee 172 struct lttng_payload payload;
f2b3ef9f
JG
173 /* Bytes left to receive for the current message. */
174 size_t bytes_to_receive;
882093ee
JR
175 /* FDs left to receive for the current message. */
176 int fds_to_receive;
f2b3ef9f
JG
177 /* Type of the message being received. */
178 enum lttng_notification_channel_message_type msg_type;
179 /*
180 * Indicates whether or not credentials are expected
181 * from the client.
182 */
183 bool expect_creds;
184 /*
185 * Indicates whether or not credentials were received
186 * from the client.
187 */
188 bool creds_received;
189 /* Only used during credentials reception. */
190 lttng_sock_cred creds;
191 } inbound;
192 struct {
193 /*
194 * Indicates whether or not a notification addressed to
195 * this client was dropped because a command reply was
196 * already buffered.
197 *
198 * A notification is dropped whenever the buffer is not
199 * empty.
200 */
201 bool dropped_notification;
202 /*
203 * Indicates whether or not a command reply is already
204 * buffered. In this case, it means that the client is
205 * not consuming command replies before emitting a new
206 * one. This could be caused by a protocol error or a
207 * misbehaving/malicious client.
208 */
209 bool queued_command_reply;
882093ee 210 struct lttng_payload payload;
f2b3ef9f
JG
211 } outbound;
212 } communication;
213 /* call_rcu delayed reclaim. */
214 struct rcu_head rcu_node;
215};
216
dd877ea6
JG
217enum client_transmission_status {
218 CLIENT_TRANSMISSION_STATUS_COMPLETE,
219 CLIENT_TRANSMISSION_STATUS_QUEUED,
220 /* Communication failure. */
221 CLIENT_TRANSMISSION_STATUS_FAIL,
222 /* Fatal error. */
223 CLIENT_TRANSMISSION_STATUS_ERROR,
224};
f2b3ef9f
JG
225
226LTTNG_HIDDEN
227bool notification_client_list_get(struct notification_client_list *list);
228
229LTTNG_HIDDEN
230void notification_client_list_put(struct notification_client_list *list);
231
6c24d3fd 232/* Only returns a non-zero value if a fatal error occurred. */
f2b3ef9f
JG
233typedef int (*report_client_transmission_result_cb)(
234 struct notification_client *client,
235 enum client_transmission_status status,
236 void *user_data);
237
238LTTNG_HIDDEN
239int notification_client_list_send_evaluation(
240 struct notification_client_list *list,
241 const struct lttng_condition *condition,
242 const struct lttng_evaluation *evaluation,
243 const struct lttng_credentials *trigger_creds,
244 const struct lttng_credentials *source_object_creds,
245 report_client_transmission_result_cb client_report,
246 void *user_data);
247
248LTTNG_HIDDEN
249int notification_thread_client_communication_update(
250 struct notification_thread_handle *handle,
251 notification_client_id id,
252 enum client_transmission_status transmission_status);
253
82b3cbf4
JR
254/*
255 * Takes ownership of the payload if present.
256 */
b9a8d78f
FD
257LTTNG_HIDDEN
258struct lttng_event_notifier_notification *lttng_event_notifier_notification_create(
259 uint64_t tracer_token,
82b3cbf4
JR
260 enum lttng_domain_type domain,
261 char *payload,
262 size_t payload_size);
b9a8d78f
FD
263
264LTTNG_HIDDEN
265void lttng_event_notifier_notification_destroy(
266 struct lttng_event_notifier_notification *event_notifier_notification);
267
8abe313a 268#endif /* NOTIFICATION_THREAD_INTERNAL_H */
This page took 0.046114 seconds and 4 git commands to generate.