Refactoring: rename lttng_event_enabler to lttng_event_recorder_enabler
[lttng-modules.git] / src / lttng-syscalls.c
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-syscalls.c
4 *
5 * LTTng syscall probes.
6 *
7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 */
9
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/compat.h>
13 #include <linux/err.h>
14 #include <linux/bitmap.h>
15 #include <linux/in.h>
16 #include <linux/in6.h>
17 #include <linux/seq_file.h>
18 #include <linux/stringify.h>
19 #include <linux/file.h>
20 #include <linux/anon_inodes.h>
21 #include <linux/fcntl.h>
22 #include <linux/mman.h>
23 #include <asm/ptrace.h>
24 #include <asm/syscall.h>
25
26 #include <lttng/bitfield.h>
27 #include <wrapper/tracepoint.h>
28 #include <wrapper/file.h>
29 #include <wrapper/rcu.h>
30 #include <wrapper/syscall.h>
31 #include <lttng/events.h>
32 #include <lttng/events-internal.h>
33 #include <lttng/utils.h>
34
35 #include "lttng-syscalls.h"
36
37 #ifndef CONFIG_COMPAT
38 # ifndef is_compat_task
39 # define is_compat_task() (0)
40 # endif
41 #endif
42
43 /* in_compat_syscall appears in kernel 4.6. */
44 #ifndef in_compat_syscall
45 #define in_compat_syscall() is_compat_task()
46 #endif
47
48 enum sc_type {
49 SC_TYPE_ENTRY,
50 SC_TYPE_EXIT,
51 SC_TYPE_COMPAT_ENTRY,
52 SC_TYPE_COMPAT_EXIT,
53 };
54
55 #define SYSCALL_ENTRY_TOK syscall_entry_
56 #define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
57 #define SYSCALL_EXIT_TOK syscall_exit_
58 #define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
59
60 #define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
61 #define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
62 #define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
63 #define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
64
65 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
66 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
67
68 /*
69 * Forward declarations for old kernels.
70 */
71 struct mmsghdr;
72 struct rlimit64;
73 struct oldold_utsname;
74 struct old_utsname;
75 struct sel_arg_struct;
76 struct mmap_arg_struct;
77 struct file_handle;
78 struct user_msghdr;
79
80 /*
81 * Forward declaration for kernels >= 5.6
82 */
83 struct timex;
84 struct timeval;
85 struct itimerval;
86 struct itimerspec;
87
88 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
89 typedef __kernel_old_time_t time_t;
90 #endif
91
92 #ifdef IA32_NR_syscalls
93 #define NR_compat_syscalls IA32_NR_syscalls
94 #else
95 #define NR_compat_syscalls NR_syscalls
96 #endif
97
98 /*
99 * Create LTTng tracepoint probes.
100 */
101 #define LTTNG_PACKAGE_BUILD
102 #define CREATE_TRACE_POINTS
103 #define TP_MODULE_NOINIT
104 #define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
105
106 #define PARAMS(args...) args
107
108 /* Handle unknown syscalls */
109 #undef TRACE_SYSTEM
110 #define TRACE_SYSTEM syscalls_unknown
111 #include <instrumentation/syscalls/headers/syscalls_unknown.h>
112 #undef TRACE_SYSTEM
113
114 #undef TP_PROBE_CB
115
116 extern const struct trace_syscall_table sc_table;
117 extern const struct trace_syscall_table compat_sc_table;
118
119 /* Event syscall exit table */
120 extern const struct trace_syscall_table sc_exit_table;
121 extern const struct trace_syscall_table compat_sc_exit_table;
122
123
124 #undef SC_EXIT
125
126 #undef CREATE_SYSCALL_TABLE
127
128 struct lttng_syscall_filter {
129 DECLARE_BITMAP(sc_entry, NR_syscalls);
130 DECLARE_BITMAP(sc_exit, NR_syscalls);
131 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
132 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
133 };
134
135 static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
136 struct pt_regs *regs, long id)
137 {
138 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
139 struct lttng_kernel_event_common_private *event_priv;
140
141 lttng_syscall_get_arguments(current, regs, args);
142 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
143 if (unlikely(in_compat_syscall()))
144 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
145 else
146 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
147 }
148 }
149
150 static __always_inline
151 void syscall_entry_event_call_func(struct hlist_head *action_list,
152 void *func, unsigned int nrargs,
153 struct pt_regs *regs)
154 {
155 struct lttng_kernel_event_common_private *event_priv;
156
157 switch (nrargs) {
158 case 0:
159 {
160 void (*fptr)(void *__data) = func;
161
162 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
163 fptr(event_priv->pub);
164 break;
165 }
166 case 1:
167 {
168 void (*fptr)(void *__data, unsigned long arg0) = func;
169 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
170
171 lttng_syscall_get_arguments(current, regs, args);
172 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
173 fptr(event_priv->pub, args[0]);
174 break;
175 }
176 case 2:
177 {
178 void (*fptr)(void *__data,
179 unsigned long arg0,
180 unsigned long arg1) = func;
181 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
182
183 lttng_syscall_get_arguments(current, regs, args);
184 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
185 fptr(event_priv->pub, args[0], args[1]);
186 break;
187 }
188 case 3:
189 {
190 void (*fptr)(void *__data,
191 unsigned long arg0,
192 unsigned long arg1,
193 unsigned long arg2) = func;
194 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
195
196 lttng_syscall_get_arguments(current, regs, args);
197 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
198 fptr(event_priv->pub, args[0], args[1], args[2]);
199 break;
200 }
201 case 4:
202 {
203 void (*fptr)(void *__data,
204 unsigned long arg0,
205 unsigned long arg1,
206 unsigned long arg2,
207 unsigned long arg3) = func;
208 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
209
210 lttng_syscall_get_arguments(current, regs, args);
211 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
212 fptr(event_priv->pub, args[0], args[1], args[2], args[3]);
213 break;
214 }
215 case 5:
216 {
217 void (*fptr)(void *__data,
218 unsigned long arg0,
219 unsigned long arg1,
220 unsigned long arg2,
221 unsigned long arg3,
222 unsigned long arg4) = func;
223 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
224
225 lttng_syscall_get_arguments(current, regs, args);
226 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
227 fptr(event_priv->pub, args[0], args[1], args[2], args[3], args[4]);
228 break;
229 }
230 case 6:
231 {
232 void (*fptr)(void *__data,
233 unsigned long arg0,
234 unsigned long arg1,
235 unsigned long arg2,
236 unsigned long arg3,
237 unsigned long arg4,
238 unsigned long arg5) = func;
239 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
240
241 lttng_syscall_get_arguments(current, regs, args);
242 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
243 fptr(event_priv->pub, args[0], args[1], args[2],
244 args[3], args[4], args[5]);
245 break;
246 }
247 default:
248 break;
249 }
250 }
251
252 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
253 {
254 struct lttng_kernel_syscall_table *syscall_table = __data;
255 struct hlist_head *action_list, *unknown_action_list;
256 const struct trace_syscall_entry *table, *entry;
257 size_t table_len;
258
259 if (unlikely(in_compat_syscall())) {
260 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
261
262 if (id < 0 || id >= NR_compat_syscalls
263 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
264 /* System call filtered out. */
265 return;
266 }
267 table = compat_sc_table.table;
268 table_len = compat_sc_table.len;
269 unknown_action_list = &syscall_table->compat_unknown_syscall_dispatch;
270 } else {
271 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
272
273 if (id < 0 || id >= NR_syscalls
274 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
275 /* System call filtered out. */
276 return;
277 }
278 table = sc_table.table;
279 table_len = sc_table.len;
280 unknown_action_list = &syscall_table->unknown_syscall_dispatch;
281 }
282 if (unlikely(id < 0 || id >= table_len)) {
283 syscall_entry_event_unknown(unknown_action_list, regs, id);
284 return;
285 }
286
287 entry = &table[id];
288 if (!entry->event_func) {
289 syscall_entry_event_unknown(unknown_action_list, regs, id);
290 return;
291 }
292
293 if (unlikely(in_compat_syscall())) {
294 action_list = &syscall_table->compat_syscall_dispatch[id];
295 } else {
296 action_list = &syscall_table->syscall_dispatch[id];
297 }
298 if (unlikely(hlist_empty(action_list)))
299 return;
300
301 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
302 }
303
304 static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
305 struct pt_regs *regs, long id, long ret)
306 {
307 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
308 struct lttng_kernel_event_common_private *event_priv;
309
310 lttng_syscall_get_arguments(current, regs, args);
311 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
312 if (unlikely(in_compat_syscall()))
313 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
314 args);
315 else
316 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
317 }
318 }
319
320 static __always_inline
321 void syscall_exit_event_call_func(struct hlist_head *action_list,
322 void *func, unsigned int nrargs,
323 struct pt_regs *regs, long ret)
324 {
325 struct lttng_kernel_event_common_private *event_priv;
326
327 switch (nrargs) {
328 case 0:
329 {
330 void (*fptr)(void *__data, long ret) = func;
331
332 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
333 fptr(event_priv->pub, ret);
334 break;
335 }
336 case 1:
337 {
338 void (*fptr)(void *__data,
339 long ret,
340 unsigned long arg0) = func;
341 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
342
343 lttng_syscall_get_arguments(current, regs, args);
344 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
345 fptr(event_priv->pub, ret, args[0]);
346 break;
347 }
348 case 2:
349 {
350 void (*fptr)(void *__data,
351 long ret,
352 unsigned long arg0,
353 unsigned long arg1) = func;
354 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
355
356 lttng_syscall_get_arguments(current, regs, args);
357 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
358 fptr(event_priv->pub, ret, args[0], args[1]);
359 break;
360 }
361 case 3:
362 {
363 void (*fptr)(void *__data,
364 long ret,
365 unsigned long arg0,
366 unsigned long arg1,
367 unsigned long arg2) = func;
368 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
369
370 lttng_syscall_get_arguments(current, regs, args);
371 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
372 fptr(event_priv->pub, ret, args[0], args[1], args[2]);
373 break;
374 }
375 case 4:
376 {
377 void (*fptr)(void *__data,
378 long ret,
379 unsigned long arg0,
380 unsigned long arg1,
381 unsigned long arg2,
382 unsigned long arg3) = func;
383 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
384
385 lttng_syscall_get_arguments(current, regs, args);
386 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
387 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3]);
388 break;
389 }
390 case 5:
391 {
392 void (*fptr)(void *__data,
393 long ret,
394 unsigned long arg0,
395 unsigned long arg1,
396 unsigned long arg2,
397 unsigned long arg3,
398 unsigned long arg4) = func;
399 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
400
401 lttng_syscall_get_arguments(current, regs, args);
402 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
403 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3], args[4]);
404 break;
405 }
406 case 6:
407 {
408 void (*fptr)(void *__data,
409 long ret,
410 unsigned long arg0,
411 unsigned long arg1,
412 unsigned long arg2,
413 unsigned long arg3,
414 unsigned long arg4,
415 unsigned long arg5) = func;
416 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
417
418 lttng_syscall_get_arguments(current, regs, args);
419 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
420 fptr(event_priv->pub, ret, args[0], args[1], args[2],
421 args[3], args[4], args[5]);
422 break;
423 }
424 default:
425 break;
426 }
427 }
428
429 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
430 {
431 struct lttng_kernel_syscall_table *syscall_table = __data;
432 struct hlist_head *action_list, *unknown_action_list;
433 const struct trace_syscall_entry *table, *entry;
434 size_t table_len;
435 long id;
436
437 id = syscall_get_nr(current, regs);
438
439 if (unlikely(in_compat_syscall())) {
440 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
441
442 if (id < 0 || id >= NR_compat_syscalls
443 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
444 /* System call filtered out. */
445 return;
446 }
447 table = compat_sc_exit_table.table;
448 table_len = compat_sc_exit_table.len;
449 unknown_action_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
450 } else {
451 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
452
453 if (id < 0 || id >= NR_syscalls
454 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
455 /* System call filtered out. */
456 return;
457 }
458 table = sc_exit_table.table;
459 table_len = sc_exit_table.len;
460 unknown_action_list = &syscall_table->unknown_syscall_exit_dispatch;
461 }
462 if (unlikely(id < 0 || id >= table_len)) {
463 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
464 return;
465 }
466
467 entry = &table[id];
468 if (!entry->event_func) {
469 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
470 return;
471 }
472
473 if (unlikely(in_compat_syscall())) {
474 action_list = &syscall_table->compat_syscall_exit_dispatch[id];
475 } else {
476 action_list = &syscall_table->syscall_exit_dispatch[id];
477 }
478 if (unlikely(hlist_empty(action_list)))
479 return;
480
481 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
482 regs, ret);
483 }
484
485 static
486 struct lttng_kernel_syscall_table *get_syscall_table_from_enabler(struct lttng_event_enabler_common *event_enabler)
487 {
488 switch (event_enabler->enabler_type) {
489 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
490 {
491 struct lttng_event_recorder_enabler *event_recorder_enabler =
492 container_of(event_enabler, struct lttng_event_recorder_enabler, parent);
493 return &event_recorder_enabler->chan->priv->parent.syscall_table;
494 }
495 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
496 {
497 struct lttng_event_notifier_enabler *event_notifier_enabler =
498 container_of(event_enabler, struct lttng_event_notifier_enabler, parent);
499 return &event_notifier_enabler->group->syscall_table;
500 }
501 default:
502 return NULL;
503 }
504 }
505
506 static
507 struct lttng_kernel_syscall_table *get_syscall_table_from_event(struct lttng_kernel_event_common *event)
508 {
509 switch (event->type) {
510 case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
511 {
512 struct lttng_kernel_event_recorder *event_recorder =
513 container_of(event, struct lttng_kernel_event_recorder, parent);
514 return &event_recorder->chan->priv->parent.syscall_table;
515 }
516 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
517 {
518 struct lttng_kernel_event_notifier *event_notifier =
519 container_of(event, struct lttng_kernel_event_notifier, parent);
520 return &event_notifier->priv->group->syscall_table;
521 }
522 default:
523 return NULL;
524 }
525 }
526
527 /*
528 * noinline to diminish caller stack size.
529 * Should be called with sessions lock held.
530 */
531 static
532 int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *table, size_t table_len,
533 struct hlist_head *chan_table, struct lttng_event_recorder_enabler *syscall_event_enabler,
534 enum sc_type type)
535 {
536 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(&syscall_event_enabler->parent);
537 struct lttng_kernel_channel_buffer *chan = syscall_event_enabler->chan;
538 struct lttng_kernel_session *session = chan->parent.session;
539 unsigned int i;
540
541 /* Allocate events for each syscall matching enabler, insert into table */
542 for (i = 0; i < table_len; i++) {
543 const struct lttng_kernel_event_desc *desc = table[i].desc;
544 struct lttng_event_recorder_enabler *event_enabler;
545 struct lttng_kernel_abi_event ev;
546 struct lttng_kernel_event_recorder_private *event_recorder_priv;
547 struct lttng_kernel_event_recorder *event_recorder;
548 struct hlist_head *head;
549 bool found = false;
550
551 if (!desc) {
552 /* Unknown syscall */
553 continue;
554 }
555 if (lttng_desc_match_enabler(desc,
556 lttng_event_recorder_enabler_as_enabler(syscall_event_enabler)) <= 0)
557 continue;
558 /*
559 * Check if already created.
560 */
561 head = utils_borrow_hash_table_bucket(
562 session->priv->events_ht.table, LTTNG_EVENT_HT_SIZE,
563 desc->event_name);
564 lttng_hlist_for_each_entry(event_recorder_priv, head, hlist) {
565 if (event_recorder_priv->parent.desc == desc
566 && get_syscall_table_from_event(event_recorder_priv->parent.pub) == syscall_table)
567 found = true;
568 }
569 if (found)
570 continue;
571
572 /* We need to create an event for this syscall/enabler. */
573 memset(&ev, 0, sizeof(ev));
574 switch (type) {
575 case SC_TYPE_ENTRY:
576 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
577 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
578 break;
579 case SC_TYPE_EXIT:
580 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
581 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
582 break;
583 case SC_TYPE_COMPAT_ENTRY:
584 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
585 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
586 break;
587 case SC_TYPE_COMPAT_EXIT:
588 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
589 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
590 break;
591 }
592 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
593 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
594 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
595 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan);
596 if (!event_enabler) {
597 return -ENOMEM;
598 }
599 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
600 WARN_ON_ONCE(!event_recorder);
601 lttng_event_enabler_destroy(event_enabler);
602 if (IS_ERR(event_recorder)) {
603 /*
604 * If something goes wrong in event registration
605 * after the first one, we have no choice but to
606 * leave the previous events in there, until
607 * deleted by session teardown.
608 */
609 return PTR_ERR(event_recorder);
610 }
611 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan_table[i]);
612 }
613 return 0;
614 }
615
616 /*
617 * Should be called with sessions lock held.
618 */
619 int lttng_syscalls_register_event(struct lttng_event_recorder_enabler *syscall_event_enabler)
620 {
621 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(&syscall_event_enabler->parent);
622 struct lttng_kernel_abi_event ev;
623 int ret;
624
625 wrapper_vmalloc_sync_mappings();
626
627 if (!syscall_table->syscall_dispatch) {
628 /* create syscall table mapping syscall to events */
629 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
630 if (!syscall_table->syscall_dispatch)
631 return -ENOMEM;
632 }
633 if (!syscall_table->syscall_exit_dispatch) {
634 /* create syscall table mapping syscall to events */
635 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_exit_table.len, GFP_KERNEL);
636 if (!syscall_table->syscall_exit_dispatch)
637 return -ENOMEM;
638 }
639
640
641 #ifdef CONFIG_COMPAT
642 if (!syscall_table->compat_syscall_dispatch) {
643 /* create syscall table mapping compat syscall to events */
644 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
645 if (!syscall_table->compat_syscall_dispatch)
646 return -ENOMEM;
647 }
648
649 if (!syscall_table->compat_syscall_exit_dispatch) {
650 /* create syscall table mapping compat syscall to events */
651 syscall_table->compat_syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len, GFP_KERNEL);
652 if (!syscall_table->compat_syscall_exit_dispatch)
653 return -ENOMEM;
654 }
655 #endif
656 if (hlist_empty(&syscall_table->unknown_syscall_dispatch)) {
657 const struct lttng_kernel_event_desc *desc =
658 &__event_desc___syscall_entry_unknown;
659 struct lttng_kernel_event_recorder *event_recorder;
660 struct lttng_event_recorder_enabler *event_enabler;
661
662 memset(&ev, 0, sizeof(ev));
663 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
664 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
665 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
666 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
667 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
668 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
669 if (!event_enabler) {
670 return -ENOMEM;
671 }
672 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
673 lttng_event_enabler_destroy(event_enabler);
674 WARN_ON_ONCE(!event_recorder);
675 if (IS_ERR(event_recorder)) {
676 return PTR_ERR(event_recorder);
677 }
678 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->unknown_syscall_dispatch);
679 }
680
681 if (hlist_empty(&syscall_table->compat_unknown_syscall_dispatch)) {
682 const struct lttng_kernel_event_desc *desc =
683 &__event_desc___compat_syscall_entry_unknown;
684 struct lttng_kernel_event_recorder *event_recorder;
685 struct lttng_event_recorder_enabler *event_enabler;
686
687 memset(&ev, 0, sizeof(ev));
688 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
689 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
690 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
691 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
692 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
693 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
694 if (!event_enabler) {
695 return -ENOMEM;
696 }
697 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
698 WARN_ON_ONCE(!event_recorder);
699 lttng_event_enabler_destroy(event_enabler);
700 if (IS_ERR(event_recorder)) {
701 return PTR_ERR(event_recorder);
702 }
703 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->compat_unknown_syscall_dispatch);
704 }
705
706 if (hlist_empty(&syscall_table->compat_unknown_syscall_exit_dispatch)) {
707 const struct lttng_kernel_event_desc *desc =
708 &__event_desc___compat_syscall_exit_unknown;
709 struct lttng_kernel_event_recorder *event_recorder;
710 struct lttng_event_recorder_enabler *event_enabler;
711
712 memset(&ev, 0, sizeof(ev));
713 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
714 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
715 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
716 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
717 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
718 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
719 if (!event_enabler) {
720 return -ENOMEM;
721 }
722 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
723 WARN_ON_ONCE(!event_recorder);
724 lttng_event_enabler_destroy(event_enabler);
725 if (IS_ERR(event_recorder)) {
726 return PTR_ERR(event_recorder);
727 }
728 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->compat_unknown_syscall_exit_dispatch);
729 }
730
731 if (hlist_empty(&syscall_table->unknown_syscall_exit_dispatch)) {
732 const struct lttng_kernel_event_desc *desc =
733 &__event_desc___syscall_exit_unknown;
734 struct lttng_kernel_event_recorder *event_recorder;
735 struct lttng_event_recorder_enabler *event_enabler;
736
737 memset(&ev, 0, sizeof(ev));
738 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
739 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
740 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
741 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
742 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
743 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
744 if (!event_enabler) {
745 return -ENOMEM;
746 }
747 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
748 WARN_ON_ONCE(!event_recorder);
749 lttng_event_enabler_destroy(event_enabler);
750 if (IS_ERR(event_recorder)) {
751 return PTR_ERR(event_recorder);
752 }
753 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->unknown_syscall_exit_dispatch);
754 }
755
756 ret = lttng_create_syscall_event_if_missing(sc_table.table, sc_table.len,
757 syscall_table->syscall_dispatch, syscall_event_enabler, SC_TYPE_ENTRY);
758 if (ret)
759 return ret;
760 ret = lttng_create_syscall_event_if_missing(sc_exit_table.table, sc_exit_table.len,
761 syscall_table->syscall_exit_dispatch, syscall_event_enabler, SC_TYPE_EXIT);
762 if (ret)
763 return ret;
764
765 #ifdef CONFIG_COMPAT
766 ret = lttng_create_syscall_event_if_missing(compat_sc_table.table, compat_sc_table.len,
767 syscall_table->compat_syscall_dispatch, syscall_event_enabler, SC_TYPE_COMPAT_ENTRY);
768 if (ret)
769 return ret;
770 ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table.table, compat_sc_exit_table.len,
771 syscall_table->compat_syscall_exit_dispatch, syscall_event_enabler, SC_TYPE_COMPAT_EXIT);
772 if (ret)
773 return ret;
774 #endif
775
776 if (!syscall_table->sc_filter) {
777 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
778 GFP_KERNEL);
779 if (!syscall_table->sc_filter)
780 return -ENOMEM;
781 }
782
783 if (!syscall_table->sys_enter_registered) {
784 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
785 (void *) syscall_entry_event_probe, syscall_table);
786 if (ret)
787 return ret;
788 syscall_table->sys_enter_registered = 1;
789 }
790 /*
791 * We change the name of sys_exit tracepoint due to namespace
792 * conflict with sys_exit syscall entry.
793 */
794 if (!syscall_table->sys_exit_registered) {
795 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
796 (void *) syscall_exit_event_probe, syscall_table);
797 if (ret) {
798 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
799 (void *) syscall_entry_event_probe, syscall_table));
800 return ret;
801 }
802 syscall_table->sys_exit_registered = 1;
803 }
804 return ret;
805 }
806
807 /*
808 * Should be called with sessions lock held.
809 */
810 int lttng_syscalls_register_event_notifier(
811 struct lttng_event_notifier_enabler *event_notifier_enabler)
812 {
813 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
814 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
815 unsigned int i;
816 int ret = 0;
817
818 wrapper_vmalloc_sync_mappings();
819
820 if (!syscall_table->syscall_dispatch) {
821 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
822 if (!syscall_table->syscall_dispatch)
823 return -ENOMEM;
824
825 /* Initialize all list_head */
826 for (i = 0; i < sc_table.len; i++)
827 INIT_HLIST_HEAD(&syscall_table->syscall_dispatch[i]);
828
829 /* Init the unknown syscall notifier list. */
830 INIT_HLIST_HEAD(&syscall_table->unknown_syscall_dispatch);
831 }
832
833 if (!syscall_table->syscall_exit_dispatch) {
834 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
835 if (!syscall_table->syscall_exit_dispatch)
836 return -ENOMEM;
837
838 /* Initialize all list_head */
839 for (i = 0; i < sc_table.len; i++)
840 INIT_HLIST_HEAD(&syscall_table->syscall_exit_dispatch[i]);
841
842 /* Init the unknown exit syscall notifier list. */
843 INIT_HLIST_HEAD(&syscall_table->unknown_syscall_exit_dispatch);
844 }
845
846 #ifdef CONFIG_COMPAT
847 if (!syscall_table->compat_syscall_dispatch) {
848 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
849 if (!syscall_table->compat_syscall_dispatch)
850 return -ENOMEM;
851
852 /* Initialize all list_head */
853 for (i = 0; i < compat_sc_table.len; i++)
854 INIT_HLIST_HEAD(&syscall_table->compat_syscall_dispatch[i]);
855
856 /* Init the unknown syscall notifier list. */
857 INIT_HLIST_HEAD(&syscall_table->compat_unknown_syscall_dispatch);
858 }
859
860 if (!syscall_table->compat_syscall_exit_dispatch) {
861 syscall_table->compat_syscall_exit_dispatch =
862 kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len,
863 GFP_KERNEL);
864 if (!syscall_table->compat_syscall_exit_dispatch)
865 return -ENOMEM;
866
867 /* Initialize all list_head */
868 for (i = 0; i < compat_sc_exit_table.len; i++)
869 INIT_HLIST_HEAD(&syscall_table->compat_syscall_exit_dispatch[i]);
870
871 /* Init the unknown exit syscall notifier list. */
872 INIT_HLIST_HEAD(&syscall_table->compat_unknown_syscall_exit_dispatch);
873 }
874 #endif
875
876 if (!syscall_table->sc_filter) {
877 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
878 GFP_KERNEL);
879 if (!syscall_table->sc_filter)
880 return -ENOMEM;
881 }
882
883 if (!syscall_table->sys_enter_registered) {
884 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
885 (void *) syscall_entry_event_probe, syscall_table);
886 if (ret)
887 return ret;
888 syscall_table->sys_enter_registered = 1;
889 }
890
891 if (!syscall_table->sys_exit_registered) {
892 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
893 (void *) syscall_exit_event_probe, syscall_table);
894 if (ret) {
895 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
896 (void *) syscall_entry_event_probe, syscall_table));
897 return ret;
898 }
899 syscall_table->sys_exit_registered = 1;
900 }
901
902 return ret;
903 }
904
905 static
906 int create_unknown_event_notifier(
907 struct lttng_event_notifier_enabler *event_notifier_enabler,
908 enum sc_type type)
909 {
910 struct lttng_kernel_event_notifier_private *event_notifier_priv;
911 struct lttng_kernel_event_notifier *event_notifier;
912 const struct lttng_kernel_event_desc *desc;
913 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
914 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
915 struct lttng_kernel_abi_event_notifier event_notifier_param;
916 uint64_t user_token = event_notifier_enabler->parent.user_token;
917 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
918 struct lttng_event_enabler_common *base_enabler = lttng_event_notifier_enabler_as_enabler(
919 event_notifier_enabler);
920 struct hlist_head *unknown_dispatch_list;
921 int ret = 0;
922 bool found = false;
923 enum lttng_kernel_abi_syscall_abi abi;
924 enum lttng_kernel_abi_syscall_entryexit entryexit;
925 struct hlist_head *head;
926
927 switch (type) {
928 case SC_TYPE_ENTRY:
929 desc = &__event_desc___syscall_entry_unknown;
930 unknown_dispatch_list = &syscall_table->unknown_syscall_dispatch;
931 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
932 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
933 break;
934 case SC_TYPE_EXIT:
935 desc = &__event_desc___syscall_exit_unknown;
936 unknown_dispatch_list = &syscall_table->unknown_syscall_exit_dispatch;
937 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
938 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
939 break;
940 case SC_TYPE_COMPAT_ENTRY:
941 desc = &__event_desc___compat_syscall_entry_unknown;
942 unknown_dispatch_list = &syscall_table->compat_unknown_syscall_dispatch;
943 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
944 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
945 break;
946 case SC_TYPE_COMPAT_EXIT:
947 desc = &__event_desc___compat_syscall_exit_unknown;
948 unknown_dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
949 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
950 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
951 break;
952 default:
953 BUG_ON(1);
954 }
955
956 /*
957 * Check if already created.
958 */
959 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
960 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
961 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
962 if (event_notifier_priv->parent.desc == desc &&
963 event_notifier_priv->parent.user_token == base_enabler->user_token)
964 found = true;
965 }
966 if (found)
967 goto end;
968
969 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
970 strncat(event_notifier_param.event.name, desc->event_name,
971 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
972
973 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
974
975 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
976 event_notifier_param.event.u.syscall.abi = abi;
977 event_notifier_param.event.u.syscall.entryexit = entryexit;
978
979 event_notifier = _lttng_event_notifier_create(desc, user_token,
980 error_counter_index, group, &event_notifier_param,
981 event_notifier_param.event.instrumentation);
982 if (IS_ERR(event_notifier)) {
983 printk(KERN_INFO "Unable to create unknown notifier %s\n",
984 desc->event_name);
985 ret = -ENOMEM;
986 goto end;
987 }
988
989 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, unknown_dispatch_list);
990
991 end:
992 return ret;
993 }
994
995 static int create_matching_event_notifiers(
996 struct lttng_event_notifier_enabler *event_notifier_enabler,
997 const struct trace_syscall_entry *table,
998 size_t table_len, enum sc_type type)
999 {
1000 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1001 const struct lttng_kernel_event_desc *desc;
1002 uint64_t user_token = event_notifier_enabler->parent.user_token;
1003 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
1004 unsigned int i;
1005 int ret = 0;
1006
1007 /* iterate over all syscall and create event_notifier that match */
1008 for (i = 0; i < table_len; i++) {
1009 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1010 struct lttng_kernel_event_notifier *event_notifier;
1011 struct lttng_kernel_abi_event_notifier event_notifier_param;
1012 struct hlist_head *head;
1013 int found = 0;
1014
1015 desc = table[i].desc;
1016 if (!desc) {
1017 /* Unknown syscall */
1018 continue;
1019 }
1020
1021 if (!lttng_desc_match_enabler(desc,
1022 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
1023 continue;
1024
1025 /*
1026 * Check if already created.
1027 */
1028 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
1029 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
1030 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
1031 if (event_notifier_priv->parent.desc == desc
1032 && event_notifier_priv->parent.user_token == event_notifier_enabler->parent.user_token)
1033 found = 1;
1034 }
1035 if (found)
1036 continue;
1037
1038 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1039 switch (type) {
1040 case SC_TYPE_ENTRY:
1041 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1042 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
1043 break;
1044 case SC_TYPE_EXIT:
1045 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1046 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
1047 break;
1048 case SC_TYPE_COMPAT_ENTRY:
1049 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1050 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
1051 break;
1052 case SC_TYPE_COMPAT_EXIT:
1053 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1054 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
1055 break;
1056 }
1057 strncat(event_notifier_param.event.name, desc->event_name,
1058 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1059 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1060 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1061
1062 event_notifier = _lttng_event_notifier_create(desc, user_token,
1063 error_counter_index, group, &event_notifier_param,
1064 event_notifier_param.event.instrumentation);
1065 if (IS_ERR(event_notifier)) {
1066 printk(KERN_INFO "Unable to create event_notifier %s\n",
1067 desc->event_name);
1068 ret = -ENOMEM;
1069 goto end;
1070 }
1071
1072 event_notifier->priv->parent.u.syscall.syscall_id = i;
1073 }
1074
1075 end:
1076 return ret;
1077
1078 }
1079
1080 int lttng_syscalls_create_matching_event_notifiers(
1081 struct lttng_event_notifier_enabler *event_notifier_enabler)
1082 {
1083 int ret;
1084 struct lttng_event_enabler_common *base_enabler =
1085 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
1086 enum lttng_kernel_abi_syscall_entryexit entryexit =
1087 base_enabler->event_param.u.syscall.entryexit;
1088
1089 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
1090 ret = create_matching_event_notifiers(event_notifier_enabler,
1091 sc_table.table, sc_table.len, SC_TYPE_ENTRY);
1092 if (ret)
1093 goto end;
1094
1095 ret = create_matching_event_notifiers(event_notifier_enabler,
1096 compat_sc_table.table, compat_sc_table.len,
1097 SC_TYPE_COMPAT_ENTRY);
1098 if (ret)
1099 goto end;
1100
1101 ret = create_unknown_event_notifier(event_notifier_enabler,
1102 SC_TYPE_ENTRY);
1103 if (ret)
1104 goto end;
1105
1106 ret = create_unknown_event_notifier(event_notifier_enabler,
1107 SC_TYPE_COMPAT_ENTRY);
1108 if (ret)
1109 goto end;
1110 }
1111
1112 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
1113 ret = create_matching_event_notifiers(event_notifier_enabler,
1114 sc_exit_table.table, sc_exit_table.len,
1115 SC_TYPE_EXIT);
1116 if (ret)
1117 goto end;
1118
1119 ret = create_unknown_event_notifier(event_notifier_enabler,
1120 SC_TYPE_EXIT);
1121 if (ret)
1122 goto end;
1123
1124 ret = create_matching_event_notifiers(event_notifier_enabler,
1125 compat_sc_exit_table.table, compat_sc_exit_table.len,
1126 SC_TYPE_COMPAT_EXIT);
1127 if (ret)
1128 goto end;
1129
1130 ret = create_unknown_event_notifier(event_notifier_enabler,
1131 SC_TYPE_COMPAT_EXIT);
1132 if (ret)
1133 goto end;
1134 }
1135
1136 end:
1137 return ret;
1138 }
1139
1140 /*
1141 * Unregister the syscall event_notifier probes from the callsites.
1142 */
1143 int lttng_syscalls_unregister_event_notifier_group(
1144 struct lttng_event_notifier_group *event_notifier_group)
1145 {
1146 struct lttng_kernel_syscall_table *syscall_table = &event_notifier_group->syscall_table;
1147 int ret;
1148
1149 /*
1150 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1151 * At the moment, we don't think it's desirable to have one fired
1152 * event_notifier for the entry and one for the exit of a syscall.
1153 */
1154 if (syscall_table->sys_enter_registered) {
1155 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1156 (void *) syscall_entry_event_probe, syscall_table);
1157 if (ret)
1158 return ret;
1159 syscall_table->sys_enter_registered = 0;
1160 }
1161 if (syscall_table->sys_exit_registered) {
1162 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1163 (void *) syscall_exit_event_probe, syscall_table);
1164 if (ret)
1165 return ret;
1166 syscall_table->sys_enter_registered = 0;
1167 }
1168
1169 kfree(syscall_table->syscall_dispatch);
1170 kfree(syscall_table->syscall_exit_dispatch);
1171 #ifdef CONFIG_COMPAT
1172 kfree(syscall_table->compat_syscall_dispatch);
1173 kfree(syscall_table->compat_syscall_exit_dispatch);
1174 #endif
1175 return 0;
1176 }
1177
1178 int lttng_syscalls_unregister_channel(struct lttng_kernel_channel_buffer *chan)
1179 {
1180 struct lttng_kernel_syscall_table *syscall_table = &chan->priv->parent.syscall_table;
1181 int ret;
1182
1183 if (!syscall_table->syscall_dispatch)
1184 return 0;
1185 if (syscall_table->sys_enter_registered) {
1186 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1187 (void *) syscall_entry_event_probe, syscall_table);
1188 if (ret)
1189 return ret;
1190 syscall_table->sys_enter_registered = 0;
1191 }
1192 if (syscall_table->sys_exit_registered) {
1193 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1194 (void *) syscall_exit_event_probe, syscall_table);
1195 if (ret)
1196 return ret;
1197 syscall_table->sys_exit_registered = 0;
1198 }
1199 return 0;
1200 }
1201
1202 int lttng_syscalls_destroy_event(struct lttng_kernel_channel_buffer *chan)
1203 {
1204 struct lttng_kernel_syscall_table *syscall_table = &chan->priv->parent.syscall_table;
1205
1206 kfree(syscall_table->syscall_dispatch);
1207 kfree(syscall_table->syscall_exit_dispatch);
1208 #ifdef CONFIG_COMPAT
1209 kfree(syscall_table->compat_syscall_dispatch);
1210 kfree(syscall_table->compat_syscall_exit_dispatch);
1211 #endif
1212 kfree(syscall_table->sc_filter);
1213 return 0;
1214 }
1215
1216 static
1217 int get_syscall_nr(const char *syscall_name)
1218 {
1219 int syscall_nr = -1;
1220 int i;
1221
1222 for (i = 0; i < sc_table.len; i++) {
1223 const struct trace_syscall_entry *entry;
1224 const char *it_name;
1225
1226 entry = &sc_table.table[i];
1227 if (!entry->desc)
1228 continue;
1229 it_name = entry->desc->event_name;
1230 it_name += strlen(SYSCALL_ENTRY_STR);
1231 if (!strcmp(syscall_name, it_name)) {
1232 syscall_nr = i;
1233 break;
1234 }
1235 }
1236 return syscall_nr;
1237 }
1238
1239 static
1240 int get_compat_syscall_nr(const char *syscall_name)
1241 {
1242 int syscall_nr = -1;
1243 int i;
1244
1245 for (i = 0; i < compat_sc_table.len; i++) {
1246 const struct trace_syscall_entry *entry;
1247 const char *it_name;
1248
1249 entry = &compat_sc_table.table[i];
1250 if (!entry->desc)
1251 continue;
1252 it_name = entry->desc->event_name;
1253 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1254 if (!strcmp(syscall_name, it_name)) {
1255 syscall_nr = i;
1256 break;
1257 }
1258 }
1259 return syscall_nr;
1260 }
1261
1262 static
1263 uint32_t get_sc_tables_len(void)
1264 {
1265 return sc_table.len + compat_sc_table.len;
1266 }
1267
1268 static
1269 const char *get_syscall_name(const char *desc_name,
1270 enum lttng_syscall_abi abi,
1271 enum lttng_syscall_entryexit entryexit)
1272 {
1273 size_t prefix_len = 0;
1274
1275
1276 switch (entryexit) {
1277 case LTTNG_SYSCALL_ENTRY:
1278 switch (abi) {
1279 case LTTNG_SYSCALL_ABI_NATIVE:
1280 prefix_len = strlen(SYSCALL_ENTRY_STR);
1281 break;
1282 case LTTNG_SYSCALL_ABI_COMPAT:
1283 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1284 break;
1285 }
1286 break;
1287 case LTTNG_SYSCALL_EXIT:
1288 switch (abi) {
1289 case LTTNG_SYSCALL_ABI_NATIVE:
1290 prefix_len = strlen(SYSCALL_EXIT_STR);
1291 break;
1292 case LTTNG_SYSCALL_ABI_COMPAT:
1293 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1294 break;
1295 }
1296 break;
1297 }
1298 WARN_ON_ONCE(prefix_len == 0);
1299 return desc_name + prefix_len;
1300 }
1301
1302 static
1303 int lttng_syscall_filter_enable(
1304 struct lttng_syscall_filter *filter,
1305 const char *desc_name, enum lttng_syscall_abi abi,
1306 enum lttng_syscall_entryexit entryexit)
1307 {
1308 const char *syscall_name;
1309 unsigned long *bitmap;
1310 int syscall_nr;
1311
1312 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1313
1314 switch (abi) {
1315 case LTTNG_SYSCALL_ABI_NATIVE:
1316 syscall_nr = get_syscall_nr(syscall_name);
1317 break;
1318 case LTTNG_SYSCALL_ABI_COMPAT:
1319 syscall_nr = get_compat_syscall_nr(syscall_name);
1320 break;
1321 default:
1322 return -EINVAL;
1323 }
1324 if (syscall_nr < 0)
1325 return -ENOENT;
1326
1327 switch (entryexit) {
1328 case LTTNG_SYSCALL_ENTRY:
1329 switch (abi) {
1330 case LTTNG_SYSCALL_ABI_NATIVE:
1331 bitmap = filter->sc_entry;
1332 break;
1333 case LTTNG_SYSCALL_ABI_COMPAT:
1334 bitmap = filter->sc_compat_entry;
1335 break;
1336 default:
1337 return -EINVAL;
1338 }
1339 break;
1340 case LTTNG_SYSCALL_EXIT:
1341 switch (abi) {
1342 case LTTNG_SYSCALL_ABI_NATIVE:
1343 bitmap = filter->sc_exit;
1344 break;
1345 case LTTNG_SYSCALL_ABI_COMPAT:
1346 bitmap = filter->sc_compat_exit;
1347 break;
1348 default:
1349 return -EINVAL;
1350 }
1351 break;
1352 default:
1353 return -EINVAL;
1354 }
1355 if (test_bit(syscall_nr, bitmap))
1356 return -EEXIST;
1357 bitmap_set(bitmap, syscall_nr, 1);
1358 return 0;
1359 }
1360
1361 int lttng_syscall_filter_enable_event_notifier(
1362 struct lttng_kernel_event_notifier *event_notifier)
1363 {
1364 struct lttng_event_notifier_group *group = event_notifier->priv->group;
1365 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
1366 unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id;
1367 struct hlist_head *dispatch_list;
1368 int ret = 0;
1369
1370 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
1371
1372 ret = lttng_syscall_filter_enable(syscall_table->sc_filter,
1373 event_notifier->priv->parent.desc->event_name,
1374 event_notifier->priv->parent.u.syscall.abi,
1375 event_notifier->priv->parent.u.syscall.entryexit);
1376 if (ret) {
1377 goto end;
1378 }
1379
1380 switch (event_notifier->priv->parent.u.syscall.entryexit) {
1381 case LTTNG_SYSCALL_ENTRY:
1382 switch (event_notifier->priv->parent.u.syscall.abi) {
1383 case LTTNG_SYSCALL_ABI_NATIVE:
1384 dispatch_list = &syscall_table->syscall_dispatch[syscall_id];
1385 break;
1386 case LTTNG_SYSCALL_ABI_COMPAT:
1387 dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id];
1388 break;
1389 default:
1390 ret = -EINVAL;
1391 goto end;
1392 }
1393 break;
1394 case LTTNG_SYSCALL_EXIT:
1395 switch (event_notifier->priv->parent.u.syscall.abi) {
1396 case LTTNG_SYSCALL_ABI_NATIVE:
1397 dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id];
1398 break;
1399 case LTTNG_SYSCALL_ABI_COMPAT:
1400 dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id];
1401 break;
1402 default:
1403 ret = -EINVAL;
1404 goto end;
1405 }
1406 break;
1407 default:
1408 ret = -EINVAL;
1409 goto end;
1410 }
1411
1412 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list);
1413
1414 end:
1415 return ret ;
1416 }
1417
1418 int lttng_syscall_filter_enable_event(
1419 struct lttng_kernel_channel_buffer *channel,
1420 struct lttng_kernel_event_recorder *event_recorder)
1421 {
1422 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1423
1424 WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
1425
1426 return lttng_syscall_filter_enable(syscall_table->sc_filter,
1427 event_recorder->priv->parent.desc->event_name,
1428 event_recorder->priv->parent.u.syscall.abi,
1429 event_recorder->priv->parent.u.syscall.entryexit);
1430 }
1431
1432 static
1433 int lttng_syscall_filter_disable(
1434 struct lttng_syscall_filter *filter,
1435 const char *desc_name, enum lttng_syscall_abi abi,
1436 enum lttng_syscall_entryexit entryexit)
1437 {
1438 const char *syscall_name;
1439 unsigned long *bitmap;
1440 int syscall_nr;
1441
1442 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1443
1444 switch (abi) {
1445 case LTTNG_SYSCALL_ABI_NATIVE:
1446 syscall_nr = get_syscall_nr(syscall_name);
1447 break;
1448 case LTTNG_SYSCALL_ABI_COMPAT:
1449 syscall_nr = get_compat_syscall_nr(syscall_name);
1450 break;
1451 default:
1452 return -EINVAL;
1453 }
1454 if (syscall_nr < 0)
1455 return -ENOENT;
1456
1457 switch (entryexit) {
1458 case LTTNG_SYSCALL_ENTRY:
1459 switch (abi) {
1460 case LTTNG_SYSCALL_ABI_NATIVE:
1461 bitmap = filter->sc_entry;
1462 break;
1463 case LTTNG_SYSCALL_ABI_COMPAT:
1464 bitmap = filter->sc_compat_entry;
1465 break;
1466 default:
1467 return -EINVAL;
1468 }
1469 break;
1470 case LTTNG_SYSCALL_EXIT:
1471 switch (abi) {
1472 case LTTNG_SYSCALL_ABI_NATIVE:
1473 bitmap = filter->sc_exit;
1474 break;
1475 case LTTNG_SYSCALL_ABI_COMPAT:
1476 bitmap = filter->sc_compat_exit;
1477 break;
1478 default:
1479 return -EINVAL;
1480 }
1481 break;
1482 default:
1483 return -EINVAL;
1484 }
1485 if (!test_bit(syscall_nr, bitmap))
1486 return -EEXIST;
1487 bitmap_clear(bitmap, syscall_nr, 1);
1488
1489 return 0;
1490 }
1491
1492 int lttng_syscall_filter_disable_event_notifier(
1493 struct lttng_kernel_event_notifier *event_notifier)
1494 {
1495 struct lttng_event_notifier_group *group = event_notifier->priv->group;
1496 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
1497 int ret;
1498
1499 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
1500
1501 ret = lttng_syscall_filter_disable(syscall_table->sc_filter,
1502 event_notifier->priv->parent.desc->event_name,
1503 event_notifier->priv->parent.u.syscall.abi,
1504 event_notifier->priv->parent.u.syscall.entryexit);
1505 WARN_ON_ONCE(ret != 0);
1506
1507 hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node);
1508 return 0;
1509 }
1510
1511 int lttng_syscall_filter_disable_event(
1512 struct lttng_kernel_channel_buffer *channel,
1513 struct lttng_kernel_event_recorder *event_recorder)
1514 {
1515 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1516
1517 return lttng_syscall_filter_disable(syscall_table->sc_filter,
1518 event_recorder->priv->parent.desc->event_name,
1519 event_recorder->priv->parent.u.syscall.abi,
1520 event_recorder->priv->parent.u.syscall.entryexit);
1521 }
1522
1523 static
1524 const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1525 {
1526 const struct trace_syscall_entry *entry;
1527 int iter = 0;
1528
1529 for (entry = sc_table.table;
1530 entry < sc_table.table + sc_table.len;
1531 entry++) {
1532 if (iter++ >= *pos)
1533 return entry;
1534 }
1535 for (entry = compat_sc_table.table;
1536 entry < compat_sc_table.table + compat_sc_table.len;
1537 entry++) {
1538 if (iter++ >= *pos)
1539 return entry;
1540 }
1541 /* End of list */
1542 return NULL;
1543 }
1544
1545 static
1546 void *syscall_list_start(struct seq_file *m, loff_t *pos)
1547 {
1548 return (void *) syscall_list_get_entry(pos);
1549 }
1550
1551 static
1552 void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1553 {
1554 (*ppos)++;
1555 return (void *) syscall_list_get_entry(ppos);
1556 }
1557
1558 static
1559 void syscall_list_stop(struct seq_file *m, void *p)
1560 {
1561 }
1562
1563 static
1564 int get_sc_table(const struct trace_syscall_entry *entry,
1565 const struct trace_syscall_entry **table,
1566 unsigned int *bitness)
1567 {
1568 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
1569 if (bitness)
1570 *bitness = BITS_PER_LONG;
1571 if (table)
1572 *table = sc_table.table;
1573 return 0;
1574 }
1575 if (!(entry >= compat_sc_table.table
1576 && entry < compat_sc_table.table + compat_sc_table.len)) {
1577 return -EINVAL;
1578 }
1579 if (bitness)
1580 *bitness = 32;
1581 if (table)
1582 *table = compat_sc_table.table;
1583 return 0;
1584 }
1585
1586 static
1587 int syscall_list_show(struct seq_file *m, void *p)
1588 {
1589 const struct trace_syscall_entry *table, *entry = p;
1590 unsigned int bitness;
1591 unsigned long index;
1592 int ret;
1593 const char *name;
1594
1595 ret = get_sc_table(entry, &table, &bitness);
1596 if (ret)
1597 return ret;
1598 if (!entry->desc)
1599 return 0;
1600 if (table == sc_table.table) {
1601 index = entry - table;
1602 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
1603 } else {
1604 index = (entry - table) + sc_table.len;
1605 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
1606 }
1607 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
1608 index, name, bitness);
1609 return 0;
1610 }
1611
1612 static
1613 const struct seq_operations lttng_syscall_list_seq_ops = {
1614 .start = syscall_list_start,
1615 .next = syscall_list_next,
1616 .stop = syscall_list_stop,
1617 .show = syscall_list_show,
1618 };
1619
1620 static
1621 int lttng_syscall_list_open(struct inode *inode, struct file *file)
1622 {
1623 return seq_open(file, &lttng_syscall_list_seq_ops);
1624 }
1625
1626 const struct file_operations lttng_syscall_list_fops = {
1627 .owner = THIS_MODULE,
1628 .open = lttng_syscall_list_open,
1629 .read = seq_read,
1630 .llseek = seq_lseek,
1631 .release = seq_release,
1632 };
1633
1634 /*
1635 * A syscall is enabled if it is traced for either entry or exit.
1636 */
1637 long lttng_channel_syscall_mask(struct lttng_kernel_channel_buffer *channel,
1638 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
1639 {
1640 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1641 uint32_t len, sc_tables_len, bitmask_len;
1642 int ret = 0, bit;
1643 char *tmp_mask;
1644 struct lttng_syscall_filter *filter;
1645
1646 ret = get_user(len, &usyscall_mask->len);
1647 if (ret)
1648 return ret;
1649 sc_tables_len = get_sc_tables_len();
1650 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1651 if (len < sc_tables_len) {
1652 return put_user(sc_tables_len, &usyscall_mask->len);
1653 }
1654 /* Array is large enough, we can copy array to user-space. */
1655 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1656 if (!tmp_mask)
1657 return -ENOMEM;
1658 filter = syscall_table->sc_filter;
1659
1660 for (bit = 0; bit < sc_table.len; bit++) {
1661 char state;
1662
1663 if (syscall_table->syscall_dispatch) {
1664 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1665 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
1666 state = test_bit(bit, filter->sc_entry)
1667 || test_bit(bit, filter->sc_exit);
1668 else
1669 state = 1;
1670 } else {
1671 state = 0;
1672 }
1673 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
1674 }
1675 for (; bit < sc_tables_len; bit++) {
1676 char state;
1677
1678 if (syscall_table->compat_syscall_dispatch) {
1679 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1680 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
1681 state = test_bit(bit - sc_table.len,
1682 filter->sc_compat_entry)
1683 || test_bit(bit - sc_table.len,
1684 filter->sc_compat_exit);
1685 else
1686 state = 1;
1687 } else {
1688 state = 0;
1689 }
1690 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
1691 }
1692 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1693 ret = -EFAULT;
1694 kfree(tmp_mask);
1695 return ret;
1696 }
1697
1698 int lttng_abi_syscall_list(void)
1699 {
1700 struct file *syscall_list_file;
1701 int file_fd, ret;
1702
1703 file_fd = lttng_get_unused_fd();
1704 if (file_fd < 0) {
1705 ret = file_fd;
1706 goto fd_error;
1707 }
1708
1709 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
1710 &lttng_syscall_list_fops,
1711 NULL, O_RDWR);
1712 if (IS_ERR(syscall_list_file)) {
1713 ret = PTR_ERR(syscall_list_file);
1714 goto file_error;
1715 }
1716 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
1717 if (ret < 0)
1718 goto open_error;
1719 fd_install(file_fd, syscall_list_file);
1720 return file_fd;
1721
1722 open_error:
1723 fput(syscall_list_file);
1724 file_error:
1725 put_unused_fd(file_fd);
1726 fd_error:
1727 return ret;
1728 }
This page took 0.084014 seconds and 5 git commands to generate.