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