2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/error.h>
10 #include <common/macros.h>
11 #include <common/payload.h>
12 #include <common/payload-view.h>
13 #include <common/runas.h>
15 #include <lttng/constant.h>
16 #include <lttng/event-rule/event-rule-internal.h>
17 #include <lttng/event-rule/kprobe-internal.h>
18 #include <lttng/kernel-probe.h>
19 #include <lttng/kernel-probe-internal.h>
22 #define IS_KPROBE_EVENT_RULE(rule) \
23 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KPROBE)
25 #if (LTTNG_SYMBOL_NAME_LEN == 256)
26 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
29 static void lttng_event_rule_kprobe_destroy(struct lttng_event_rule
*rule
)
31 struct lttng_event_rule_kprobe
*kprobe
;
33 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
35 lttng_kernel_probe_location_destroy(kprobe
->location
);
40 static bool lttng_event_rule_kprobe_validate(
41 const struct lttng_event_rule
*rule
)
44 struct lttng_event_rule_kprobe
*kprobe
;
50 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
54 ERR("Invalid name event rule: a name must be set.");
59 if(!kprobe
->location
) {
60 ERR("Invalid name event rule: a location must be set.");
69 static int lttng_event_rule_kprobe_serialize(
70 const struct lttng_event_rule
*rule
,
71 struct lttng_payload
*payload
)
74 size_t name_len
, header_offset
, size_before_location
;
75 struct lttng_event_rule_kprobe
*kprobe
;
76 struct lttng_event_rule_kprobe_comm kprobe_comm
;
77 struct lttng_event_rule_kprobe_comm
*header
;
79 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
)) {
84 header_offset
= payload
->buffer
.size
;
86 DBG("Serializing kprobe event rule.");
87 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
89 name_len
= strlen(kprobe
->name
) + 1;
90 kprobe_comm
.name_len
= name_len
;
92 ret
= lttng_dynamic_buffer_append(
93 &payload
->buffer
, &kprobe_comm
, sizeof(kprobe_comm
));
98 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, kprobe
->name
, name_len
);
103 size_before_location
= payload
->buffer
.size
;
105 ret
= lttng_kernel_probe_location_serialize(kprobe
->location
, payload
);
110 /* Update the header regarding the probe size. */
111 header
= (struct lttng_event_rule_kprobe_comm
*) (
112 (char *) payload
->buffer
.data
+ header_offset
);
113 header
->location_len
= payload
->buffer
.size
- size_before_location
;
121 static bool lttng_event_rule_kprobe_is_equal(const struct lttng_event_rule
*_a
,
122 const struct lttng_event_rule
*_b
)
124 bool is_equal
= false;
125 struct lttng_event_rule_kprobe
*a
, *b
;
127 a
= container_of(_a
, struct lttng_event_rule_kprobe
, parent
);
128 b
= container_of(_b
, struct lttng_event_rule_kprobe
, parent
);
131 if (!!a
->name
!= !!b
->name
) {
138 if (strcmp(a
->name
, b
->name
)) {
142 is_equal
= lttng_kernel_probe_location_is_equal(
143 a
->location
, b
->location
);
148 static enum lttng_error_code
lttng_event_rule_kprobe_generate_filter_bytecode(
149 struct lttng_event_rule
*rule
, uid_t uid
, gid_t gid
)
155 static const char *lttng_event_rule_kprobe_get_filter(
156 const struct lttng_event_rule
*rule
)
162 static const struct lttng_filter_bytecode
*
163 lttng_event_rule_kprobe_get_filter_bytecode(const struct lttng_event_rule
*rule
)
169 static struct lttng_event_exclusion
*
170 lttng_event_rule_kprobe_generate_exclusions(const struct lttng_event_rule
*rule
)
176 struct lttng_event_rule
*lttng_event_rule_kprobe_create()
178 struct lttng_event_rule
*rule
= NULL
;
179 struct lttng_event_rule_kprobe
*krule
;
181 krule
= zmalloc(sizeof(struct lttng_event_rule_kprobe
));
186 rule
= &krule
->parent
;
187 lttng_event_rule_init(&krule
->parent
, LTTNG_EVENT_RULE_TYPE_KPROBE
);
188 krule
->parent
.validate
= lttng_event_rule_kprobe_validate
;
189 krule
->parent
.serialize
= lttng_event_rule_kprobe_serialize
;
190 krule
->parent
.equal
= lttng_event_rule_kprobe_is_equal
;
191 krule
->parent
.destroy
= lttng_event_rule_kprobe_destroy
;
192 krule
->parent
.generate_filter_bytecode
=
193 lttng_event_rule_kprobe_generate_filter_bytecode
;
194 krule
->parent
.get_filter
= lttng_event_rule_kprobe_get_filter
;
195 krule
->parent
.get_filter_bytecode
=
196 lttng_event_rule_kprobe_get_filter_bytecode
;
197 krule
->parent
.generate_exclusions
=
198 lttng_event_rule_kprobe_generate_exclusions
;
204 ssize_t
lttng_event_rule_kprobe_create_from_payload(
205 struct lttng_payload_view
*view
,
206 struct lttng_event_rule
**_event_rule
)
208 ssize_t ret
, offset
= 0;
209 enum lttng_event_rule_status status
;
210 const struct lttng_event_rule_kprobe_comm
*kprobe_comm
;
212 struct lttng_buffer_view current_buffer_view
;
213 struct lttng_event_rule
*rule
= NULL
;
214 struct lttng_event_rule_kprobe
*kprobe
= NULL
;
215 struct lttng_kernel_probe_location
*location
;
222 if (view
->buffer
.size
< sizeof(*kprobe_comm
)) {
223 ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header.");
228 current_buffer_view
= lttng_buffer_view_from_view(
229 &view
->buffer
, offset
, sizeof(*kprobe_comm
));
230 kprobe_comm
= (typeof(kprobe_comm
)) current_buffer_view
.data
;
236 rule
= lttng_event_rule_kprobe_create();
238 ERR("Failed to create event rule kprobe.");
243 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
245 /* Skip to payload */
246 offset
+= current_buffer_view
.size
;
250 struct lttng_payload_view current_payload_view
=
251 lttng_payload_view_from_view(view
, offset
,
252 kprobe_comm
->name_len
);
254 name
= current_payload_view
.buffer
.data
;
260 if (!lttng_buffer_view_contains_string(
261 ¤t_payload_view
.buffer
, name
,
262 kprobe_comm
->name_len
)) {
268 /* Skip after the name. */
269 offset
+= kprobe_comm
->name_len
;
271 /* Map the kernel probe location. */
273 struct lttng_payload_view current_payload_view
=
274 lttng_payload_view_from_view(view
, offset
,
275 kprobe_comm
->location_len
);
277 ret
= lttng_kernel_probe_location_create_from_payload(
278 ¤t_payload_view
, &location
);
285 if (ret
!= kprobe_comm
->location_len
) {
290 kprobe
->location
= location
;
292 /* Skip after the location */
293 offset
+= kprobe_comm
->location_len
;
295 status
= lttng_event_rule_kprobe_set_name(rule
, name
);
296 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
297 ERR("Failed to set event rule kprobe name.");
306 lttng_event_rule_destroy(rule
);
310 enum lttng_event_rule_status
lttng_event_rule_kprobe_set_location(
311 struct lttng_event_rule
*rule
,
312 const struct lttng_kernel_probe_location
*location
)
314 struct lttng_kernel_probe_location
*location_copy
= NULL
;
315 struct lttng_event_rule_kprobe
*kprobe
;
316 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
318 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !location
) {
319 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
323 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
324 location_copy
= lttng_kernel_probe_location_copy(location
);
325 if (!location_copy
) {
326 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
330 if (kprobe
->location
) {
331 lttng_kernel_probe_location_destroy(kprobe
->location
);
334 kprobe
->location
= location_copy
;
335 location_copy
= NULL
;
337 lttng_kernel_probe_location_destroy(location_copy
);
341 enum lttng_event_rule_status
lttng_event_rule_kprobe_get_location(
342 const struct lttng_event_rule
*rule
,
343 const struct lttng_kernel_probe_location
**location
)
345 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
346 struct lttng_event_rule_kprobe
*kprobe
;
348 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !location
) {
349 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
353 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
354 *location
= kprobe
->location
;
357 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
365 enum lttng_event_rule_status
lttng_event_rule_kprobe_set_name(
366 struct lttng_event_rule
*rule
, const char *name
)
368 char *name_copy
= NULL
;
369 struct lttng_event_rule_kprobe
*kprobe
;
370 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
372 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
||
374 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
378 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
379 name_copy
= strdup(name
);
381 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
387 kprobe
->name
= name_copy
;
393 enum lttng_event_rule_status
lttng_event_rule_kprobe_get_name(
394 const struct lttng_event_rule
*rule
, const char **name
)
396 struct lttng_event_rule_kprobe
*kprobe
;
397 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
399 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
) {
400 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
404 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
406 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
410 *name
= kprobe
->name
;