event-rule: kernel probe: force location on create
[lttng-tools.git] / src / common / event-rule / kernel-probe.c
CommitLineData
077192fd
JR
1/*
2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include <assert.h>
58daac01 9#include <common/credentials.h>
077192fd
JR
10#include <common/error.h>
11#include <common/macros.h>
12#include <common/payload.h>
13#include <common/payload-view.h>
14#include <common/runas.h>
959e3c66
JR
15#include <common/hashtable/hashtable.h>
16#include <common/hashtable/utils.h>
077192fd
JR
17#include <ctype.h>
18#include <lttng/constant.h>
602a6d40 19#include <lttng/event-rule/event-rule.h>
077192fd 20#include <lttng/event-rule/event-rule-internal.h>
a3c51653 21#include <lttng/event-rule/kernel-probe-internal.h>
077192fd
JR
22#include <lttng/kernel-probe.h>
23#include <lttng/kernel-probe-internal.h>
24#include <stdio.h>
25
26#define IS_KPROBE_EVENT_RULE(rule) \
f2791161 27 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE)
077192fd
JR
28
29#if (LTTNG_SYMBOL_NAME_LEN == 256)
30#define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
31#endif
32
f2791161 33static void lttng_event_rule_kernel_probe_destroy(struct lttng_event_rule *rule)
077192fd 34{
f2791161 35 struct lttng_event_rule_kernel_probe *kprobe;
077192fd 36
f2791161 37 kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
38
39 lttng_kernel_probe_location_destroy(kprobe->location);
40 free(kprobe->name);
41 free(kprobe);
42}
43
f2791161 44static bool lttng_event_rule_kernel_probe_validate(
077192fd
JR
45 const struct lttng_event_rule *rule)
46{
47 bool valid = false;
f2791161 48 struct lttng_event_rule_kernel_probe *kprobe;
077192fd
JR
49
50 if (!rule) {
51 goto end;
52 }
53
f2791161 54 kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
55
56 /* Required field. */
57 if (!kprobe->name) {
58 ERR("Invalid name event rule: a name must be set.");
59 goto end;
60 }
61
62 /* Required field. */
63 if(!kprobe->location) {
64 ERR("Invalid name event rule: a location must be set.");
65 goto end;
66 }
67
68 valid = true;
69end:
70 return valid;
71}
72
f2791161 73static int lttng_event_rule_kernel_probe_serialize(
077192fd
JR
74 const struct lttng_event_rule *rule,
75 struct lttng_payload *payload)
76{
77 int ret;
78 size_t name_len, header_offset, size_before_location;
f2791161
JR
79 struct lttng_event_rule_kernel_probe *kprobe;
80 struct lttng_event_rule_kernel_probe_comm kprobe_comm;
81 struct lttng_event_rule_kernel_probe_comm *header;
077192fd
JR
82
83 if (!rule || !IS_KPROBE_EVENT_RULE(rule)) {
84 ret = -1;
85 goto end;
86 }
87
88 header_offset = payload->buffer.size;
89
90 DBG("Serializing kprobe event rule.");
f2791161 91 kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
92
93 name_len = strlen(kprobe->name) + 1;
94 kprobe_comm.name_len = name_len;
95
96 ret = lttng_dynamic_buffer_append(
97 &payload->buffer, &kprobe_comm, sizeof(kprobe_comm));
98 if (ret) {
99 goto end;
100 }
101
102 ret = lttng_dynamic_buffer_append(&payload->buffer, kprobe->name, name_len);
103 if (ret) {
104 goto end;
105 }
106
107 size_before_location = payload->buffer.size;
108
109 ret = lttng_kernel_probe_location_serialize(kprobe->location, payload);
110 if (ret < 0) {
111 goto end;
112 }
113
114 /* Update the header regarding the probe size. */
f2791161 115 header = (struct lttng_event_rule_kernel_probe_comm*) (
077192fd
JR
116 (char *) payload->buffer.data + header_offset);
117 header->location_len = payload->buffer.size - size_before_location;
118
119 ret = 0;
120
121end:
122 return ret;
123}
124
f2791161 125static bool lttng_event_rule_kernel_probe_is_equal(const struct lttng_event_rule *_a,
077192fd
JR
126 const struct lttng_event_rule *_b)
127{
128 bool is_equal = false;
f2791161 129 struct lttng_event_rule_kernel_probe *a, *b;
077192fd 130
f2791161
JR
131 a = container_of(_a, struct lttng_event_rule_kernel_probe, parent);
132 b = container_of(_b, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
133
134 /* Quick checks */
135 if (!!a->name != !!b->name) {
136 goto end;
137 }
138
139 /* Long check */
140 assert(a->name);
141 assert(b->name);
142 if (strcmp(a->name, b->name)) {
143 goto end;
144 }
145
146 is_equal = lttng_kernel_probe_location_is_equal(
147 a->location, b->location);
148end:
149 return is_equal;
150}
151
f2791161 152static enum lttng_error_code lttng_event_rule_kernel_probe_generate_filter_bytecode(
58daac01
JR
153 struct lttng_event_rule *rule,
154 const struct lttng_credentials *creds)
077192fd
JR
155{
156 /* Nothing to do. */
157 return LTTNG_OK;
158}
159
f2791161 160static const char *lttng_event_rule_kernel_probe_get_filter(
077192fd
JR
161 const struct lttng_event_rule *rule)
162{
163 /* Not supported. */
164 return NULL;
165}
166
2b00d462 167static const struct lttng_bytecode *
f2791161 168lttng_event_rule_kernel_probe_get_filter_bytecode(const struct lttng_event_rule *rule)
077192fd
JR
169{
170 /* Not supported. */
171 return NULL;
172}
173
993578ff 174static enum lttng_event_rule_generate_exclusions_status
f2791161 175lttng_event_rule_kernel_probe_generate_exclusions(const struct lttng_event_rule *rule,
993578ff 176 struct lttng_event_exclusion **exclusions)
077192fd
JR
177{
178 /* Not supported. */
993578ff
JR
179 *exclusions = NULL;
180 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
077192fd
JR
181}
182
959e3c66 183static unsigned long
f2791161 184lttng_event_rule_kernel_probe_hash(
959e3c66
JR
185 const struct lttng_event_rule *rule)
186{
187 unsigned long hash;
f2791161 188 struct lttng_event_rule_kernel_probe *krule =
959e3c66
JR
189 container_of(rule, typeof(*krule), parent);
190
f2791161 191 hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE,
959e3c66
JR
192 lttng_ht_seed);
193 hash ^= hash_key_str(krule->name, lttng_ht_seed);
194 hash ^= lttng_kernel_probe_location_hash(krule->location);
195
196 return hash;
197}
198
602a6d40
JR
199static
200int kernel_probe_set_location(
201 struct lttng_event_rule_kernel_probe *kprobe,
202 const struct lttng_kernel_probe_location *location)
203{
204 int ret;
205 struct lttng_kernel_probe_location *location_copy = NULL;
206
207 if (!kprobe || !location || kprobe->location) {
208 ret = -1;
209 goto end;
210 }
211
212 location_copy = lttng_kernel_probe_location_copy(location);
213 if (!location_copy) {
214 ret = -1;
215 goto end;
216 }
217
218 kprobe->location = location_copy;
219 location_copy = NULL;
220 ret = 0;
221end:
222 lttng_kernel_probe_location_destroy(location_copy);
223 return ret;
224}
225
226struct lttng_event_rule *lttng_event_rule_kernel_probe_create(
227 const struct lttng_kernel_probe_location *location)
077192fd
JR
228{
229 struct lttng_event_rule *rule = NULL;
f2791161 230 struct lttng_event_rule_kernel_probe *krule;
077192fd 231
f2791161 232 krule = zmalloc(sizeof(struct lttng_event_rule_kernel_probe));
077192fd
JR
233 if (!krule) {
234 goto end;
235 }
236
237 rule = &krule->parent;
f2791161
JR
238 lttng_event_rule_init(&krule->parent, LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE);
239 krule->parent.validate = lttng_event_rule_kernel_probe_validate;
240 krule->parent.serialize = lttng_event_rule_kernel_probe_serialize;
241 krule->parent.equal = lttng_event_rule_kernel_probe_is_equal;
242 krule->parent.destroy = lttng_event_rule_kernel_probe_destroy;
077192fd 243 krule->parent.generate_filter_bytecode =
f2791161
JR
244 lttng_event_rule_kernel_probe_generate_filter_bytecode;
245 krule->parent.get_filter = lttng_event_rule_kernel_probe_get_filter;
077192fd 246 krule->parent.get_filter_bytecode =
f2791161 247 lttng_event_rule_kernel_probe_get_filter_bytecode;
077192fd 248 krule->parent.generate_exclusions =
f2791161
JR
249 lttng_event_rule_kernel_probe_generate_exclusions;
250 krule->parent.hash = lttng_event_rule_kernel_probe_hash;
602a6d40
JR
251
252 if (kernel_probe_set_location(krule, location)) {
253 lttng_event_rule_destroy(rule);
254 rule = NULL;
255 }
256
077192fd
JR
257end:
258 return rule;
259}
260
261LTTNG_HIDDEN
f2791161 262ssize_t lttng_event_rule_kernel_probe_create_from_payload(
077192fd
JR
263 struct lttng_payload_view *view,
264 struct lttng_event_rule **_event_rule)
265{
266 ssize_t ret, offset = 0;
267 enum lttng_event_rule_status status;
f2791161 268 const struct lttng_event_rule_kernel_probe_comm *kprobe_comm;
077192fd
JR
269 const char *name;
270 struct lttng_buffer_view current_buffer_view;
271 struct lttng_event_rule *rule = NULL;
602a6d40 272 struct lttng_kernel_probe_location *location = NULL;
077192fd
JR
273
274 if (!_event_rule) {
275 ret = -1;
276 goto end;
277 }
278
3e6e0df2
JG
279 current_buffer_view = lttng_buffer_view_from_view(
280 &view->buffer, offset, sizeof(*kprobe_comm));
281 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
077192fd
JR
282 ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header.");
283 ret = -1;
284 goto end;
285 }
286
077192fd 287 kprobe_comm = (typeof(kprobe_comm)) current_buffer_view.data;
077192fd 288
077192fd
JR
289 /* Skip to payload */
290 offset += current_buffer_view.size;
291
292 {
293 /* Map the name. */
294 struct lttng_payload_view current_payload_view =
295 lttng_payload_view_from_view(view, offset,
296 kprobe_comm->name_len);
297
3e6e0df2 298 if (!lttng_payload_view_is_valid(&current_payload_view)) {
077192fd
JR
299 ret = -1;
300 goto end;
301 }
302
3e6e0df2 303 name = current_payload_view.buffer.data;
077192fd
JR
304 if (!lttng_buffer_view_contains_string(
305 &current_payload_view.buffer, name,
306 kprobe_comm->name_len)) {
307 ret = -1;
308 goto end;
309 }
310 }
311
312 /* Skip after the name. */
313 offset += kprobe_comm->name_len;
314
315 /* Map the kernel probe location. */
316 {
317 struct lttng_payload_view current_payload_view =
318 lttng_payload_view_from_view(view, offset,
319 kprobe_comm->location_len);
320
3e6e0df2
JG
321 if (!lttng_payload_view_is_valid(&current_payload_view)) {
322 ret = -1;
323 goto end;
324 }
325
077192fd
JR
326 ret = lttng_kernel_probe_location_create_from_payload(
327 &current_payload_view, &location);
328 if (ret < 0) {
329 ret = -1;
330 goto end;
331 }
332 }
333
334 if (ret != kprobe_comm->location_len) {
335 ret = -1;
336 goto end;
337 }
338
077192fd
JR
339 /* Skip after the location */
340 offset += kprobe_comm->location_len;
341
602a6d40
JR
342 rule = lttng_event_rule_kernel_probe_create(location);
343 if (!rule) {
344 ERR("Failed to create event rule kprobe.");
345 ret = -1;
346 goto end;
347 }
348
d891bb52 349 status = lttng_event_rule_kernel_probe_set_event_name(rule, name);
077192fd
JR
350 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
351 ERR("Failed to set event rule kprobe name.");
352 ret = -1;
353 goto end;
354 }
355
356 *_event_rule = rule;
357 rule = NULL;
358 ret = offset;
359end:
602a6d40 360 lttng_kernel_probe_location_destroy(location);
077192fd
JR
361 lttng_event_rule_destroy(rule);
362 return ret;
363}
364
f2791161 365enum lttng_event_rule_status lttng_event_rule_kernel_probe_get_location(
077192fd
JR
366 const struct lttng_event_rule *rule,
367 const struct lttng_kernel_probe_location **location)
368{
369 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
f2791161 370 struct lttng_event_rule_kernel_probe *kprobe;
077192fd
JR
371
372 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !location) {
373 status = LTTNG_EVENT_RULE_STATUS_INVALID;
374 goto end;
375 }
376
f2791161 377 kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
378 *location = kprobe->location;
379
380 if (!*location) {
381 status = LTTNG_EVENT_RULE_STATUS_UNSET;
382 goto end;
383 }
384
385end:
386 return status;
387}
388
d891bb52 389enum lttng_event_rule_status lttng_event_rule_kernel_probe_set_event_name(
077192fd
JR
390 struct lttng_event_rule *rule, const char *name)
391{
392 char *name_copy = NULL;
f2791161 393 struct lttng_event_rule_kernel_probe *kprobe;
077192fd
JR
394 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
395
396 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !name ||
397 strlen(name) == 0) {
398 status = LTTNG_EVENT_RULE_STATUS_INVALID;
399 goto end;
400 }
401
f2791161 402 kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
403 name_copy = strdup(name);
404 if (!name_copy) {
405 status = LTTNG_EVENT_RULE_STATUS_ERROR;
406 goto end;
407 }
408
409 free(kprobe->name);
410
411 kprobe->name = name_copy;
412 name_copy = NULL;
413end:
414 return status;
415}
416
d891bb52 417enum lttng_event_rule_status lttng_event_rule_kernel_probe_get_event_name(
077192fd
JR
418 const struct lttng_event_rule *rule, const char **name)
419{
f2791161 420 struct lttng_event_rule_kernel_probe *kprobe;
077192fd
JR
421 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
422
423 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !name) {
424 status = LTTNG_EVENT_RULE_STATUS_INVALID;
425 goto end;
426 }
427
f2791161 428 kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent);
077192fd
JR
429 if (!kprobe->name) {
430 status = LTTNG_EVENT_RULE_STATUS_UNSET;
431 goto end;
432 }
433
434 *name = kprobe->name;
435end:
436 return status;
437}
This page took 0.046083 seconds and 5 git commands to generate.