SoW-2020-0003: Trace Hit Counters
[deliverable/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/utils.h>
33
34 #ifndef CONFIG_COMPAT
35 # ifndef is_compat_task
36 # define is_compat_task() (0)
37 # endif
38 #endif
39
40 /* in_compat_syscall appears in kernel 4.6. */
41 #ifndef in_compat_syscall
42 #define in_compat_syscall() is_compat_task()
43 #endif
44
45 enum sc_type {
46 SC_TYPE_ENTRY,
47 SC_TYPE_EXIT,
48 SC_TYPE_COMPAT_ENTRY,
49 SC_TYPE_COMPAT_EXIT,
50 };
51
52 #define SYSCALL_ENTRY_TOK syscall_entry_
53 #define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
54 #define SYSCALL_EXIT_TOK syscall_exit_
55 #define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
56
57 #define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
58 #define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
59 #define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
60 #define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
61
62 static
63 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
64 static
65 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
66
67 static
68 void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
69 long id);
70 static
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 #define SC_ENTER
121
122 #undef sc_exit
123 #define sc_exit(...)
124 #undef sc_in
125 #define sc_in(...) __VA_ARGS__
126 #undef sc_out
127 #define sc_out(...)
128 #undef sc_inout
129 #define sc_inout(...) __VA_ARGS__
130
131 /* Hijack probe callback for system call enter */
132 #undef TP_PROBE_CB
133 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
134 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
135 LTTNG_TRACEPOINT_EVENT(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
136 PARAMS(_fields))
137 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
138 LTTNG_TRACEPOINT_EVENT_CODE(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
139 PARAMS(_locvar), PARAMS(_code_pre), \
140 PARAMS(_fields), PARAMS(_code_post))
141 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
142 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
143 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
144 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
145 /* Enumerations only defined at first inclusion. */
146 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
147 LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
148 #undef TRACE_SYSTEM
149 #define TRACE_SYSTEM syscall_entry_integers
150 #define TRACE_INCLUDE_FILE syscalls_integers
151 #include <instrumentation/syscalls/headers/syscalls_integers.h>
152 #undef TRACE_INCLUDE_FILE
153 #undef TRACE_SYSTEM
154 #define TRACE_SYSTEM syscall_entry_pointers
155 #define TRACE_INCLUDE_FILE syscalls_pointers
156 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
157 #undef TRACE_INCLUDE_FILE
158 #undef TRACE_SYSTEM
159 #undef SC_LTTNG_TRACEPOINT_ENUM
160 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
161 #undef SC_LTTNG_TRACEPOINT_EVENT
162 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
163 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
164 #undef TP_PROBE_CB
165 #undef _TRACE_SYSCALLS_INTEGERS_H
166 #undef _TRACE_SYSCALLS_POINTERS_H
167
168 /* Hijack probe callback for compat system call enter */
169 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
170 #define LTTNG_SC_COMPAT
171 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
172 LTTNG_TRACEPOINT_EVENT(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
173 PARAMS(_fields))
174 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
175 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
176 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
177 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
178 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_entry_##_name, PARAMS(_fields))
179 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
180 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
181 compat_syscall_entry_##_name)
182 /* Enumerations only defined at inital inclusion (not here). */
183 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
184 #define TRACE_SYSTEM compat_syscall_entry_integers
185 #define TRACE_INCLUDE_FILE compat_syscalls_integers
186 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
187 #undef TRACE_INCLUDE_FILE
188 #undef TRACE_SYSTEM
189 #define TRACE_SYSTEM compat_syscall_entry_pointers
190 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
191 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
192 #undef TRACE_INCLUDE_FILE
193 #undef TRACE_SYSTEM
194 #undef SC_LTTNG_TRACEPOINT_ENUM
195 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
196 #undef SC_LTTNG_TRACEPOINT_EVENT
197 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
198 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
199 #undef TP_PROBE_CB
200 #undef _TRACE_SYSCALLS_INTEGERS_H
201 #undef _TRACE_SYSCALLS_POINTERS_H
202 #undef LTTNG_SC_COMPAT
203
204 #undef SC_ENTER
205
206 #define SC_EXIT
207
208 #undef sc_exit
209 #define sc_exit(...) __VA_ARGS__
210 #undef sc_in
211 #define sc_in(...)
212 #undef sc_out
213 #define sc_out(...) __VA_ARGS__
214 #undef sc_inout
215 #define sc_inout(...) __VA_ARGS__
216
217 /* Hijack probe callback for system call exit */
218 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
219 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
220 LTTNG_TRACEPOINT_EVENT(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
221 PARAMS(_fields))
222 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
223 LTTNG_TRACEPOINT_EVENT_CODE(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
224 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
225 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
226 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_exit_##_name, PARAMS(_fields))
227 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
228 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \
229 syscall_exit_##_name)
230 /* Enumerations only defined at inital inclusion (not here). */
231 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
232 #define TRACE_SYSTEM syscall_exit_integers
233 #define TRACE_INCLUDE_FILE syscalls_integers
234 #include <instrumentation/syscalls/headers/syscalls_integers.h>
235 #undef TRACE_INCLUDE_FILE
236 #undef TRACE_SYSTEM
237 #define TRACE_SYSTEM syscall_exit_pointers
238 #define TRACE_INCLUDE_FILE syscalls_pointers
239 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
240 #undef TRACE_INCLUDE_FILE
241 #undef TRACE_SYSTEM
242 #undef SC_LTTNG_TRACEPOINT_ENUM
243 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
244 #undef SC_LTTNG_TRACEPOINT_EVENT
245 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
246 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
247 #undef TP_PROBE_CB
248 #undef _TRACE_SYSCALLS_INTEGERS_H
249 #undef _TRACE_SYSCALLS_POINTERS_H
250
251
252 /* Hijack probe callback for compat system call exit */
253 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
254 #define LTTNG_SC_COMPAT
255 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
256 LTTNG_TRACEPOINT_EVENT(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
257 PARAMS(_fields))
258 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
259 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
260 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
261 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
262 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_exit_##_name, PARAMS(_fields))
263 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
264 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
265 compat_syscall_exit_##_name)
266 /* Enumerations only defined at inital inclusion (not here). */
267 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
268 #define TRACE_SYSTEM compat_syscall_exit_integers
269 #define TRACE_INCLUDE_FILE compat_syscalls_integers
270 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
271 #undef TRACE_INCLUDE_FILE
272 #undef TRACE_SYSTEM
273 #define TRACE_SYSTEM compat_syscall_exit_pointers
274 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
275 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
276 #undef TRACE_INCLUDE_FILE
277 #undef TRACE_SYSTEM
278 #undef SC_LTTNG_TRACEPOINT_ENUM
279 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
280 #undef SC_LTTNG_TRACEPOINT_EVENT
281 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
282 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
283 #undef TP_PROBE_CB
284 #undef _TRACE_SYSCALLS_INTEGERS_H
285 #undef _TRACE_SYSCALLS_POINTERS_H
286 #undef LTTNG_SC_COMPAT
287
288 #undef SC_EXIT
289
290 #undef TP_MODULE_NOINIT
291 #undef LTTNG_PACKAGE_BUILD
292 #undef CREATE_TRACE_POINTS
293
294 struct trace_syscall_entry {
295 void *event_func;
296 void *event_notifier_func;
297 const struct lttng_event_desc *desc;
298 const struct lttng_event_field *fields;
299 unsigned int nrargs;
300 };
301
302 #define CREATE_SYSCALL_TABLE
303
304 #define SC_ENTER
305
306 #undef sc_exit
307 #define sc_exit(...)
308
309 #undef TRACE_SYSCALL_TABLE
310 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
311 [ _nr ] = { \
312 .event_func = __event_probe__syscall_entry_##_template, \
313 .event_notifier_func = __event_notifier_probe__syscall_entry_##_template, \
314 .nrargs = (_nrargs), \
315 .fields = __event_fields___syscall_entry_##_template, \
316 .desc = &__event_desc___syscall_entry_##_name, \
317 },
318
319 /* Event syscall enter tracing table */
320 static const struct trace_syscall_entry sc_table[] = {
321 #include <instrumentation/syscalls/headers/syscalls_integers.h>
322 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
323 };
324
325 #undef TRACE_SYSCALL_TABLE
326 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
327 [ _nr ] = { \
328 .event_func = __event_probe__compat_syscall_entry_##_template, \
329 .event_notifier_func = __event_notifier_probe__compat_syscall_entry_##_template, \
330 .nrargs = (_nrargs), \
331 .fields = __event_fields___compat_syscall_entry_##_template, \
332 .desc = &__event_desc___compat_syscall_entry_##_name, \
333 },
334
335 /* Event compat syscall enter table */
336 const struct trace_syscall_entry compat_sc_table[] = {
337 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
338 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
339 };
340
341 #undef SC_ENTER
342
343 #define SC_EXIT
344
345 #undef sc_exit
346 #define sc_exit(...) __VA_ARGS__
347
348 #undef TRACE_SYSCALL_TABLE
349 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
350 [ _nr ] = { \
351 .event_func = __event_probe__syscall_exit_##_template, \
352 .event_notifier_func = __event_notifier_probe__syscall_exit_##_template, \
353 .nrargs = (_nrargs), \
354 .fields = __event_fields___syscall_exit_##_template, \
355 .desc = &__event_desc___syscall_exit_##_name, \
356 },
357
358 /* Event syscall exit table */
359 static const struct trace_syscall_entry sc_exit_table[] = {
360 #include <instrumentation/syscalls/headers/syscalls_integers.h>
361 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
362 };
363
364 #undef TRACE_SYSCALL_TABLE
365 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
366 [ _nr ] = { \
367 .event_func = __event_probe__compat_syscall_exit_##_template, \
368 .event_notifier_func = __event_notifier_probe__compat_syscall_exit_##_template, \
369 .nrargs = (_nrargs), \
370 .fields = __event_fields___compat_syscall_exit_##_template, \
371 .desc = &__event_desc___compat_syscall_exit_##_name, \
372 },
373
374 /* Event compat syscall exit table */
375 const struct trace_syscall_entry compat_sc_exit_table[] = {
376 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
377 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
378 };
379
380 #undef SC_EXIT
381
382 #undef CREATE_SYSCALL_TABLE
383
384 struct lttng_syscall_filter {
385 DECLARE_BITMAP(sc_entry, NR_syscalls);
386 DECLARE_BITMAP(sc_exit, NR_syscalls);
387 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
388 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
389 };
390
391 static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
392 struct pt_regs *regs, long id)
393 {
394 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
395 struct lttng_event *event;
396
397 lttng_syscall_get_arguments(current, regs, args);
398 lttng_hlist_for_each_entry_rcu(event, unknown_action_list_head, u.syscall.node) {
399 if (unlikely(in_compat_syscall()))
400 __event_probe__compat_syscall_entry_unknown(event, id, args);
401 else
402 __event_probe__syscall_entry_unknown(event, id, args);
403 }
404 }
405
406 static void syscall_entry_event_notifier_unknown(
407 struct hlist_head *unknown_dispatch_list_head,
408 struct pt_regs *regs, long id)
409 {
410 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
411 struct lttng_event_notifier *notifier;
412
413 lttng_syscall_get_arguments(current, regs, args);
414 lttng_hlist_for_each_entry_rcu(notifier, unknown_dispatch_list_head, u.syscall.node) {
415 if (unlikely(in_compat_syscall()))
416 __event_notifier_probe__compat_syscall_entry_unknown(notifier, id, args);
417 else
418 __event_notifier_probe__syscall_entry_unknown(notifier, id, args);
419 }
420 }
421
422 static void syscall_exit_event_notifier_unknown(
423 struct hlist_head *unknown_dispatch_list_head,
424 struct pt_regs *regs, long id, long ret)
425 {
426 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
427 struct lttng_event_notifier *notifier;
428
429 lttng_syscall_get_arguments(current, regs, args);
430 lttng_hlist_for_each_entry_rcu(notifier, unknown_dispatch_list_head, u.syscall.node) {
431 if (unlikely(in_compat_syscall()))
432 __event_notifier_probe__compat_syscall_exit_unknown(notifier, id, ret, args);
433 else
434 __event_notifier_probe__syscall_exit_unknown(notifier, id, ret, args);
435 }
436 }
437
438 static __always_inline
439 void syscall_entry_call_func(struct hlist_head *action_list,
440 void *func, unsigned int nrargs,
441 struct pt_regs *regs)
442 {
443 struct lttng_event *event;
444
445 switch (nrargs) {
446 case 0:
447 {
448 void (*fptr)(void *__data) = func;
449
450 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
451 fptr(event);
452 break;
453 }
454 case 1:
455 {
456 void (*fptr)(void *__data, unsigned long arg0) = 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, action_list, u.syscall.node)
461 fptr(event, args[0]);
462 break;
463 }
464 case 2:
465 {
466 void (*fptr)(void *__data,
467 unsigned long arg0,
468 unsigned long arg1) = func;
469 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
470
471 lttng_syscall_get_arguments(current, regs, args);
472 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
473 fptr(event, args[0], args[1]);
474 break;
475 }
476 case 3:
477 {
478 void (*fptr)(void *__data,
479 unsigned long arg0,
480 unsigned long arg1,
481 unsigned long arg2) = func;
482 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
483
484 lttng_syscall_get_arguments(current, regs, args);
485 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
486 fptr(event, args[0], args[1], args[2]);
487 break;
488 }
489 case 4:
490 {
491 void (*fptr)(void *__data,
492 unsigned long arg0,
493 unsigned long arg1,
494 unsigned long arg2,
495 unsigned long arg3) = func;
496 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
497
498 lttng_syscall_get_arguments(current, regs, args);
499 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
500 fptr(event, args[0], args[1], args[2], args[3]);
501 break;
502 }
503 case 5:
504 {
505 void (*fptr)(void *__data,
506 unsigned long arg0,
507 unsigned long arg1,
508 unsigned long arg2,
509 unsigned long arg3,
510 unsigned long arg4) = func;
511 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
512
513 lttng_syscall_get_arguments(current, regs, args);
514 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
515 fptr(event, args[0], args[1], args[2], args[3], args[4]);
516 break;
517 }
518 case 6:
519 {
520 void (*fptr)(void *__data,
521 unsigned long arg0,
522 unsigned long arg1,
523 unsigned long arg2,
524 unsigned long arg3,
525 unsigned long arg4,
526 unsigned long arg5) = func;
527 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
528
529 lttng_syscall_get_arguments(current, regs, args);
530 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
531 fptr(event, args[0], args[1], args[2],
532 args[3], args[4], args[5]);
533 break;
534 }
535 default:
536 break;
537 }
538 }
539
540 static __always_inline
541 void syscall_entry_event_notifier_call_func(struct hlist_head *dispatch_list,
542 void *func, unsigned int nrargs, struct pt_regs *regs)
543 {
544 struct lttng_event_notifier *notifier;
545
546 switch (nrargs) {
547 case 0:
548 {
549 void (*fptr)(void *__data) = func;
550
551 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
552 fptr(notifier);
553 break;
554 }
555 case 1:
556 {
557 void (*fptr)(void *__data, unsigned long arg0) = func;
558 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
559
560 lttng_syscall_get_arguments(current, regs, args);
561 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
562 fptr(notifier, args[0]);
563 break;
564 }
565 case 2:
566 {
567 void (*fptr)(void *__data,
568 unsigned long arg0,
569 unsigned long arg1) = func;
570 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
571
572 lttng_syscall_get_arguments(current, regs, args);
573 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
574 fptr(notifier, args[0], args[1]);
575 break;
576 }
577 case 3:
578 {
579 void (*fptr)(void *__data,
580 unsigned long arg0,
581 unsigned long arg1,
582 unsigned long arg2) = func;
583 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
584
585 lttng_syscall_get_arguments(current, regs, args);
586 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
587 fptr(notifier, args[0], args[1], args[2]);
588 break;
589 }
590 case 4:
591 {
592 void (*fptr)(void *__data,
593 unsigned long arg0,
594 unsigned long arg1,
595 unsigned long arg2,
596 unsigned long arg3) = func;
597 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
598
599 lttng_syscall_get_arguments(current, regs, args);
600 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
601 fptr(notifier, args[0], args[1], args[2], args[3]);
602 break;
603 }
604 case 5:
605 {
606 void (*fptr)(void *__data,
607 unsigned long arg0,
608 unsigned long arg1,
609 unsigned long arg2,
610 unsigned long arg3,
611 unsigned long arg4) = func;
612 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
613
614 lttng_syscall_get_arguments(current, regs, args);
615 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
616 fptr(notifier, args[0], args[1], args[2], args[3], args[4]);
617 break;
618 }
619 case 6:
620 {
621 void (*fptr)(void *__data,
622 unsigned long arg0,
623 unsigned long arg1,
624 unsigned long arg2,
625 unsigned long arg3,
626 unsigned long arg4,
627 unsigned long arg5) = func;
628 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
629
630 lttng_syscall_get_arguments(current, regs, args);
631 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
632 fptr(notifier, args[0], args[1], args[2], args[3], args[4], args[5]);
633 break;
634 }
635 default:
636 break;
637 }
638 }
639
640 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
641 {
642 struct lttng_event_container *container = __data;
643 struct hlist_head *action_list, *unknown_action_list;
644 const struct trace_syscall_entry *table, *entry;
645 size_t table_len;
646
647 if (unlikely(in_compat_syscall())) {
648 struct lttng_syscall_filter *filter = container->sc_filter;
649
650 if (id < 0 || id >= NR_compat_syscalls
651 || (!READ_ONCE(container->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
652 /* System call filtered out. */
653 return;
654 }
655 table = compat_sc_table;
656 table_len = ARRAY_SIZE(compat_sc_table);
657 unknown_action_list = &container->sc_compat_unknown;
658 } else {
659 struct lttng_syscall_filter *filter = container->sc_filter;
660
661 if (id < 0 || id >= NR_syscalls
662 || (!READ_ONCE(container->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
663 /* System call filtered out. */
664 return;
665 }
666 table = sc_table;
667 table_len = ARRAY_SIZE(sc_table);
668 unknown_action_list = &container->sc_unknown;
669 }
670 if (unlikely(id < 0 || id >= table_len)) {
671 syscall_entry_event_unknown(unknown_action_list, regs, id);
672 return;
673 }
674
675 entry = &table[id];
676 if (!entry->event_func) {
677 syscall_entry_event_unknown(unknown_action_list, regs, id);
678 return;
679 }
680
681 if (unlikely(in_compat_syscall())) {
682 action_list = &container->compat_sc_table[id];
683 } else {
684 action_list = &container->sc_table[id];
685 }
686 if (unlikely(hlist_empty(action_list)))
687 return;
688
689 syscall_entry_call_func(action_list, entry->event_func, entry->nrargs, regs);
690 }
691
692 void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
693 long id)
694 {
695 struct lttng_event_notifier_group *group = __data;
696 const struct trace_syscall_entry *table, *entry;
697 struct hlist_head *dispatch_list, *unknown_dispatch_list;
698 size_t table_len;
699
700 if (unlikely(in_compat_syscall())) {
701 struct lttng_syscall_filter *filter = group->sc_filter;
702
703 if (id < 0 || id >= NR_compat_syscalls
704 || (!READ_ONCE(group->syscall_all_entry) &&
705 !test_bit(id, filter->sc_compat_entry))) {
706 /* System call filtered out. */
707 return;
708 }
709 table = compat_sc_table;
710 table_len = ARRAY_SIZE(compat_sc_table);
711 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
712 } else {
713 struct lttng_syscall_filter *filter = group->sc_filter;
714
715 if (id < 0 || id >= NR_syscalls
716 || (!READ_ONCE(group->syscall_all_entry) &&
717 !test_bit(id, filter->sc_entry))) {
718 /* System call filtered out. */
719 return;
720 }
721 table = sc_table;
722 table_len = ARRAY_SIZE(sc_table);
723 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
724 }
725 /* Check if the syscall id is out of bound. */
726 if (unlikely(id < 0 || id >= table_len)) {
727 syscall_entry_event_notifier_unknown(unknown_dispatch_list,
728 regs, id);
729 return;
730 }
731
732 entry = &table[id];
733 if (!entry->event_notifier_func) {
734 syscall_entry_event_notifier_unknown(unknown_dispatch_list,
735 regs, id);
736 return;
737 }
738
739 if (unlikely(in_compat_syscall())) {
740 dispatch_list = &group->event_notifier_compat_syscall_dispatch[id];
741 } else {
742 dispatch_list = &group->event_notifier_syscall_dispatch[id];
743 }
744 if (unlikely(hlist_empty(dispatch_list)))
745 return;
746
747 syscall_entry_event_notifier_call_func(dispatch_list,
748 entry->event_notifier_func, entry->nrargs, regs);
749 }
750
751 static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
752 struct pt_regs *regs, long id, long ret)
753 {
754 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
755 struct lttng_event *event;
756
757 lttng_syscall_get_arguments(current, regs, args);
758 lttng_hlist_for_each_entry_rcu(event, unknown_action_list_head, u.syscall.node) {
759 if (unlikely(in_compat_syscall()))
760 __event_probe__compat_syscall_exit_unknown(event, id, ret,
761 args);
762 else
763 __event_probe__syscall_exit_unknown(event, id, ret, args);
764 }
765 }
766
767 static __always_inline
768 void syscall_exit_call_func(struct hlist_head *action_list,
769 void *func, unsigned int nrargs,
770 struct pt_regs *regs, long ret)
771 {
772 struct lttng_event *event;
773
774 switch (nrargs) {
775 case 0:
776 {
777 void (*fptr)(void *__data, long ret) = func;
778
779 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
780 fptr(event, ret);
781 break;
782 }
783 case 1:
784 {
785 void (*fptr)(void *__data,
786 long ret,
787 unsigned long arg0) = func;
788 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
789
790 lttng_syscall_get_arguments(current, regs, args);
791 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
792 fptr(event, ret, args[0]);
793 break;
794 }
795 case 2:
796 {
797 void (*fptr)(void *__data,
798 long ret,
799 unsigned long arg0,
800 unsigned long arg1) = func;
801 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
802
803 lttng_syscall_get_arguments(current, regs, args);
804 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
805 fptr(event, ret, args[0], args[1]);
806 break;
807 }
808 case 3:
809 {
810 void (*fptr)(void *__data,
811 long ret,
812 unsigned long arg0,
813 unsigned long arg1,
814 unsigned long arg2) = func;
815 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
816
817 lttng_syscall_get_arguments(current, regs, args);
818 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
819 fptr(event, ret, args[0], args[1], args[2]);
820 break;
821 }
822 case 4:
823 {
824 void (*fptr)(void *__data,
825 long ret,
826 unsigned long arg0,
827 unsigned long arg1,
828 unsigned long arg2,
829 unsigned long arg3) = func;
830 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
831
832 lttng_syscall_get_arguments(current, regs, args);
833 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
834 fptr(event, ret, args[0], args[1], args[2], args[3]);
835 break;
836 }
837 case 5:
838 {
839 void (*fptr)(void *__data,
840 long ret,
841 unsigned long arg0,
842 unsigned long arg1,
843 unsigned long arg2,
844 unsigned long arg3,
845 unsigned long arg4) = func;
846 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
847
848 lttng_syscall_get_arguments(current, regs, args);
849 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
850 fptr(event, ret, args[0], args[1], args[2], args[3], args[4]);
851 break;
852 }
853 case 6:
854 {
855 void (*fptr)(void *__data,
856 long ret,
857 unsigned long arg0,
858 unsigned long arg1,
859 unsigned long arg2,
860 unsigned long arg3,
861 unsigned long arg4,
862 unsigned long arg5) = func;
863 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
864
865 lttng_syscall_get_arguments(current, regs, args);
866 lttng_hlist_for_each_entry_rcu(event, action_list, u.syscall.node)
867 fptr(event, ret, args[0], args[1], args[2],
868 args[3], args[4], args[5]);
869 break;
870 }
871 default:
872 break;
873 }
874 }
875
876 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
877 {
878 struct lttng_event_container *container = __data;
879 struct hlist_head *action_list, *unknown_action_list;
880 const struct trace_syscall_entry *table, *entry;
881 size_t table_len;
882 long id;
883
884 id = syscall_get_nr(current, regs);
885
886 if (unlikely(in_compat_syscall())) {
887 struct lttng_syscall_filter *filter = container->sc_filter;
888
889 if (id < 0 || id >= NR_compat_syscalls
890 || (!READ_ONCE(container->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
891 /* System call filtered out. */
892 return;
893 }
894 table = compat_sc_exit_table;
895 table_len = ARRAY_SIZE(compat_sc_exit_table);
896 unknown_action_list = &container->compat_sc_exit_unknown;
897 } else {
898 struct lttng_syscall_filter *filter = container->sc_filter;
899
900 if (id < 0 || id >= NR_syscalls
901 || (!READ_ONCE(container->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
902 /* System call filtered out. */
903 return;
904 }
905 table = sc_exit_table;
906 table_len = ARRAY_SIZE(sc_exit_table);
907 unknown_action_list = &container->sc_exit_unknown;
908 }
909 if (unlikely(id < 0 || id >= table_len)) {
910 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
911 return;
912 }
913
914 entry = &table[id];
915 if (!entry->event_func) {
916 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
917 return;
918 }
919
920 if (unlikely(in_compat_syscall())) {
921 action_list = &container->compat_sc_exit_table[id];
922 } else {
923 action_list = &container->sc_exit_table[id];
924 }
925 if (unlikely(hlist_empty(action_list)))
926 return;
927
928 syscall_exit_call_func(action_list, entry->event_func, entry->nrargs,
929 regs, ret);
930 }
931
932 static __always_inline
933 void syscall_exit_event_notifier_call_func(struct hlist_head *dispatch_list,
934 void *func, unsigned int nrargs, struct pt_regs *regs, long ret)
935 {
936 struct lttng_event_notifier *notifier;
937
938 switch (nrargs) {
939 case 0:
940 {
941 void (*fptr)(void *__data, long ret) = func;
942
943 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
944 fptr(notifier, ret);
945 break;
946 }
947 case 1:
948 {
949 void (*fptr)(void *__data, long ret, unsigned long arg0) = func;
950 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
951
952 lttng_syscall_get_arguments(current, regs, args);
953 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
954 fptr(notifier, ret, args[0]);
955 break;
956 }
957 case 2:
958 {
959 void (*fptr)(void *__data,
960 long ret,
961 unsigned long arg0,
962 unsigned long arg1) = func;
963 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
964
965 lttng_syscall_get_arguments(current, regs, args);
966 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
967 fptr(notifier, ret, args[0], args[1]);
968 break;
969 }
970 case 3:
971 {
972 void (*fptr)(void *__data,
973 long ret,
974 unsigned long arg0,
975 unsigned long arg1,
976 unsigned long arg2) = func;
977 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
978
979 lttng_syscall_get_arguments(current, regs, args);
980 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
981 fptr(notifier, ret, args[0], args[1], args[2]);
982 break;
983 }
984 case 4:
985 {
986 void (*fptr)(void *__data,
987 long ret,
988 unsigned long arg0,
989 unsigned long arg1,
990 unsigned long arg2,
991 unsigned long arg3) = func;
992 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
993
994 lttng_syscall_get_arguments(current, regs, args);
995 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
996 fptr(notifier, ret, args[0], args[1], args[2], args[3]);
997 break;
998 }
999 case 5:
1000 {
1001 void (*fptr)(void *__data,
1002 long ret,
1003 unsigned long arg0,
1004 unsigned long arg1,
1005 unsigned long arg2,
1006 unsigned long arg3,
1007 unsigned long arg4) = func;
1008 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1009
1010 lttng_syscall_get_arguments(current, regs, args);
1011 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
1012 fptr(notifier, ret, args[0], args[1], args[2], args[3], args[4]);
1013 break;
1014 }
1015 case 6:
1016 {
1017 void (*fptr)(void *__data,
1018 long ret,
1019 unsigned long arg0,
1020 unsigned long arg1,
1021 unsigned long arg2,
1022 unsigned long arg3,
1023 unsigned long arg4,
1024 unsigned long arg5) = func;
1025 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1026
1027 lttng_syscall_get_arguments(current, regs, args);
1028 lttng_hlist_for_each_entry_rcu(notifier, dispatch_list, u.syscall.node)
1029 fptr(notifier, ret, args[0], args[1], args[2], args[3], args[4], args[5]);
1030 break;
1031 }
1032 default:
1033 break;
1034 }
1035 }
1036
1037 static
1038 void syscall_exit_event_notifier_probe(void *__data, struct pt_regs *regs,
1039 long ret)
1040 {
1041 struct lttng_event_notifier_group *group = __data;
1042 const struct trace_syscall_entry *table, *entry;
1043 struct hlist_head *dispatch_list, *unknown_dispatch_list;
1044 size_t table_len;
1045 long id;
1046
1047 id = syscall_get_nr(current, regs);
1048
1049 if (unlikely(in_compat_syscall())) {
1050 struct lttng_syscall_filter *filter = group->sc_filter;
1051
1052 if (id < 0 || id >= NR_compat_syscalls
1053 || (!READ_ONCE(group->syscall_all_exit) &&
1054 !test_bit(id, filter->sc_compat_exit))) {
1055 /* System call filtered out. */
1056 return;
1057 }
1058 table = compat_sc_exit_table;
1059 table_len = ARRAY_SIZE(compat_sc_exit_table);
1060 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
1061 } else {
1062 struct lttng_syscall_filter *filter = group->sc_filter;
1063
1064 if (id < 0 || id >= NR_syscalls
1065 || (!READ_ONCE(group->syscall_all_exit) &&
1066 !test_bit(id, filter->sc_exit))) {
1067 /* System call filtered out. */
1068 return;
1069 }
1070 table = sc_exit_table;
1071 table_len = ARRAY_SIZE(sc_exit_table);
1072 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
1073 }
1074 /* Check if the syscall id is out of bound. */
1075 if (unlikely(id < 0 || id >= table_len)) {
1076 syscall_exit_event_notifier_unknown(unknown_dispatch_list,
1077 regs, id, ret);
1078 return;
1079 }
1080
1081 entry = &table[id];
1082 if (!entry->event_notifier_func) {
1083 syscall_entry_event_notifier_unknown(unknown_dispatch_list,
1084 regs, id);
1085 return;
1086 }
1087
1088 if (unlikely(in_compat_syscall())) {
1089 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[id];
1090 } else {
1091 dispatch_list = &group->event_notifier_exit_syscall_dispatch[id];
1092 }
1093 if (unlikely(hlist_empty(dispatch_list)))
1094 return;
1095
1096 syscall_exit_event_notifier_call_func(dispatch_list,
1097 entry->event_notifier_func, entry->nrargs, regs, ret);
1098 }
1099 /*
1100 * noinline to diminish caller stack size.
1101 * Should be called with sessions lock held.
1102 */
1103 static
1104 int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *table, size_t table_len,
1105 struct hlist_head *container_table, struct lttng_event_enabler *event_enabler,
1106 void *filter, enum sc_type type)
1107 {
1108 struct lttng_event_container *container = event_enabler->container;
1109 unsigned int i;
1110
1111 /* Allocate events for each syscall matching enabler, insert into table */
1112 for (i = 0; i < table_len; i++) {
1113 const struct lttng_event_desc *desc = table[i].desc;
1114 struct lttng_kernel_event ev;
1115 struct lttng_event *event;
1116
1117 if (!desc) {
1118 /* Unknown syscall */
1119 continue;
1120 }
1121 if (lttng_desc_match_enabler(desc,
1122 lttng_event_enabler_as_enabler(event_enabler)) <= 0)
1123 continue;
1124
1125 /* We need to create an event for this syscall/enabler. */
1126 memset(&ev, 0, sizeof(ev));
1127 switch (type) {
1128 case SC_TYPE_ENTRY:
1129 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1130 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1131 break;
1132 case SC_TYPE_EXIT:
1133 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1134 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1135 break;
1136 case SC_TYPE_COMPAT_ENTRY:
1137 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1138 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1139 break;
1140 case SC_TYPE_COMPAT_EXIT:
1141 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1142 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1143 break;
1144 }
1145 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN - 1);
1146 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1147 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
1148 event = _lttng_event_create(container, &ev, &event_enabler->key, filter,
1149 desc, ev.instrumentation,
1150 event_enabler->base.user_token);
1151 /* Skip if event is already found. */
1152 if (IS_ERR(event) && PTR_ERR(event) == -EEXIST)
1153 continue;
1154 if (IS_ERR(event)) {
1155 /*
1156 * If something goes wrong in event registration
1157 * after the first one, we have no choice but to
1158 * leave the previous events in there, until
1159 * deleted by session teardown.
1160 */
1161 return PTR_ERR(event);
1162 }
1163 hlist_add_head(&event->u.syscall.node, &container_table[i]);
1164 }
1165 return 0;
1166 }
1167
1168 /*
1169 * Should be called with sessions lock held.
1170 */
1171 int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler, void *filter)
1172 {
1173 struct lttng_event_container *container = event_enabler->container;
1174 struct lttng_kernel_event ev;
1175 int ret;
1176
1177 wrapper_vmalloc_sync_mappings();
1178
1179 if (!container->sc_table) {
1180 /* create syscall table mapping syscall to events */
1181 container->sc_table = kzalloc(sizeof(struct hlist_head)
1182 * ARRAY_SIZE(sc_table), GFP_KERNEL);
1183 if (!container->sc_table)
1184 return -ENOMEM;
1185 }
1186 if (!container->sc_exit_table) {
1187 /* create syscall table mapping syscall to events */
1188 container->sc_exit_table = kzalloc(sizeof(struct hlist_head)
1189 * ARRAY_SIZE(sc_exit_table), GFP_KERNEL);
1190 if (!container->sc_exit_table)
1191 return -ENOMEM;
1192 }
1193
1194 #ifdef CONFIG_COMPAT
1195 if (!container->compat_sc_table) {
1196 /* create syscall table mapping compat syscall to events */
1197 container->compat_sc_table = kzalloc(sizeof(struct hlist_head)
1198 * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
1199 if (!container->compat_sc_table)
1200 return -ENOMEM;
1201 }
1202
1203 if (!container->compat_sc_exit_table) {
1204 /* create syscall table mapping compat syscall to events */
1205 container->compat_sc_exit_table = kzalloc(sizeof(struct hlist_head)
1206 * ARRAY_SIZE(compat_sc_exit_table), GFP_KERNEL);
1207 if (!container->compat_sc_exit_table)
1208 return -ENOMEM;
1209 }
1210 #endif
1211
1212 {
1213 const struct lttng_event_desc *desc =
1214 &__event_desc___syscall_entry_unknown;
1215 struct lttng_event *event;
1216
1217 memset(&ev, 0, sizeof(ev));
1218 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
1219 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1220 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
1221 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1222 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1223 event = _lttng_event_create(container, &ev, &event_enabler->key, filter,
1224 desc, ev.instrumentation,
1225 event_enabler->base.user_token);
1226 if (IS_ERR(event)) {
1227 if (PTR_ERR(event) != -EEXIST)
1228 return PTR_ERR(event);
1229 /* Skip if event is already found. */
1230 } else {
1231 hlist_add_head(&event->u.syscall.node, &container->sc_unknown);
1232 }
1233 }
1234
1235 {
1236 const struct lttng_event_desc *desc =
1237 &__event_desc___compat_syscall_entry_unknown;
1238 struct lttng_event *event;
1239
1240 memset(&ev, 0, sizeof(ev));
1241 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
1242 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1243 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
1244 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1245 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1246 event = _lttng_event_create(container, &ev, &event_enabler->key, filter,
1247 desc, ev.instrumentation,
1248 event_enabler->base.user_token);
1249 if (IS_ERR(event)) {
1250 if (PTR_ERR(event) != -EEXIST)
1251 return PTR_ERR(event);
1252 /* Skip if event is already found. */
1253 } else {
1254 hlist_add_head(&event->u.syscall.node, &container->sc_compat_unknown);
1255 }
1256 }
1257
1258 {
1259 const struct lttng_event_desc *desc =
1260 &__event_desc___compat_syscall_exit_unknown;
1261 struct lttng_event *event;
1262
1263 memset(&ev, 0, sizeof(ev));
1264 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
1265 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1266 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
1267 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1268 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1269 event = _lttng_event_create(container, &ev, &event_enabler->key,
1270 filter, desc, ev.instrumentation,
1271 event_enabler->base.user_token);
1272 if (IS_ERR(event)) {
1273 if (PTR_ERR(event) != -EEXIST)
1274 return PTR_ERR(event);
1275 /* Skip if event is already found. */
1276 } else {
1277 hlist_add_head(&event->u.syscall.node, &container->compat_sc_exit_unknown);
1278 }
1279 }
1280
1281 {
1282 const struct lttng_event_desc *desc =
1283 &__event_desc___syscall_exit_unknown;
1284 struct lttng_event *event;
1285
1286 memset(&ev, 0, sizeof(ev));
1287 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
1288 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1289 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
1290 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1291 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1292 event = _lttng_event_create(container, &ev, &event_enabler->key, filter,
1293 desc, ev.instrumentation,
1294 event_enabler->base.user_token);
1295 if (IS_ERR(event)) {
1296 if (PTR_ERR(event) != -EEXIST)
1297 return PTR_ERR(event);
1298 /* Skip if event is already found. */
1299 } else {
1300 hlist_add_head(&event->u.syscall.node, &container->sc_exit_unknown);
1301 }
1302 }
1303
1304 ret = lttng_create_syscall_event_if_missing(sc_table, ARRAY_SIZE(sc_table),
1305 container->sc_table, event_enabler, filter, SC_TYPE_ENTRY);
1306 if (ret)
1307 return ret;
1308 ret = lttng_create_syscall_event_if_missing(sc_exit_table, ARRAY_SIZE(sc_exit_table),
1309 container->sc_exit_table, event_enabler, filter, SC_TYPE_EXIT);
1310 if (ret)
1311 return ret;
1312
1313 #ifdef CONFIG_COMPAT
1314 ret = lttng_create_syscall_event_if_missing(compat_sc_table, ARRAY_SIZE(compat_sc_table),
1315 container->compat_sc_table, event_enabler, filter,
1316 SC_TYPE_COMPAT_ENTRY);
1317 if (ret)
1318 return ret;
1319 ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
1320 container->compat_sc_exit_table, event_enabler, filter,
1321 SC_TYPE_COMPAT_EXIT);
1322 if (ret)
1323 return ret;
1324 #endif
1325
1326 if (!container->sc_filter) {
1327 container->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
1328 GFP_KERNEL);
1329 if (!container->sc_filter)
1330 return -ENOMEM;
1331 }
1332
1333 if (!container->sys_enter_registered) {
1334 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
1335 (void *) syscall_entry_event_probe, container);
1336 if (ret)
1337 return ret;
1338 container->sys_enter_registered = 1;
1339 }
1340 /*
1341 * We change the name of sys_exit tracepoint due to namespace
1342 * conflict with sys_exit syscall entry.
1343 */
1344 if (!container->sys_exit_registered) {
1345 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
1346 (void *) syscall_exit_event_probe, container);
1347 if (ret) {
1348 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1349 (void *) syscall_entry_event_probe, container));
1350 return ret;
1351 }
1352 container->sys_exit_registered = 1;
1353 }
1354 return ret;
1355 }
1356
1357 /*
1358 * Should be called with sessions lock held.
1359 */
1360 int lttng_syscalls_register_event_notifier(
1361 struct lttng_event_notifier_enabler *event_notifier_enabler,
1362 void *filter)
1363 {
1364 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1365 unsigned int i;
1366 int ret = 0;
1367
1368 wrapper_vmalloc_sync_mappings();
1369
1370 if (!group->event_notifier_syscall_dispatch) {
1371 group->event_notifier_syscall_dispatch =
1372 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(sc_table),
1373 GFP_KERNEL);
1374 if (!group->event_notifier_syscall_dispatch)
1375 return -ENOMEM;
1376
1377 /* Initialize all list_head */
1378 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1379 INIT_HLIST_HEAD(&group->event_notifier_syscall_dispatch[i]);
1380
1381 /* Init the unknown syscall notifier list. */
1382 INIT_HLIST_HEAD(&group->event_notifier_unknown_syscall_dispatch);
1383 }
1384
1385 if (!group->event_notifier_exit_syscall_dispatch) {
1386 group->event_notifier_exit_syscall_dispatch =
1387 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(sc_table),
1388 GFP_KERNEL);
1389 if (!group->event_notifier_exit_syscall_dispatch)
1390 return -ENOMEM;
1391
1392 /* Initialize all list_head */
1393 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1394 INIT_HLIST_HEAD(&group->event_notifier_exit_syscall_dispatch[i]);
1395
1396 /* Init the unknown exit syscall notifier list. */
1397 INIT_HLIST_HEAD(&group->event_notifier_exit_unknown_syscall_dispatch);
1398 }
1399
1400 #ifdef CONFIG_COMPAT
1401 if (!group->event_notifier_compat_syscall_dispatch) {
1402 group->event_notifier_compat_syscall_dispatch =
1403 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(compat_sc_table),
1404 GFP_KERNEL);
1405 if (!group->event_notifier_syscall_dispatch)
1406 return -ENOMEM;
1407
1408 /* Initialize all list_head */
1409 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++)
1410 INIT_HLIST_HEAD(&group->event_notifier_compat_syscall_dispatch[i]);
1411
1412 /* Init the unknown syscall notifier list. */
1413 INIT_HLIST_HEAD(&group->event_notifier_compat_unknown_syscall_dispatch);
1414 }
1415
1416 if (!group->event_notifier_exit_compat_syscall_dispatch) {
1417 group->event_notifier_exit_compat_syscall_dispatch =
1418 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(compat_sc_exit_table),
1419 GFP_KERNEL);
1420 if (!group->event_notifier_exit_syscall_dispatch)
1421 return -ENOMEM;
1422
1423 /* Initialize all list_head */
1424 for (i = 0; i < ARRAY_SIZE(compat_sc_exit_table); i++)
1425 INIT_HLIST_HEAD(&group->event_notifier_exit_compat_syscall_dispatch[i]);
1426
1427 /* Init the unknown exit syscall notifier list. */
1428 INIT_HLIST_HEAD(&group->event_notifier_exit_compat_unknown_syscall_dispatch);
1429 }
1430 #endif
1431
1432 if (!group->sc_filter) {
1433 group->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
1434 GFP_KERNEL);
1435 if (!group->sc_filter)
1436 return -ENOMEM;
1437 }
1438
1439 if (!group->sys_enter_registered) {
1440 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
1441 (void *) syscall_entry_event_notifier_probe, group);
1442 if (ret)
1443 return ret;
1444 group->sys_enter_registered = 1;
1445 }
1446
1447 if (!group->sys_exit_registered) {
1448 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
1449 (void *) syscall_exit_event_notifier_probe, group);
1450 if (ret) {
1451 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1452 (void *) syscall_entry_event_notifier_probe, group));
1453 return ret;
1454 }
1455 group->sys_exit_registered = 1;
1456 }
1457
1458 return ret;
1459 }
1460
1461 static
1462 int create_unknown_event_notifier(
1463 struct lttng_event_notifier_enabler *event_notifier_enabler,
1464 enum sc_type type)
1465 {
1466 struct lttng_event_notifier *notifier;
1467 const struct lttng_event_desc *desc;
1468 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1469 struct lttng_kernel_event_notifier event_notifier_param;
1470 uint64_t user_token = event_notifier_enabler->base.user_token;
1471 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
1472 struct lttng_enabler *base_enabler = lttng_event_notifier_enabler_as_enabler(
1473 event_notifier_enabler);
1474 struct hlist_head *unknown_dispatch_list;
1475 int ret = 0;
1476 bool found = false;
1477 enum lttng_kernel_syscall_abi abi;
1478 enum lttng_kernel_syscall_entryexit entryexit;
1479 struct hlist_head *head;
1480
1481 switch (type) {
1482 case SC_TYPE_ENTRY:
1483 desc = &__event_desc___syscall_entry_unknown;
1484 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
1485 entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1486 abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1487 break;
1488 case SC_TYPE_EXIT:
1489 desc = &__event_desc___syscall_exit_unknown;
1490 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
1491 entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1492 abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1493 break;
1494 case SC_TYPE_COMPAT_ENTRY:
1495 desc = &__event_desc___compat_syscall_entry_unknown;
1496 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
1497 entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1498 abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1499 break;
1500 case SC_TYPE_COMPAT_EXIT:
1501 desc = &__event_desc___compat_syscall_exit_unknown;
1502 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
1503 entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1504 abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1505 break;
1506 default:
1507 BUG_ON(1);
1508 }
1509
1510 /*
1511 * Check if already created.
1512 */
1513 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
1514 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->name);
1515 lttng_hlist_for_each_entry(notifier, head, hlist) {
1516 if (notifier->desc == desc &&
1517 notifier->user_token == base_enabler->user_token)
1518 found = true;
1519 }
1520 if (found)
1521 goto end;
1522
1523 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1524 strncat(event_notifier_param.event.name, desc->name,
1525 LTTNG_KERNEL_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1526
1527 event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1528
1529 event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL;
1530 event_notifier_param.event.u.syscall.abi = abi;
1531 event_notifier_param.event.u.syscall.entryexit = entryexit;
1532
1533 notifier = _lttng_event_notifier_create(desc, user_token,
1534 error_counter_index, group, &event_notifier_param, NULL,
1535 event_notifier_param.event.instrumentation);
1536 if (IS_ERR(notifier)) {
1537 printk(KERN_INFO "Unable to create unknown notifier %s\n",
1538 desc->name);
1539 ret = -ENOMEM;
1540 goto end;
1541 }
1542
1543 hlist_add_head_rcu(&notifier->u.syscall.node, unknown_dispatch_list);
1544
1545 end:
1546 return ret;
1547 }
1548
1549 static int create_matching_event_notifiers(
1550 struct lttng_event_notifier_enabler *event_notifier_enabler,
1551 void *filter, const struct trace_syscall_entry *table,
1552 size_t table_len, enum sc_type type)
1553 {
1554 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1555 const struct lttng_event_desc *desc;
1556 uint64_t user_token = event_notifier_enabler->base.user_token;
1557 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
1558 unsigned int i;
1559 int ret = 0;
1560
1561 /* iterate over all syscall and create event_notifier that match */
1562 for (i = 0; i < table_len; i++) {
1563 struct lttng_event_notifier *event_notifier;
1564 struct lttng_kernel_event_notifier event_notifier_param;
1565 struct hlist_head *head;
1566 int found = 0;
1567
1568 desc = table[i].desc;
1569 if (!desc) {
1570 /* Unknown syscall */
1571 continue;
1572 }
1573
1574 if (lttng_desc_match_enabler(desc,
1575 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)) <= 0)
1576 continue;
1577
1578 /*
1579 * Check if already created.
1580 */
1581 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
1582 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->name);
1583 lttng_hlist_for_each_entry(event_notifier, head, hlist) {
1584 if (event_notifier->desc == desc
1585 && event_notifier->user_token == event_notifier_enabler->base.user_token)
1586 found = 1;
1587 }
1588 if (found)
1589 continue;
1590
1591 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1592 switch (type) {
1593 case SC_TYPE_ENTRY:
1594 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1595 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1596 break;
1597 case SC_TYPE_EXIT:
1598 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1599 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1600 break;
1601 case SC_TYPE_COMPAT_ENTRY:
1602 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1603 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1604 break;
1605 case SC_TYPE_COMPAT_EXIT:
1606 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1607 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1608 break;
1609 }
1610 strncat(event_notifier_param.event.name, desc->name,
1611 LTTNG_KERNEL_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1612 event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1613 event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL;
1614
1615 event_notifier = _lttng_event_notifier_create(desc, user_token,
1616 error_counter_index, group, &event_notifier_param,
1617 filter, event_notifier_param.event.instrumentation);
1618 if (IS_ERR(event_notifier)) {
1619 printk(KERN_INFO "Unable to create event_notifier %s\n",
1620 desc->name);
1621 ret = -ENOMEM;
1622 goto end;
1623 }
1624
1625 event_notifier->u.syscall.syscall_id = i;
1626 }
1627
1628 end:
1629 return ret;
1630 }
1631
1632 int lttng_syscals_create_matching_event_notifiers(
1633 struct lttng_event_notifier_enabler *event_notifier_enabler,
1634 void *filter)
1635 {
1636 int ret;
1637 struct lttng_enabler *base_enabler =
1638 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
1639 enum lttng_kernel_syscall_entryexit entryexit =
1640 base_enabler->event_param.u.syscall.entryexit;
1641
1642 if (entryexit == LTTNG_KERNEL_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_SYSCALL_ENTRYEXIT) {
1643 ret = create_matching_event_notifiers(event_notifier_enabler,
1644 filter, sc_table, ARRAY_SIZE(sc_table), SC_TYPE_ENTRY);
1645 if (ret)
1646 goto end;
1647
1648 ret = create_matching_event_notifiers(event_notifier_enabler,
1649 filter, compat_sc_table, ARRAY_SIZE(compat_sc_table),
1650 SC_TYPE_COMPAT_ENTRY);
1651 if (ret)
1652 goto end;
1653
1654 ret = create_unknown_event_notifier(event_notifier_enabler,
1655 SC_TYPE_ENTRY);
1656 if (ret)
1657 goto end;
1658
1659 ret = create_unknown_event_notifier(event_notifier_enabler,
1660 SC_TYPE_COMPAT_ENTRY);
1661 if (ret)
1662 goto end;
1663 }
1664
1665 if (entryexit == LTTNG_KERNEL_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_SYSCALL_ENTRYEXIT) {
1666 ret = create_matching_event_notifiers(event_notifier_enabler,
1667 filter, sc_exit_table, ARRAY_SIZE(sc_exit_table),
1668 SC_TYPE_EXIT);
1669 if (ret)
1670 goto end;
1671
1672 ret = create_unknown_event_notifier(event_notifier_enabler,
1673 SC_TYPE_EXIT);
1674 if (ret)
1675 goto end;
1676
1677 ret = create_matching_event_notifiers(event_notifier_enabler,
1678 filter, compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
1679 SC_TYPE_COMPAT_EXIT);
1680 if (ret)
1681 goto end;
1682
1683 ret = create_unknown_event_notifier(event_notifier_enabler,
1684 SC_TYPE_COMPAT_EXIT);
1685 if (ret)
1686 goto end;
1687 }
1688
1689 end:
1690 return ret;
1691 }
1692
1693 /*
1694 * Unregister the syscall event_notifier probes from the callsites.
1695 */
1696 int lttng_syscalls_unregister_event_notifier_group(
1697 struct lttng_event_notifier_group *event_notifier_group)
1698 {
1699 int ret;
1700
1701 /*
1702 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1703 * At the moment, we don't think it's desirable to have one fired
1704 * event_notifier for the entry and one for the exit of a syscall.
1705 */
1706 if (event_notifier_group->sys_enter_registered) {
1707 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1708 (void *) syscall_entry_event_notifier_probe, event_notifier_group);
1709 if (ret)
1710 return ret;
1711 event_notifier_group->sys_enter_registered = 0;
1712 }
1713 if (event_notifier_group->sys_exit_registered) {
1714 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1715 (void *) syscall_exit_event_notifier_probe, event_notifier_group);
1716 if (ret)
1717 return ret;
1718 event_notifier_group->sys_enter_registered = 0;
1719 }
1720
1721 kfree(event_notifier_group->event_notifier_syscall_dispatch);
1722 kfree(event_notifier_group->event_notifier_exit_syscall_dispatch);
1723 #ifdef CONFIG_COMPAT
1724 kfree(event_notifier_group->event_notifier_compat_syscall_dispatch);
1725 kfree(event_notifier_group->event_notifier_exit_compat_syscall_dispatch);
1726 #endif
1727 return 0;
1728 }
1729
1730 int lttng_syscalls_unregister_event_container(struct lttng_event_container *container)
1731 {
1732 int ret;
1733
1734 if (!container->sc_table)
1735 return 0;
1736 if (container->sys_enter_registered) {
1737 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1738 (void *) syscall_entry_event_probe, container);
1739 if (ret)
1740 return ret;
1741 container->sys_enter_registered = 0;
1742 }
1743 if (container->sys_exit_registered) {
1744 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1745 (void *) syscall_exit_event_probe, container);
1746 if (ret)
1747 return ret;
1748 container->sys_exit_registered = 0;
1749 }
1750 return 0;
1751 }
1752
1753 int lttng_syscalls_destroy_event_container(struct lttng_event_container *container)
1754 {
1755 kfree(container->sc_table);
1756 kfree(container->sc_exit_table);
1757 #ifdef CONFIG_COMPAT
1758 kfree(container->compat_sc_table);
1759 kfree(container->compat_sc_exit_table);
1760 #endif
1761 kfree(container->sc_filter);
1762 return 0;
1763 }
1764
1765 static
1766 int get_syscall_nr(const char *syscall_name)
1767 {
1768 int syscall_nr = -1;
1769 int i;
1770
1771 for (i = 0; i < ARRAY_SIZE(sc_table); i++) {
1772 const struct trace_syscall_entry *entry;
1773 const char *it_name;
1774
1775 entry = &sc_table[i];
1776 if (!entry->desc)
1777 continue;
1778 it_name = entry->desc->name;
1779 it_name += strlen(SYSCALL_ENTRY_STR);
1780 if (!strcmp(syscall_name, it_name)) {
1781 syscall_nr = i;
1782 break;
1783 }
1784 }
1785 return syscall_nr;
1786 }
1787
1788 static
1789 int get_compat_syscall_nr(const char *syscall_name)
1790 {
1791 int syscall_nr = -1;
1792 int i;
1793
1794 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++) {
1795 const struct trace_syscall_entry *entry;
1796 const char *it_name;
1797
1798 entry = &compat_sc_table[i];
1799 if (!entry->desc)
1800 continue;
1801 it_name = entry->desc->name;
1802 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1803 if (!strcmp(syscall_name, it_name)) {
1804 syscall_nr = i;
1805 break;
1806 }
1807 }
1808 return syscall_nr;
1809 }
1810
1811 static
1812 uint32_t get_sc_tables_len(void)
1813 {
1814 return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table);
1815 }
1816
1817 static
1818 const char *get_syscall_name(const char *desc_name,
1819 enum lttng_syscall_abi abi,
1820 enum lttng_syscall_entryexit entryexit)
1821 {
1822 size_t prefix_len = 0;
1823
1824
1825 switch (entryexit) {
1826 case LTTNG_SYSCALL_ENTRY:
1827 switch (abi) {
1828 case LTTNG_SYSCALL_ABI_NATIVE:
1829 prefix_len = strlen(SYSCALL_ENTRY_STR);
1830 break;
1831 case LTTNG_SYSCALL_ABI_COMPAT:
1832 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1833 break;
1834 }
1835 break;
1836 case LTTNG_SYSCALL_EXIT:
1837 switch (abi) {
1838 case LTTNG_SYSCALL_ABI_NATIVE:
1839 prefix_len = strlen(SYSCALL_EXIT_STR);
1840 break;
1841 case LTTNG_SYSCALL_ABI_COMPAT:
1842 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1843 break;
1844 }
1845 break;
1846 }
1847 WARN_ON_ONCE(prefix_len == 0);
1848 return desc_name + prefix_len;
1849 }
1850
1851 static
1852 int lttng_syscall_filter_enable(
1853 struct lttng_syscall_filter *filter,
1854 const char *desc_name, enum lttng_syscall_abi abi,
1855 enum lttng_syscall_entryexit entryexit)
1856 {
1857 const char *syscall_name;
1858 unsigned long *bitmap;
1859 int syscall_nr;
1860
1861 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1862
1863 switch (abi) {
1864 case LTTNG_SYSCALL_ABI_NATIVE:
1865 syscall_nr = get_syscall_nr(syscall_name);
1866 break;
1867 case LTTNG_SYSCALL_ABI_COMPAT:
1868 syscall_nr = get_compat_syscall_nr(syscall_name);
1869 break;
1870 default:
1871 return -EINVAL;
1872 }
1873 if (syscall_nr < 0)
1874 return -ENOENT;
1875
1876 switch (entryexit) {
1877 case LTTNG_SYSCALL_ENTRY:
1878 switch (abi) {
1879 case LTTNG_SYSCALL_ABI_NATIVE:
1880 bitmap = filter->sc_entry;
1881 break;
1882 case LTTNG_SYSCALL_ABI_COMPAT:
1883 bitmap = filter->sc_compat_entry;
1884 break;
1885 default:
1886 return -EINVAL;
1887 }
1888 break;
1889 case LTTNG_SYSCALL_EXIT:
1890 switch (abi) {
1891 case LTTNG_SYSCALL_ABI_NATIVE:
1892 bitmap = filter->sc_exit;
1893 break;
1894 case LTTNG_SYSCALL_ABI_COMPAT:
1895 bitmap = filter->sc_compat_exit;
1896 break;
1897 default:
1898 return -EINVAL;
1899 }
1900 break;
1901 default:
1902 return -EINVAL;
1903 }
1904 if (test_bit(syscall_nr, bitmap))
1905 return -EEXIST;
1906 bitmap_set(bitmap, syscall_nr, 1);
1907 return 0;
1908 }
1909
1910 int lttng_syscall_filter_enable_event_notifier(
1911 struct lttng_event_notifier *notifier)
1912 {
1913 struct lttng_event_notifier_group *group = notifier->group;
1914 unsigned int syscall_id = notifier->u.syscall.syscall_id;
1915 struct hlist_head *dispatch_list;
1916 int ret = 0;
1917
1918 WARN_ON_ONCE(notifier->instrumentation != LTTNG_KERNEL_SYSCALL);
1919
1920 ret = lttng_syscall_filter_enable(group->sc_filter,
1921 notifier->desc->name, notifier->u.syscall.abi,
1922 notifier->u.syscall.entryexit);
1923 if (ret) {
1924 goto end;
1925 }
1926
1927 switch (notifier->u.syscall.entryexit) {
1928 case LTTNG_SYSCALL_ENTRY:
1929 switch (notifier->u.syscall.abi) {
1930 case LTTNG_SYSCALL_ABI_NATIVE:
1931 dispatch_list = &group->event_notifier_syscall_dispatch[syscall_id];
1932 break;
1933 case LTTNG_SYSCALL_ABI_COMPAT:
1934 dispatch_list = &group->event_notifier_compat_syscall_dispatch[syscall_id];
1935 break;
1936 default:
1937 ret = -EINVAL;
1938 goto end;
1939 }
1940 break;
1941 case LTTNG_SYSCALL_EXIT:
1942 switch (notifier->u.syscall.abi) {
1943 case LTTNG_SYSCALL_ABI_NATIVE:
1944 dispatch_list = &group->event_notifier_exit_syscall_dispatch[syscall_id];
1945 break;
1946 case LTTNG_SYSCALL_ABI_COMPAT:
1947 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[syscall_id];
1948 break;
1949 default:
1950 ret = -EINVAL;
1951 goto end;
1952 }
1953 break;
1954 default:
1955 ret = -EINVAL;
1956 goto end;
1957 }
1958
1959 hlist_add_head_rcu(&notifier->u.syscall.node, dispatch_list);
1960
1961 end:
1962 return ret ;
1963 }
1964
1965 int lttng_syscall_filter_enable_event(
1966 struct lttng_event_container *container,
1967 struct lttng_event *event)
1968 {
1969 WARN_ON_ONCE(event->instrumentation != LTTNG_KERNEL_SYSCALL);
1970
1971 return lttng_syscall_filter_enable(container->sc_filter,
1972 event->desc->name, event->u.syscall.abi,
1973 event->u.syscall.entryexit);
1974 }
1975
1976 static
1977 int lttng_syscall_filter_disable(
1978 struct lttng_syscall_filter *filter,
1979 const char *desc_name, enum lttng_syscall_abi abi,
1980 enum lttng_syscall_entryexit entryexit)
1981 {
1982 const char *syscall_name;
1983 unsigned long *bitmap;
1984 int syscall_nr;
1985
1986 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1987
1988 switch (abi) {
1989 case LTTNG_SYSCALL_ABI_NATIVE:
1990 syscall_nr = get_syscall_nr(syscall_name);
1991 break;
1992 case LTTNG_SYSCALL_ABI_COMPAT:
1993 syscall_nr = get_compat_syscall_nr(syscall_name);
1994 break;
1995 default:
1996 return -EINVAL;
1997 }
1998 if (syscall_nr < 0)
1999 return -ENOENT;
2000
2001 switch (entryexit) {
2002 case LTTNG_SYSCALL_ENTRY:
2003 switch (abi) {
2004 case LTTNG_SYSCALL_ABI_NATIVE:
2005 bitmap = filter->sc_entry;
2006 break;
2007 case LTTNG_SYSCALL_ABI_COMPAT:
2008 bitmap = filter->sc_compat_entry;
2009 break;
2010 default:
2011 return -EINVAL;
2012 }
2013 break;
2014 case LTTNG_SYSCALL_EXIT:
2015 switch (abi) {
2016 case LTTNG_SYSCALL_ABI_NATIVE:
2017 bitmap = filter->sc_exit;
2018 break;
2019 case LTTNG_SYSCALL_ABI_COMPAT:
2020 bitmap = filter->sc_compat_exit;
2021 break;
2022 default:
2023 return -EINVAL;
2024 }
2025 break;
2026 default:
2027 return -EINVAL;
2028 }
2029 if (!test_bit(syscall_nr, bitmap))
2030 return -EEXIST;
2031 bitmap_clear(bitmap, syscall_nr, 1);
2032
2033 return 0;
2034 }
2035
2036 int lttng_syscall_filter_disable_event_notifier(
2037 struct lttng_event_notifier *notifier)
2038 {
2039 struct lttng_event_notifier_group *group = notifier->group;
2040 int ret;
2041
2042 WARN_ON_ONCE(notifier->instrumentation != LTTNG_KERNEL_SYSCALL);
2043
2044 ret = lttng_syscall_filter_disable(group->sc_filter,
2045 notifier->desc->name, notifier->u.syscall.abi,
2046 notifier->u.syscall.entryexit);
2047 WARN_ON_ONCE(ret != 0);
2048
2049 hlist_del_rcu(&notifier->u.syscall.node);
2050 return 0;
2051 }
2052
2053 int lttng_syscall_filter_disable_event(
2054 struct lttng_event_container *container,
2055 struct lttng_event *event)
2056 {
2057 return lttng_syscall_filter_disable(container->sc_filter,
2058 event->desc->name, event->u.syscall.abi,
2059 event->u.syscall.entryexit);
2060 }
2061
2062 static
2063 const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
2064 {
2065 const struct trace_syscall_entry *entry;
2066 int iter = 0;
2067
2068 for (entry = sc_table;
2069 entry < sc_table + ARRAY_SIZE(sc_table);
2070 entry++) {
2071 if (iter++ >= *pos)
2072 return entry;
2073 }
2074 for (entry = compat_sc_table;
2075 entry < compat_sc_table + ARRAY_SIZE(compat_sc_table);
2076 entry++) {
2077 if (iter++ >= *pos)
2078 return entry;
2079 }
2080 /* End of list */
2081 return NULL;
2082 }
2083
2084 static
2085 void *syscall_list_start(struct seq_file *m, loff_t *pos)
2086 {
2087 return (void *) syscall_list_get_entry(pos);
2088 }
2089
2090 static
2091 void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
2092 {
2093 (*ppos)++;
2094 return (void *) syscall_list_get_entry(ppos);
2095 }
2096
2097 static
2098 void syscall_list_stop(struct seq_file *m, void *p)
2099 {
2100 }
2101
2102 static
2103 int get_sc_table(const struct trace_syscall_entry *entry,
2104 const struct trace_syscall_entry **table,
2105 unsigned int *bitness)
2106 {
2107 if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) {
2108 if (bitness)
2109 *bitness = BITS_PER_LONG;
2110 if (table)
2111 *table = sc_table;
2112 return 0;
2113 }
2114 if (!(entry >= compat_sc_table
2115 && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))) {
2116 return -EINVAL;
2117 }
2118 if (bitness)
2119 *bitness = 32;
2120 if (table)
2121 *table = compat_sc_table;
2122 return 0;
2123 }
2124
2125 static
2126 int syscall_list_show(struct seq_file *m, void *p)
2127 {
2128 const struct trace_syscall_entry *table, *entry = p;
2129 unsigned int bitness;
2130 unsigned long index;
2131 int ret;
2132 const char *name;
2133
2134 ret = get_sc_table(entry, &table, &bitness);
2135 if (ret)
2136 return ret;
2137 if (!entry->desc)
2138 return 0;
2139 if (table == sc_table) {
2140 index = entry - table;
2141 name = &entry->desc->name[strlen(SYSCALL_ENTRY_STR)];
2142 } else {
2143 index = (entry - table) + ARRAY_SIZE(sc_table);
2144 name = &entry->desc->name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
2145 }
2146 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
2147 index, name, bitness);
2148 return 0;
2149 }
2150
2151 static
2152 const struct seq_operations lttng_syscall_list_seq_ops = {
2153 .start = syscall_list_start,
2154 .next = syscall_list_next,
2155 .stop = syscall_list_stop,
2156 .show = syscall_list_show,
2157 };
2158
2159 static
2160 int lttng_syscall_list_open(struct inode *inode, struct file *file)
2161 {
2162 return seq_open(file, &lttng_syscall_list_seq_ops);
2163 }
2164
2165 const struct file_operations lttng_syscall_list_fops = {
2166 .owner = THIS_MODULE,
2167 .open = lttng_syscall_list_open,
2168 .read = seq_read,
2169 .llseek = seq_lseek,
2170 .release = seq_release,
2171 };
2172
2173 /*
2174 * A syscall is enabled if it is traced for either entry or exit.
2175 */
2176 long lttng_event_container_syscall_mask(struct lttng_event_container *container,
2177 struct lttng_kernel_syscall_mask __user *usyscall_mask)
2178 {
2179 uint32_t len, sc_tables_len, bitmask_len;
2180 int ret = 0, bit;
2181 char *tmp_mask;
2182 struct lttng_syscall_filter *filter;
2183
2184 ret = get_user(len, &usyscall_mask->len);
2185 if (ret)
2186 return ret;
2187 sc_tables_len = get_sc_tables_len();
2188 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
2189 if (len < sc_tables_len) {
2190 return put_user(sc_tables_len, &usyscall_mask->len);
2191 }
2192 /* Array is large enough, we can copy array to user-space. */
2193 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
2194 if (!tmp_mask)
2195 return -ENOMEM;
2196 filter = container->sc_filter;
2197
2198 for (bit = 0; bit < ARRAY_SIZE(sc_table); bit++) {
2199 char state;
2200
2201 if (container->sc_table) {
2202 if (!(READ_ONCE(container->syscall_all_entry)
2203 || READ_ONCE(container->syscall_all_exit)) && filter)
2204 state = test_bit(bit, filter->sc_entry)
2205 || test_bit(bit, filter->sc_exit);
2206 else
2207 state = 1;
2208 } else {
2209 state = 0;
2210 }
2211 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
2212 }
2213 for (; bit < sc_tables_len; bit++) {
2214 char state;
2215
2216 if (container->compat_sc_table) {
2217 if (!(READ_ONCE(container->syscall_all_entry)
2218 || READ_ONCE(container->syscall_all_exit)) && filter)
2219 state = test_bit(bit - ARRAY_SIZE(sc_table),
2220 filter->sc_compat_entry)
2221 || test_bit(bit - ARRAY_SIZE(sc_table),
2222 filter->sc_compat_exit);
2223 else
2224 state = 1;
2225 } else {
2226 state = 0;
2227 }
2228 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
2229 }
2230 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
2231 ret = -EFAULT;
2232 kfree(tmp_mask);
2233 return ret;
2234 }
2235
2236 int lttng_abi_syscall_list(void)
2237 {
2238 struct file *syscall_list_file;
2239 int file_fd, ret;
2240
2241 file_fd = lttng_get_unused_fd();
2242 if (file_fd < 0) {
2243 ret = file_fd;
2244 goto fd_error;
2245 }
2246
2247 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
2248 &lttng_syscall_list_fops,
2249 NULL, O_RDWR);
2250 if (IS_ERR(syscall_list_file)) {
2251 ret = PTR_ERR(syscall_list_file);
2252 goto file_error;
2253 }
2254 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
2255 if (ret < 0)
2256 goto open_error;
2257 fd_install(file_fd, syscall_list_file);
2258 return file_fd;
2259
2260 open_error:
2261 fput(syscall_list_file);
2262 file_error:
2263 put_unused_fd(file_fd);
2264 fd_error:
2265 return ret;
2266 }
This page took 0.137525 seconds and 5 git commands to generate.