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