2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/credentials.h>
10 #include <common/error.h>
11 #include <common/hashtable/hashtable.h>
12 #include <common/hashtable/utils.h>
13 #include <common/macros.h>
14 #include <common/mi-lttng.h>
15 #include <common/payload-view.h>
16 #include <common/payload.h>
17 #include <common/runas.h>
19 #include <lttng/constant.h>
20 #include <lttng/event-rule/event-rule-internal.h>
21 #include <lttng/event-rule/event-rule.h>
22 #include <lttng/event-rule/kernel-kprobe-internal.h>
23 #include <lttng/kernel-probe-internal.h>
24 #include <lttng/kernel-probe.h>
27 #define IS_KPROBE_EVENT_RULE(rule) \
28 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE)
30 #if (LTTNG_SYMBOL_NAME_LEN == 256)
31 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
34 static void lttng_event_rule_kernel_kprobe_destroy(struct lttng_event_rule
*rule
)
36 struct lttng_event_rule_kernel_kprobe
*kprobe
;
38 kprobe
= container_of(rule
, struct lttng_event_rule_kernel_kprobe
, parent
);
40 lttng_kernel_probe_location_destroy(kprobe
->location
);
45 static bool lttng_event_rule_kernel_kprobe_validate(
46 const struct lttng_event_rule
*rule
)
49 struct lttng_event_rule_kernel_kprobe
*kprobe
;
55 kprobe
= container_of(rule
, struct lttng_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(
75 const struct lttng_event_rule
*rule
,
76 struct lttng_payload
*payload
)
79 size_t name_len
, header_offset
, size_before_location
;
80 struct lttng_event_rule_kernel_kprobe
*kprobe
;
81 struct lttng_event_rule_kernel_kprobe_comm kprobe_comm
;
82 struct lttng_event_rule_kernel_kprobe_comm
*header
;
84 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
)) {
89 header_offset
= payload
->buffer
.size
;
91 DBG("Serializing kprobe event rule.");
92 kprobe
= container_of(rule
, struct lttng_event_rule_kernel_kprobe
, parent
);
94 name_len
= strlen(kprobe
->name
) + 1;
95 kprobe_comm
.name_len
= name_len
;
97 ret
= lttng_dynamic_buffer_append(
98 &payload
->buffer
, &kprobe_comm
, sizeof(kprobe_comm
));
103 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, kprobe
->name
, name_len
);
108 size_before_location
= payload
->buffer
.size
;
110 ret
= lttng_kernel_probe_location_serialize(kprobe
->location
, payload
);
115 /* Update the header regarding the probe size. */
116 header
= (struct lttng_event_rule_kernel_kprobe_comm
*) (
117 (char *) payload
->buffer
.data
+ header_offset
);
118 header
->location_len
= payload
->buffer
.size
- size_before_location
;
126 static bool lttng_event_rule_kernel_kprobe_is_equal(const struct lttng_event_rule
*_a
,
127 const struct lttng_event_rule
*_b
)
129 bool is_equal
= false;
130 struct lttng_event_rule_kernel_kprobe
*a
, *b
;
132 a
= container_of(_a
, struct lttng_event_rule_kernel_kprobe
, parent
);
133 b
= container_of(_b
, struct lttng_event_rule_kernel_kprobe
, parent
);
136 if (!!a
->name
!= !!b
->name
) {
143 if (strcmp(a
->name
, b
->name
)) {
147 is_equal
= lttng_kernel_probe_location_is_equal(
148 a
->location
, b
->location
);
153 static enum lttng_error_code
lttng_event_rule_kernel_kprobe_generate_filter_bytecode(
154 struct lttng_event_rule
*rule
,
155 const struct lttng_credentials
*creds
)
161 static const char *lttng_event_rule_kernel_kprobe_get_filter(
162 const struct lttng_event_rule
*rule
)
168 static const struct lttng_bytecode
*
169 lttng_event_rule_kernel_kprobe_get_filter_bytecode(const struct lttng_event_rule
*rule
)
175 static enum lttng_event_rule_generate_exclusions_status
176 lttng_event_rule_kernel_kprobe_generate_exclusions(const struct lttng_event_rule
*rule
,
177 struct lttng_event_exclusion
**exclusions
)
181 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE
;
185 lttng_event_rule_kernel_kprobe_hash(
186 const struct lttng_event_rule
*rule
)
189 struct lttng_event_rule_kernel_kprobe
*krule
=
190 container_of(rule
, typeof(*krule
), parent
);
192 hash
= hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
,
194 hash
^= hash_key_str(krule
->name
, lttng_ht_seed
);
195 hash
^= lttng_kernel_probe_location_hash(krule
->location
);
201 int kernel_probe_set_location(
202 struct lttng_event_rule_kernel_kprobe
*kprobe
,
203 const struct lttng_kernel_probe_location
*location
)
206 struct lttng_kernel_probe_location
*location_copy
= NULL
;
208 if (!kprobe
|| !location
|| kprobe
->location
) {
213 location_copy
= lttng_kernel_probe_location_copy(location
);
214 if (!location_copy
) {
219 kprobe
->location
= location_copy
;
220 location_copy
= NULL
;
223 lttng_kernel_probe_location_destroy(location_copy
);
228 enum lttng_error_code
lttng_event_rule_kernel_kprobe_mi_serialize(
229 const struct lttng_event_rule
*rule
, struct mi_writer
*writer
)
232 enum lttng_error_code ret_code
;
233 enum lttng_event_rule_status status
;
234 const char *event_name
= NULL
;
235 const struct lttng_kernel_probe_location
*location
= NULL
;
239 assert(IS_KPROBE_EVENT_RULE(rule
));
241 status
= lttng_event_rule_kernel_kprobe_get_event_name(
243 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
);
246 status
= lttng_event_rule_kernel_kprobe_get_location(rule
, &location
);
247 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
);
250 /* Open event rule kernel kprobe element. */
251 ret
= mi_lttng_writer_open_element(
252 writer
, mi_lttng_element_event_rule_kernel_kprobe
);
258 ret
= mi_lttng_writer_write_element_string(writer
,
259 mi_lttng_element_event_rule_event_name
, event_name
);
264 /* Probe location. */
265 ret_code
= lttng_kernel_probe_location_mi_serialize(location
, writer
);
266 if (ret_code
!= LTTNG_OK
) {
270 /* Close event rule kernel kprobe element. */
271 ret
= mi_lttng_writer_close_element(writer
);
280 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
285 struct lttng_event_rule
*lttng_event_rule_kernel_kprobe_create(
286 const struct lttng_kernel_probe_location
*location
)
288 struct lttng_event_rule
*rule
= NULL
;
289 struct lttng_event_rule_kernel_kprobe
*krule
;
291 krule
= zmalloc(sizeof(struct lttng_event_rule_kernel_kprobe
));
296 rule
= &krule
->parent
;
297 lttng_event_rule_init(&krule
->parent
, LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
);
298 krule
->parent
.validate
= lttng_event_rule_kernel_kprobe_validate
;
299 krule
->parent
.serialize
= lttng_event_rule_kernel_kprobe_serialize
;
300 krule
->parent
.equal
= lttng_event_rule_kernel_kprobe_is_equal
;
301 krule
->parent
.destroy
= lttng_event_rule_kernel_kprobe_destroy
;
302 krule
->parent
.generate_filter_bytecode
=
303 lttng_event_rule_kernel_kprobe_generate_filter_bytecode
;
304 krule
->parent
.get_filter
= lttng_event_rule_kernel_kprobe_get_filter
;
305 krule
->parent
.get_filter_bytecode
=
306 lttng_event_rule_kernel_kprobe_get_filter_bytecode
;
307 krule
->parent
.generate_exclusions
=
308 lttng_event_rule_kernel_kprobe_generate_exclusions
;
309 krule
->parent
.hash
= lttng_event_rule_kernel_kprobe_hash
;
310 krule
->parent
.mi_serialize
= lttng_event_rule_kernel_kprobe_mi_serialize
;
312 if (kernel_probe_set_location(krule
, location
)) {
313 lttng_event_rule_destroy(rule
);
322 ssize_t
lttng_event_rule_kernel_kprobe_create_from_payload(
323 struct lttng_payload_view
*view
,
324 struct lttng_event_rule
**_event_rule
)
326 ssize_t ret
, offset
= 0;
327 enum lttng_event_rule_status status
;
328 const struct lttng_event_rule_kernel_kprobe_comm
*kprobe_comm
;
330 struct lttng_buffer_view current_buffer_view
;
331 struct lttng_event_rule
*rule
= NULL
;
332 struct lttng_kernel_probe_location
*location
= NULL
;
339 current_buffer_view
= lttng_buffer_view_from_view(
340 &view
->buffer
, offset
, sizeof(*kprobe_comm
));
341 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
342 ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header.");
347 kprobe_comm
= (typeof(kprobe_comm
)) current_buffer_view
.data
;
349 /* Skip to payload */
350 offset
+= current_buffer_view
.size
;
354 struct lttng_payload_view current_payload_view
=
355 lttng_payload_view_from_view(view
, offset
,
356 kprobe_comm
->name_len
);
358 if (!lttng_payload_view_is_valid(¤t_payload_view
)) {
363 name
= current_payload_view
.buffer
.data
;
364 if (!lttng_buffer_view_contains_string(
365 ¤t_payload_view
.buffer
, name
,
366 kprobe_comm
->name_len
)) {
372 /* Skip after the name. */
373 offset
+= kprobe_comm
->name_len
;
375 /* Map the kernel probe location. */
377 struct lttng_payload_view current_payload_view
=
378 lttng_payload_view_from_view(view
, offset
,
379 kprobe_comm
->location_len
);
381 if (!lttng_payload_view_is_valid(¤t_payload_view
)) {
386 ret
= lttng_kernel_probe_location_create_from_payload(
387 ¤t_payload_view
, &location
);
394 if (ret
!= kprobe_comm
->location_len
) {
399 /* Skip after the location */
400 offset
+= kprobe_comm
->location_len
;
402 rule
= lttng_event_rule_kernel_kprobe_create(location
);
404 ERR("Failed to create event rule kprobe.");
409 status
= lttng_event_rule_kernel_kprobe_set_event_name(rule
, name
);
410 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
411 ERR("Failed to set event rule kprobe name.");
420 lttng_kernel_probe_location_destroy(location
);
421 lttng_event_rule_destroy(rule
);
425 enum lttng_event_rule_status
lttng_event_rule_kernel_kprobe_get_location(
426 const struct lttng_event_rule
*rule
,
427 const struct lttng_kernel_probe_location
**location
)
429 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
430 struct lttng_event_rule_kernel_kprobe
*kprobe
;
432 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !location
) {
433 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
437 kprobe
= container_of(rule
, struct lttng_event_rule_kernel_kprobe
, parent
);
438 *location
= kprobe
->location
;
441 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
449 enum lttng_event_rule_status
lttng_event_rule_kernel_kprobe_set_event_name(
450 struct lttng_event_rule
*rule
, const char *name
)
452 char *name_copy
= NULL
;
453 struct lttng_event_rule_kernel_kprobe
*kprobe
;
454 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
456 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
||
458 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
462 kprobe
= container_of(rule
, struct lttng_event_rule_kernel_kprobe
, parent
);
463 name_copy
= strdup(name
);
465 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
471 kprobe
->name
= name_copy
;
477 enum lttng_event_rule_status
lttng_event_rule_kernel_kprobe_get_event_name(
478 const struct lttng_event_rule
*rule
, const char **name
)
480 struct lttng_event_rule_kernel_kprobe
*kprobe
;
481 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
483 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
) {
484 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
488 kprobe
= container_of(rule
, struct lttng_event_rule_kernel_kprobe
, parent
);
490 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
494 *name
= kprobe
->name
;