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