2 * Copyright (C) 2019 - Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <lttng/constant.h>
19 #include <lttng/event-rule/event-rule-internal.h>
20 #include <lttng/event-rule/kprobe-internal.h>
21 #include <common/macros.h>
22 #include <common/error.h>
23 #include <common/runas.h>
28 #define IS_KPROBE_EVENT_RULE(rule) ( \
29 lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KPROBE \
32 #if (LTTNG_SYMBOL_NAME_LEN == 256)
33 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
37 void lttng_event_rule_kprobe_destroy(struct lttng_event_rule
*rule
)
39 struct lttng_event_rule_kprobe
*kprobe
;
41 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
,
45 free(kprobe
->probe
.symbol_name
);
50 bool lttng_event_rule_kprobe_validate(
51 const struct lttng_event_rule
*rule
)
54 struct lttng_event_rule_kprobe
*kprobe
;
60 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
64 ERR("Invalid name event rule: a name must be set.");
67 if (kprobe
->probe
.set
== LTTNG_DOMAIN_NONE
) {
68 ERR("Invalid kprobe event rule: a source must be set.");
78 int lttng_event_rule_kprobe_serialize(
79 const struct lttng_event_rule
*rule
,
80 struct lttng_dynamic_buffer
*buf
,
84 size_t name_len
, probe_symbol_name_len
;
85 struct lttng_event_rule_kprobe
*kprobe
;
86 struct lttng_event_rule_kprobe_comm kprobe_comm
;
88 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
)) {
93 DBG("Serializing kprobe event rule");
94 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
96 name_len
= strlen(kprobe
->name
) + 1;
98 if (kprobe
->probe
.symbol_name
!= NULL
) {
99 probe_symbol_name_len
= strlen(kprobe
->probe
.symbol_name
) + 1;
101 probe_symbol_name_len
= 0;
104 kprobe_comm
.name_len
= name_len
;
105 kprobe_comm
.probe_symbol_name_len
= probe_symbol_name_len
;
106 kprobe_comm
.probe_address
= kprobe
->probe
.address
;
107 kprobe_comm
.probe_offset
= kprobe
->probe
.offset
;
109 ret
= lttng_dynamic_buffer_append(
110 buf
, &kprobe_comm
, sizeof(kprobe_comm
));
114 ret
= lttng_dynamic_buffer_append(buf
, kprobe
->name
, name_len
);
118 ret
= lttng_dynamic_buffer_append(
119 buf
, kprobe
->probe
.symbol_name
, probe_symbol_name_len
);
125 /* Nothing to send */
133 bool lttng_event_rule_kprobe_is_equal(const struct lttng_event_rule
*_a
,
134 const struct lttng_event_rule
*_b
)
136 bool is_equal
= false;
137 struct lttng_event_rule_kprobe
*a
, *b
;
139 a
= container_of(_a
, struct lttng_event_rule_kprobe
, parent
);
140 b
= container_of(_b
, struct lttng_event_rule_kprobe
, parent
);
143 if (!!a
->name
!= !!b
->name
) {
147 if (!!a
->probe
.symbol_name
!= !!b
->probe
.symbol_name
) {
152 /* kprobe is invalid if this is not true */
153 /* TODO: validate that a kprobe MUST have a name */
156 if (strcmp(a
->name
, b
->name
)) {
160 if (a
->probe
.symbol_name
) {
161 /* Both have symbol name due to previous checks */
162 if (strcmp(a
->probe
.symbol_name
, b
->probe
.symbol_name
)) {
167 if (a
->probe
.offset
!= b
->probe
.offset
) {
171 if (a
->probe
.address
!= b
->probe
.address
) {
181 enum lttng_error_code
lttng_event_rule_kprobe_populate(struct lttng_event_rule
*rule
, uid_t uid
, gid_t gid
)
187 static const char *lttng_event_rule_kprobe_get_filter(
188 const struct lttng_event_rule
*rule
)
194 static const struct lttng_filter_bytecode
*
195 lttng_event_rule_kprobe_get_filter_bytecode(const struct lttng_event_rule
*rule
)
202 struct lttng_event_exclusion
*lttng_event_rule_kprobe_generate_exclusions(struct lttng_event_rule
*rule
)
208 struct lttng_event_rule
*lttng_event_rule_kprobe_create()
210 struct lttng_event_rule_kprobe
*rule
;
212 rule
= zmalloc(sizeof(struct lttng_event_rule_kprobe
));
217 lttng_event_rule_init(&rule
->parent
, LTTNG_EVENT_RULE_TYPE_KPROBE
);
218 rule
->parent
.validate
= lttng_event_rule_kprobe_validate
;
219 rule
->parent
.serialize
= lttng_event_rule_kprobe_serialize
;
220 rule
->parent
.equal
= lttng_event_rule_kprobe_is_equal
;
221 rule
->parent
.destroy
= lttng_event_rule_kprobe_destroy
;
222 rule
->parent
.populate
= lttng_event_rule_kprobe_populate
;
223 rule
->parent
.get_filter
= lttng_event_rule_kprobe_get_filter
;
224 rule
->parent
.get_filter_bytecode
= lttng_event_rule_kprobe_get_filter_bytecode
;
225 rule
->parent
.generate_exclusions
= lttng_event_rule_kprobe_generate_exclusions
;
226 return &rule
->parent
;
230 ssize_t
lttng_event_rule_kprobe_create_from_buffer(
231 const struct lttng_buffer_view
*view
,
232 struct lttng_event_rule
**_event_rule
)
234 ssize_t ret
, offset
= 0;
235 enum lttng_event_rule_status status
;
236 const struct lttng_event_rule_kprobe_comm
*kprobe_comm
;
238 const char *probe_symbol_name
= NULL
;
239 struct lttng_buffer_view current_view
;
240 struct lttng_event_rule
*rule
= NULL
;
241 struct lttng_event_rule_kprobe
*kprobe
= NULL
;
248 if (view
->size
< sizeof(*kprobe_comm
)) {
249 ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header");
254 current_view
= lttng_buffer_view_from_view(
255 view
, offset
, sizeof(*kprobe_comm
));
256 kprobe_comm
= (typeof(kprobe_comm
)) current_view
.data
;
262 rule
= lttng_event_rule_kprobe_create();
264 ERR("Failed to create event rule kprobe");
269 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
271 /* Skip to payload */
272 offset
+= current_view
.size
;
274 current_view
= lttng_buffer_view_from_view(
275 view
, offset
, kprobe_comm
->name_len
);
276 name
= current_view
.data
;
282 if (kprobe_comm
->name_len
== 1 ||
283 name
[kprobe_comm
->name_len
- 1] != '\0' ||
284 strlen(name
) != kprobe_comm
->name_len
- 1) {
286 * Check that the name is not NULL, is NULL-terminated, and
287 * does not contain a NULL before the last byte.
293 /* Skip after the name */
294 offset
+= kprobe_comm
->name_len
;
295 if (!kprobe_comm
->probe_symbol_name_len
) {
296 goto skip_probe_symbol_name
;
299 /* Map the probe_symbol_name */
300 current_view
= lttng_buffer_view_from_view(
301 view
, offset
, kprobe_comm
->probe_symbol_name_len
);
302 probe_symbol_name
= current_view
.data
;
303 if (!probe_symbol_name
) {
308 if (kprobe_comm
->probe_symbol_name_len
== 1 ||
309 probe_symbol_name
[kprobe_comm
->probe_symbol_name_len
-
311 strlen(probe_symbol_name
) !=
312 kprobe_comm
->probe_symbol_name_len
-
315 * Check that the filter expression is not NULL, is
316 * NULL-terminated, and does not contain a NULL before the last
323 /* Skip after the pattern */
324 offset
+= kprobe_comm
->probe_symbol_name_len
;
326 skip_probe_symbol_name
:
328 status
= lttng_event_rule_kprobe_set_name(rule
, name
);
329 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
330 ERR("Failed to set event rule kprobe name");
334 kprobe
->probe
.offset
= kprobe_comm
->probe_offset
;
335 kprobe
->probe
.address
= kprobe_comm
->probe_address
;
336 if (probe_symbol_name
) {
337 kprobe
->probe
.symbol_name
= strdup(probe_symbol_name
);
338 if (!kprobe
->probe
.symbol_name
) {
339 ERR("Failed to set event rule kprobe probe symbol name");
349 lttng_event_rule_destroy(rule
);
353 enum lttng_event_rule_status
lttng_event_rule_kprobe_set_source(
354 struct lttng_event_rule
*rule
, const char *source
)
356 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
359 char name
[LTTNG_SYMBOL_NAME_LEN
];
360 struct lttng_event_rule_kprobe
*kprobe
;
362 /* TODO: support multiple call for this, we must free the symbol name if
366 if (!source
|| !IS_KPROBE_EVENT_RULE(rule
) || !rule
) {
367 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
371 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
373 /* Check for symbol+offset */
374 match
= sscanf(source
, "%18s[^'+']+%18s", name
, s_hex
);
376 /* TODO double validate termination handling of this */
377 kprobe
->probe
.symbol_name
=
378 strndup(name
, LTTNG_SYMBOL_NAME_LEN
);
379 if (!kprobe
->probe
.symbol_name
) {
380 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
383 if (*s_hex
== '\0') {
384 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
387 kprobe
->probe
.offset
= strtoul(s_hex
, NULL
, 0);
388 kprobe
->probe
.address
= 0;
389 kprobe
->probe
.set
= true;
393 /* Check for symbol */
394 if (isalpha(name
[0]) || name
[0] == '_') {
395 match
= sscanf(source
,
396 "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
400 /* TODO double validate termination handling of this */
401 kprobe
->probe
.symbol_name
=
402 strndup(name
, LTTNG_SYMBOL_NAME_LEN
);
403 if (!kprobe
->probe
.symbol_name
) {
404 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
407 kprobe
->probe
.offset
= 0;
408 kprobe
->probe
.address
= 0;
409 kprobe
->probe
.set
= true;
414 /* Check for address */
415 match
= sscanf(source
, "%18s", s_hex
);
417 if (*s_hex
== '\0') {
418 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
421 kprobe
->probe
.address
= strtoul(s_hex
, NULL
, 0);
422 kprobe
->probe
.offset
= 0;
423 kprobe
->probe
.symbol_name
= NULL
;
424 kprobe
->probe
.set
= true;
429 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
435 enum lttng_event_rule_status
lttng_event_rule_kprobe_set_name(
436 struct lttng_event_rule
*rule
, const char *name
)
438 char *name_copy
= NULL
;
439 struct lttng_event_rule_kprobe
*kprobe
;
440 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
442 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
||
444 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
448 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
449 name_copy
= strdup(name
);
451 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
459 kprobe
->name
= name_copy
;
465 enum lttng_event_rule_status
lttng_event_rule_kprobe_get_name(
466 const struct lttng_event_rule
*rule
, const char **name
)
468 struct lttng_event_rule_kprobe
*kprobe
;
469 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
471 if (!rule
|| !IS_KPROBE_EVENT_RULE(rule
) || !name
) {
472 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
476 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
478 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
482 *name
= kprobe
->name
;
488 uint64_t lttng_event_rule_kprobe_get_address(
489 const struct lttng_event_rule
*rule
)
491 struct lttng_event_rule_kprobe
*kprobe
;
493 assert(rule
&& IS_KPROBE_EVENT_RULE(rule
));
495 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
497 return kprobe
->probe
.address
;
501 uint64_t lttng_event_rule_kprobe_get_offset(
502 const struct lttng_event_rule
*rule
)
504 struct lttng_event_rule_kprobe
*kprobe
;
506 assert(rule
&& IS_KPROBE_EVENT_RULE(rule
));
508 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
509 return kprobe
->probe
.offset
;
513 const char *lttng_event_rule_kprobe_get_symbol_name(
514 const struct lttng_event_rule
*rule
)
516 struct lttng_event_rule_kprobe
*kprobe
;
518 assert(rule
&& IS_KPROBE_EVENT_RULE(rule
));
520 kprobe
= container_of(rule
, struct lttng_event_rule_kprobe
, parent
);
521 return kprobe
->probe
.symbol_name
;