2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/credentials.hpp>
9 #include <common/error.hpp>
10 #include <common/hashtable/hashtable.hpp>
11 #include <common/hashtable/utils.hpp>
12 #include <common/macros.hpp>
13 #include <common/mi-lttng.hpp>
14 #include <common/payload-view.hpp>
15 #include <common/payload.hpp>
16 #include <common/runas.hpp>
18 #include <lttng/constant.h>
19 #include <lttng/event-rule/event-rule-internal.hpp>
20 #include <lttng/event-rule/event-rule.h>
21 #include <lttng/event-rule/kernel-kprobe-internal.hpp>
22 #include <lttng/kernel-probe-internal.hpp>
23 #include <lttng/kernel-probe.h>
28 #define IS_KPROBE_EVENT_RULE(rule) \
29 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE)
31 #if (LTTNG_SYMBOL_NAME_LEN == 256)
32 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
35 static void lttng_event_rule_kernel_kprobe_destroy(struct lttng_event_rule
*rule
)
37 struct lttng_event_rule_kernel_kprobe
*kprobe
;
39 kprobe
= lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
41 lttng_kernel_probe_location_destroy(kprobe
->location
);
46 static bool lttng_event_rule_kernel_kprobe_validate(const struct lttng_event_rule
*rule
)
49 struct lttng_event_rule_kernel_kprobe
*kprobe
;
55 kprobe
= lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
59 ERR("Invalid name event rule: a name must be set.");
64 if (!kprobe
->location
) {
65 ERR("Invalid name event rule: a location must be set.");
74 static int lttng_event_rule_kernel_kprobe_serialize(const struct lttng_event_rule
*rule
,
75 struct lttng_payload
*payload
)
78 size_t name_len
, header_offset
, size_before_location
;
79 struct lttng_event_rule_kernel_kprobe
*kprobe
;
80 struct lttng_event_rule_kernel_kprobe_comm kprobe_comm
;
81 struct lttng_event_rule_kernel_kprobe_comm
*header
;
83 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
)) {
88 header_offset
= payload
->buffer
.size
;
90 DBG("Serializing kprobe event rule.");
91 kprobe
= lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
93 name_len
= strlen(kprobe
->name
) + 1;
94 kprobe_comm
.name_len
= name_len
;
96 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &kprobe_comm
, sizeof(kprobe_comm
));
101 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, kprobe
->name
, name_len
);
106 size_before_location
= payload
->buffer
.size
;
108 ret
= lttng_kernel_probe_location_serialize(kprobe
->location
, payload
);
113 /* Update the header regarding the probe size. */
114 header
= (struct lttng_event_rule_kernel_kprobe_comm
*) ((char *) payload
->buffer
.data
+
116 header
->location_len
= payload
->buffer
.size
- size_before_location
;
124 static bool lttng_event_rule_kernel_kprobe_is_equal(const struct lttng_event_rule
*_a
,
125 const struct lttng_event_rule
*_b
)
127 bool is_equal
= false;
128 struct lttng_event_rule_kernel_kprobe
*a
, *b
;
130 a
= lttng::utils::container_of(_a
, <tng_event_rule_kernel_kprobe::parent
);
131 b
= lttng::utils::container_of(_b
, <tng_event_rule_kernel_kprobe::parent
);
134 if (!!a
->name
!= !!b
->name
) {
139 LTTNG_ASSERT(a
->name
);
140 LTTNG_ASSERT(b
->name
);
141 if (strcmp(a
->name
, b
->name
) != 0) {
145 is_equal
= lttng_kernel_probe_location_is_equal(a
->location
, b
->location
);
150 static enum lttng_error_code
lttng_event_rule_kernel_kprobe_generate_filter_bytecode(
151 struct lttng_event_rule
*rule
__attribute__((unused
)),
152 const struct lttng_credentials
*creds
__attribute__((unused
)))
158 static const char *lttng_event_rule_kernel_kprobe_get_filter(const struct lttng_event_rule
*rule
159 __attribute__((unused
)))
165 static const struct lttng_bytecode
*
166 lttng_event_rule_kernel_kprobe_get_filter_bytecode(const struct lttng_event_rule
*rule
167 __attribute__((unused
)))
173 static enum lttng_event_rule_generate_exclusions_status
174 lttng_event_rule_kernel_kprobe_generate_exclusions(const struct lttng_event_rule
*rule
175 __attribute__((unused
)),
176 struct lttng_event_exclusion
**exclusions
)
179 *exclusions
= nullptr;
180 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE
;
183 static unsigned long lttng_event_rule_kernel_kprobe_hash(const struct lttng_event_rule
*rule
)
186 struct lttng_event_rule_kernel_kprobe
*krule
=
187 lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
189 hash
= hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
, lttng_ht_seed
);
190 hash
^= hash_key_str(krule
->name
, lttng_ht_seed
);
191 hash
^= lttng_kernel_probe_location_hash(krule
->location
);
196 static int kernel_probe_set_location(struct lttng_event_rule_kernel_kprobe
*kprobe
,
197 const struct lttng_kernel_probe_location
*location
)
200 struct lttng_kernel_probe_location
*location_copy
= nullptr;
202 if (!kprobe
|| !location
|| kprobe
->location
) {
207 location_copy
= lttng_kernel_probe_location_copy(location
);
208 if (!location_copy
) {
213 kprobe
->location
= location_copy
;
214 location_copy
= nullptr;
217 lttng_kernel_probe_location_destroy(location_copy
);
221 static enum lttng_error_code
222 lttng_event_rule_kernel_kprobe_mi_serialize(const struct lttng_event_rule
*rule
,
223 struct mi_writer
*writer
)
226 enum lttng_error_code ret_code
;
227 enum lttng_event_rule_status status
;
228 const char *event_name
= nullptr;
229 const struct lttng_kernel_probe_location
*location
= nullptr;
232 LTTNG_ASSERT(writer
);
233 LTTNG_ASSERT(IS_KPROBE_EVENT_RULE(rule
));
235 status
= lttng_event_rule_kernel_kprobe_get_event_name(rule
, &event_name
);
236 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
);
237 LTTNG_ASSERT(event_name
);
239 status
= lttng_event_rule_kernel_kprobe_get_location(rule
, &location
);
240 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
);
241 LTTNG_ASSERT(location
);
243 /* Open event rule kernel kprobe element. */
244 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_event_rule_kernel_kprobe
);
250 ret
= mi_lttng_writer_write_element_string(
251 writer
, mi_lttng_element_event_rule_event_name
, event_name
);
256 /* Probe location. */
257 ret_code
= lttng_kernel_probe_location_mi_serialize(location
, writer
);
258 if (ret_code
!= LTTNG_OK
) {
262 /* Close event rule kernel kprobe element. */
263 ret
= mi_lttng_writer_close_element(writer
);
272 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
277 struct lttng_event_rule
*
278 lttng_event_rule_kernel_kprobe_create(const struct lttng_kernel_probe_location
*location
)
280 struct lttng_event_rule
*rule
= nullptr;
281 struct lttng_event_rule_kernel_kprobe
*krule
;
283 krule
= zmalloc
<lttng_event_rule_kernel_kprobe
>();
288 rule
= &krule
->parent
;
289 lttng_event_rule_init(&krule
->parent
, LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
);
290 krule
->parent
.validate
= lttng_event_rule_kernel_kprobe_validate
;
291 krule
->parent
.serialize
= lttng_event_rule_kernel_kprobe_serialize
;
292 krule
->parent
.equal
= lttng_event_rule_kernel_kprobe_is_equal
;
293 krule
->parent
.destroy
= lttng_event_rule_kernel_kprobe_destroy
;
294 krule
->parent
.generate_filter_bytecode
=
295 lttng_event_rule_kernel_kprobe_generate_filter_bytecode
;
296 krule
->parent
.get_filter
= lttng_event_rule_kernel_kprobe_get_filter
;
297 krule
->parent
.get_filter_bytecode
= lttng_event_rule_kernel_kprobe_get_filter_bytecode
;
298 krule
->parent
.generate_exclusions
= lttng_event_rule_kernel_kprobe_generate_exclusions
;
299 krule
->parent
.hash
= lttng_event_rule_kernel_kprobe_hash
;
300 krule
->parent
.mi_serialize
= lttng_event_rule_kernel_kprobe_mi_serialize
;
302 if (kernel_probe_set_location(krule
, location
)) {
303 lttng_event_rule_destroy(rule
);
311 ssize_t
lttng_event_rule_kernel_kprobe_create_from_payload(struct lttng_payload_view
*view
,
312 struct lttng_event_rule
**_event_rule
)
314 ssize_t ret
, offset
= 0;
315 enum lttng_event_rule_status status
;
316 const struct lttng_event_rule_kernel_kprobe_comm
*kprobe_comm
;
318 struct lttng_buffer_view current_buffer_view
;
319 struct lttng_event_rule
*rule
= nullptr;
320 struct lttng_kernel_probe_location
*location
= nullptr;
327 current_buffer_view
=
328 lttng_buffer_view_from_view(&view
->buffer
, offset
, sizeof(*kprobe_comm
));
329 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
330 ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header.");
335 kprobe_comm
= (typeof(kprobe_comm
)) current_buffer_view
.data
;
337 /* Skip to payload */
338 offset
+= current_buffer_view
.size
;
342 struct lttng_payload_view current_payload_view
=
343 lttng_payload_view_from_view(view
, offset
, kprobe_comm
->name_len
);
345 if (!lttng_payload_view_is_valid(¤t_payload_view
)) {
350 name
= current_payload_view
.buffer
.data
;
351 if (!lttng_buffer_view_contains_string(
352 ¤t_payload_view
.buffer
, name
, kprobe_comm
->name_len
)) {
358 /* Skip after the name. */
359 offset
+= kprobe_comm
->name_len
;
361 /* Map the kernel probe location. */
363 struct lttng_payload_view current_payload_view
=
364 lttng_payload_view_from_view(view
, offset
, kprobe_comm
->location_len
);
366 if (!lttng_payload_view_is_valid(¤t_payload_view
)) {
371 ret
= lttng_kernel_probe_location_create_from_payload(¤t_payload_view
,
379 if (ret
!= kprobe_comm
->location_len
) {
384 /* Skip after the location */
385 offset
+= kprobe_comm
->location_len
;
387 rule
= lttng_event_rule_kernel_kprobe_create(location
);
389 ERR("Failed to create event rule kprobe.");
394 status
= lttng_event_rule_kernel_kprobe_set_event_name(rule
, name
);
395 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
396 ERR("Failed to set event rule kprobe name.");
405 lttng_kernel_probe_location_destroy(location
);
406 lttng_event_rule_destroy(rule
);
410 enum lttng_event_rule_status
411 lttng_event_rule_kernel_kprobe_get_location(const struct lttng_event_rule
*rule
,
412 const struct lttng_kernel_probe_location
**location
)
414 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
415 struct lttng_event_rule_kernel_kprobe
*kprobe
;
417 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !location
) {
418 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
422 kprobe
= lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
423 *location
= kprobe
->location
;
426 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
434 enum lttng_event_rule_status
435 lttng_event_rule_kernel_kprobe_set_event_name(struct lttng_event_rule
*rule
, const char *name
)
437 char *name_copy
= nullptr;
438 struct lttng_event_rule_kernel_kprobe
*kprobe
;
439 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
441 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
|| strlen(name
) == 0) {
442 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
446 kprobe
= lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
447 name_copy
= strdup(name
);
449 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
455 kprobe
->name
= name_copy
;
461 enum lttng_event_rule_status
462 lttng_event_rule_kernel_kprobe_get_event_name(const struct lttng_event_rule
*rule
,
465 struct lttng_event_rule_kernel_kprobe
*kprobe
;
466 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
468 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
) {
469 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
473 kprobe
= lttng::utils::container_of(rule
, <tng_event_rule_kernel_kprobe::parent
);
475 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
479 *name
= kprobe
->name
;