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