1465083556c4ca94657deb621cdb95f58b297962
[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 struct lttng_enabler *base_enabler = lttng_event_notifier_enabler_as_enabler(
1406 event_notifier_enabler);
1407 struct hlist_head *unknown_dispatch_list;
1408 int ret = 0;
1409 bool found = false;
1410 enum lttng_kernel_syscall_abi abi;
1411 enum lttng_kernel_syscall_entryexit entryexit;
1412 struct hlist_head *head;
1413
1414 switch (type) {
1415 case SC_TYPE_ENTRY:
1416 desc = &__event_desc___syscall_entry_unknown;
1417 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
1418 entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1419 abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1420 break;
1421 case SC_TYPE_EXIT:
1422 desc = &__event_desc___syscall_exit_unknown;
1423 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
1424 entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1425 abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1426 break;
1427 case SC_TYPE_COMPAT_ENTRY:
1428 desc = &__event_desc___compat_syscall_entry_unknown;
1429 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
1430 entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1431 abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1432 break;
1433 case SC_TYPE_COMPAT_EXIT:
1434 desc = &__event_desc___compat_syscall_exit_unknown;
1435 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
1436 entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1437 abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1438 break;
1439 default:
1440 BUG_ON(1);
1441 }
1442
1443 /*
1444 * Check if already created.
1445 */
1446 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
1447 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->name);
1448 lttng_hlist_for_each_entry(notifier, head, hlist) {
1449 if (notifier->desc == desc &&
1450 notifier->user_token == base_enabler->user_token)
1451 found = true;
1452 }
1453 if (found)
1454 goto end;
1455
1456 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1457 strncat(event_notifier_param.event.name, desc->name,
1458 LTTNG_KERNEL_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1459
1460 event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1461
1462 event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL;
1463 event_notifier_param.event.u.syscall.abi = abi;
1464 event_notifier_param.event.u.syscall.entryexit = entryexit;
1465
1466 notifier = _lttng_event_notifier_create(desc, user_token,
1467 group, &event_notifier_param, NULL,
1468 event_notifier_param.event.instrumentation);
1469 if (IS_ERR(notifier)) {
1470 printk(KERN_INFO "Unable to create unknown notifier %s\n",
1471 desc->name);
1472 ret = -ENOMEM;
1473 goto end;
1474 }
1475
1476 hlist_add_head_rcu(&notifier->u.syscall.node, unknown_dispatch_list);
1477
1478 end:
1479 return ret;
1480 }
1481
1482 static int create_matching_event_notifiers(
1483 struct lttng_event_notifier_enabler *event_notifier_enabler,
1484 void *filter, const struct trace_syscall_entry *table,
1485 size_t table_len, enum sc_type type)
1486 {
1487 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1488 const struct lttng_event_desc *desc;
1489 uint64_t user_token = event_notifier_enabler->base.user_token;
1490 unsigned int i;
1491 int ret = 0;
1492
1493 /* iterate over all syscall and create event_notifier that match */
1494 for (i = 0; i < table_len; i++) {
1495 struct lttng_event_notifier *event_notifier;
1496 struct lttng_kernel_event_notifier event_notifier_param;
1497 struct hlist_head *head;
1498 int found = 0;
1499
1500 desc = table[i].desc;
1501 if (!desc) {
1502 /* Unknown syscall */
1503 continue;
1504 }
1505
1506 if (!lttng_desc_match_enabler(desc,
1507 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
1508 continue;
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(event_notifier, head, hlist) {
1516 if (event_notifier->desc == desc
1517 && event_notifier->user_token == event_notifier_enabler->base.user_token)
1518 found = 1;
1519 }
1520 if (found)
1521 continue;
1522
1523 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1524 switch (type) {
1525 case SC_TYPE_ENTRY:
1526 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1527 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1528 break;
1529 case SC_TYPE_EXIT:
1530 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1531 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
1532 break;
1533 case SC_TYPE_COMPAT_ENTRY:
1534 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
1535 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1536 break;
1537 case SC_TYPE_COMPAT_EXIT:
1538 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
1539 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
1540 break;
1541 }
1542 strncat(event_notifier_param.event.name, desc->name,
1543 LTTNG_KERNEL_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1544 event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1545 event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL;
1546
1547 event_notifier = _lttng_event_notifier_create(desc, user_token, group,
1548 &event_notifier_param, filter,
1549 event_notifier_param.event.instrumentation);
1550 if (IS_ERR(event_notifier)) {
1551 printk(KERN_INFO "Unable to create event_notifier %s\n",
1552 desc->name);
1553 ret = -ENOMEM;
1554 goto end;
1555 }
1556
1557 event_notifier->u.syscall.syscall_id = i;
1558 }
1559
1560 end:
1561 return ret;
1562
1563 }
1564
1565 int lttng_syscals_create_matching_event_notifiers(
1566 struct lttng_event_notifier_enabler *event_notifier_enabler,
1567 void *filter)
1568 {
1569 int ret;
1570 struct lttng_enabler *base_enabler =
1571 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
1572 enum lttng_kernel_syscall_entryexit entryexit =
1573 base_enabler->event_param.u.syscall.entryexit;
1574
1575 if (entryexit == LTTNG_KERNEL_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_SYSCALL_ENTRYEXIT) {
1576 ret = create_matching_event_notifiers(event_notifier_enabler,
1577 filter, sc_table, ARRAY_SIZE(sc_table), SC_TYPE_ENTRY);
1578 if (ret)
1579 goto end;
1580
1581 ret = create_matching_event_notifiers(event_notifier_enabler,
1582 filter, compat_sc_table, ARRAY_SIZE(compat_sc_table),
1583 SC_TYPE_COMPAT_ENTRY);
1584 if (ret)
1585 goto end;
1586
1587 ret = create_unknown_event_notifier(event_notifier_enabler,
1588 SC_TYPE_ENTRY);
1589 if (ret)
1590 goto end;
1591
1592 ret = create_unknown_event_notifier(event_notifier_enabler,
1593 SC_TYPE_COMPAT_ENTRY);
1594 if (ret)
1595 goto end;
1596 }
1597
1598 if (entryexit == LTTNG_KERNEL_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_SYSCALL_ENTRYEXIT) {
1599 ret = create_matching_event_notifiers(event_notifier_enabler,
1600 filter, sc_exit_table, ARRAY_SIZE(sc_exit_table),
1601 SC_TYPE_EXIT);
1602 if (ret)
1603 goto end;
1604
1605 ret = create_unknown_event_notifier(event_notifier_enabler,
1606 SC_TYPE_EXIT);
1607 if (ret)
1608 goto end;
1609
1610 ret = create_matching_event_notifiers(event_notifier_enabler,
1611 filter, compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
1612 SC_TYPE_COMPAT_EXIT);
1613 if (ret)
1614 goto end;
1615
1616 ret = create_unknown_event_notifier(event_notifier_enabler,
1617 SC_TYPE_COMPAT_EXIT);
1618 if (ret)
1619 goto end;
1620 }
1621
1622 end:
1623 return ret;
1624 }
1625
1626 /*
1627 * Unregister the syscall event_notifier probes from the callsites.
1628 */
1629 int lttng_syscalls_unregister_event_notifier(
1630 struct lttng_event_notifier_group *event_notifier_group)
1631 {
1632 int ret;
1633
1634 /*
1635 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1636 * At the moment, we don't think it's desirable to have one fired
1637 * event_notifier for the entry and one for the exit of a syscall.
1638 */
1639 if (event_notifier_group->sys_enter_registered) {
1640 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1641 (void *) syscall_entry_event_notifier_probe, event_notifier_group);
1642 if (ret)
1643 return ret;
1644 event_notifier_group->sys_enter_registered = 0;
1645 }
1646 if (event_notifier_group->sys_exit_registered) {
1647 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1648 (void *) syscall_exit_event_notifier_probe, event_notifier_group);
1649 if (ret)
1650 return ret;
1651 event_notifier_group->sys_enter_registered = 0;
1652 }
1653
1654 kfree(event_notifier_group->event_notifier_syscall_dispatch);
1655 kfree(event_notifier_group->event_notifier_exit_syscall_dispatch);
1656 #ifdef CONFIG_COMPAT
1657 kfree(event_notifier_group->event_notifier_compat_syscall_dispatch);
1658 kfree(event_notifier_group->event_notifier_exit_compat_syscall_dispatch);
1659 #endif
1660 return 0;
1661 }
1662
1663 int lttng_syscalls_unregister_event(struct lttng_channel *chan)
1664 {
1665 int ret;
1666
1667 if (!chan->sc_table)
1668 return 0;
1669 if (chan->sys_enter_registered) {
1670 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1671 (void *) syscall_entry_event_probe, chan);
1672 if (ret)
1673 return ret;
1674 chan->sys_enter_registered = 0;
1675 }
1676 if (chan->sys_exit_registered) {
1677 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1678 (void *) syscall_exit_event_probe, chan);
1679 if (ret)
1680 return ret;
1681 chan->sys_exit_registered = 0;
1682 }
1683 return 0;
1684 }
1685
1686 int lttng_syscalls_destroy_event(struct lttng_channel *chan)
1687 {
1688 kfree(chan->sc_table);
1689 kfree(chan->sc_exit_table);
1690 #ifdef CONFIG_COMPAT
1691 kfree(chan->compat_sc_table);
1692 kfree(chan->compat_sc_exit_table);
1693 #endif
1694 kfree(chan->sc_filter);
1695 return 0;
1696 }
1697
1698 static
1699 int get_syscall_nr(const char *syscall_name)
1700 {
1701 int syscall_nr = -1;
1702 int i;
1703
1704 for (i = 0; i < ARRAY_SIZE(sc_table); i++) {
1705 const struct trace_syscall_entry *entry;
1706 const char *it_name;
1707
1708 entry = &sc_table[i];
1709 if (!entry->desc)
1710 continue;
1711 it_name = entry->desc->name;
1712 it_name += strlen(SYSCALL_ENTRY_STR);
1713 if (!strcmp(syscall_name, it_name)) {
1714 syscall_nr = i;
1715 break;
1716 }
1717 }
1718 return syscall_nr;
1719 }
1720
1721 static
1722 int get_compat_syscall_nr(const char *syscall_name)
1723 {
1724 int syscall_nr = -1;
1725 int i;
1726
1727 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++) {
1728 const struct trace_syscall_entry *entry;
1729 const char *it_name;
1730
1731 entry = &compat_sc_table[i];
1732 if (!entry->desc)
1733 continue;
1734 it_name = entry->desc->name;
1735 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1736 if (!strcmp(syscall_name, it_name)) {
1737 syscall_nr = i;
1738 break;
1739 }
1740 }
1741 return syscall_nr;
1742 }
1743
1744 static
1745 uint32_t get_sc_tables_len(void)
1746 {
1747 return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table);
1748 }
1749
1750 static
1751 const char *get_syscall_name(const char *desc_name,
1752 enum lttng_syscall_abi abi,
1753 enum lttng_syscall_entryexit entryexit)
1754 {
1755 size_t prefix_len = 0;
1756
1757
1758 switch (entryexit) {
1759 case LTTNG_SYSCALL_ENTRY:
1760 switch (abi) {
1761 case LTTNG_SYSCALL_ABI_NATIVE:
1762 prefix_len = strlen(SYSCALL_ENTRY_STR);
1763 break;
1764 case LTTNG_SYSCALL_ABI_COMPAT:
1765 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1766 break;
1767 }
1768 break;
1769 case LTTNG_SYSCALL_EXIT:
1770 switch (abi) {
1771 case LTTNG_SYSCALL_ABI_NATIVE:
1772 prefix_len = strlen(SYSCALL_EXIT_STR);
1773 break;
1774 case LTTNG_SYSCALL_ABI_COMPAT:
1775 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1776 break;
1777 }
1778 break;
1779 }
1780 WARN_ON_ONCE(prefix_len == 0);
1781 return desc_name + prefix_len;
1782 }
1783
1784 static
1785 int lttng_syscall_filter_enable(
1786 struct lttng_syscall_filter *filter,
1787 const char *desc_name, enum lttng_syscall_abi abi,
1788 enum lttng_syscall_entryexit entryexit)
1789 {
1790 const char *syscall_name;
1791 unsigned long *bitmap;
1792 int syscall_nr;
1793
1794 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1795
1796 switch (abi) {
1797 case LTTNG_SYSCALL_ABI_NATIVE:
1798 syscall_nr = get_syscall_nr(syscall_name);
1799 break;
1800 case LTTNG_SYSCALL_ABI_COMPAT:
1801 syscall_nr = get_compat_syscall_nr(syscall_name);
1802 break;
1803 default:
1804 return -EINVAL;
1805 }
1806 if (syscall_nr < 0)
1807 return -ENOENT;
1808
1809 switch (entryexit) {
1810 case LTTNG_SYSCALL_ENTRY:
1811 switch (abi) {
1812 case LTTNG_SYSCALL_ABI_NATIVE:
1813 bitmap = filter->sc_entry;
1814 break;
1815 case LTTNG_SYSCALL_ABI_COMPAT:
1816 bitmap = filter->sc_compat_entry;
1817 break;
1818 default:
1819 return -EINVAL;
1820 }
1821 break;
1822 case LTTNG_SYSCALL_EXIT:
1823 switch (abi) {
1824 case LTTNG_SYSCALL_ABI_NATIVE:
1825 bitmap = filter->sc_exit;
1826 break;
1827 case LTTNG_SYSCALL_ABI_COMPAT:
1828 bitmap = filter->sc_compat_exit;
1829 break;
1830 default:
1831 return -EINVAL;
1832 }
1833 break;
1834 default:
1835 return -EINVAL;
1836 }
1837 if (test_bit(syscall_nr, bitmap))
1838 return -EEXIST;
1839 bitmap_set(bitmap, syscall_nr, 1);
1840 return 0;
1841 }
1842
1843 int lttng_syscall_filter_enable_event_notifier(
1844 struct lttng_event_notifier *notifier)
1845 {
1846 struct lttng_event_notifier_group *group = notifier->group;
1847 unsigned int syscall_id = notifier->u.syscall.syscall_id;
1848 struct hlist_head *dispatch_list;
1849 int ret = 0;
1850
1851 WARN_ON_ONCE(notifier->instrumentation != LTTNG_KERNEL_SYSCALL);
1852
1853 ret = lttng_syscall_filter_enable(group->sc_filter,
1854 notifier->desc->name, notifier->u.syscall.abi,
1855 notifier->u.syscall.entryexit);
1856 if (ret) {
1857 goto end;
1858 }
1859
1860 switch (notifier->u.syscall.entryexit) {
1861 case LTTNG_SYSCALL_ENTRY:
1862 switch (notifier->u.syscall.abi) {
1863 case LTTNG_SYSCALL_ABI_NATIVE:
1864 dispatch_list = &group->event_notifier_syscall_dispatch[syscall_id];
1865 break;
1866 case LTTNG_SYSCALL_ABI_COMPAT:
1867 dispatch_list = &group->event_notifier_compat_syscall_dispatch[syscall_id];
1868 break;
1869 }
1870 break;
1871 case LTTNG_SYSCALL_EXIT:
1872 switch (notifier->u.syscall.abi) {
1873 case LTTNG_SYSCALL_ABI_NATIVE:
1874 dispatch_list = &group->event_notifier_exit_syscall_dispatch[syscall_id];
1875 break;
1876 case LTTNG_SYSCALL_ABI_COMPAT:
1877 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[syscall_id];
1878 break;
1879 }
1880 break;
1881 }
1882
1883 hlist_add_head_rcu(&notifier->u.syscall.node, dispatch_list);
1884
1885 end:
1886 return ret ;
1887 }
1888
1889 int lttng_syscall_filter_enable_event(
1890 struct lttng_channel *channel,
1891 struct lttng_event *event)
1892 {
1893 WARN_ON_ONCE(event->instrumentation != LTTNG_KERNEL_SYSCALL);
1894
1895 return lttng_syscall_filter_enable(channel->sc_filter,
1896 event->desc->name, event->u.syscall.abi,
1897 event->u.syscall.entryexit);
1898 }
1899
1900 static
1901 int lttng_syscall_filter_disable(
1902 struct lttng_syscall_filter *filter,
1903 const char *desc_name, enum lttng_syscall_abi abi,
1904 enum lttng_syscall_entryexit entryexit)
1905 {
1906 const char *syscall_name;
1907 unsigned long *bitmap;
1908 int syscall_nr;
1909
1910 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1911
1912 switch (abi) {
1913 case LTTNG_SYSCALL_ABI_NATIVE:
1914 syscall_nr = get_syscall_nr(syscall_name);
1915 break;
1916 case LTTNG_SYSCALL_ABI_COMPAT:
1917 syscall_nr = get_compat_syscall_nr(syscall_name);
1918 break;
1919 default:
1920 return -EINVAL;
1921 }
1922 if (syscall_nr < 0)
1923 return -ENOENT;
1924
1925 switch (entryexit) {
1926 case LTTNG_SYSCALL_ENTRY:
1927 switch (abi) {
1928 case LTTNG_SYSCALL_ABI_NATIVE:
1929 bitmap = filter->sc_entry;
1930 break;
1931 case LTTNG_SYSCALL_ABI_COMPAT:
1932 bitmap = filter->sc_compat_entry;
1933 break;
1934 default:
1935 return -EINVAL;
1936 }
1937 break;
1938 case LTTNG_SYSCALL_EXIT:
1939 switch (abi) {
1940 case LTTNG_SYSCALL_ABI_NATIVE:
1941 bitmap = filter->sc_exit;
1942 break;
1943 case LTTNG_SYSCALL_ABI_COMPAT:
1944 bitmap = filter->sc_compat_exit;
1945 break;
1946 default:
1947 return -EINVAL;
1948 }
1949 break;
1950 default:
1951 return -EINVAL;
1952 }
1953 if (!test_bit(syscall_nr, bitmap))
1954 return -EEXIST;
1955 bitmap_clear(bitmap, syscall_nr, 1);
1956
1957 return 0;
1958 }
1959
1960 int lttng_syscall_filter_disable_event_notifier(
1961 struct lttng_event_notifier *notifier)
1962 {
1963 struct lttng_event_notifier_group *group = notifier->group;
1964 int ret;
1965
1966 WARN_ON_ONCE(notifier->instrumentation != LTTNG_KERNEL_SYSCALL);
1967
1968 ret = lttng_syscall_filter_disable(group->sc_filter,
1969 notifier->desc->name, notifier->u.syscall.abi,
1970 notifier->u.syscall.entryexit);
1971 WARN_ON_ONCE(ret != 0);
1972
1973 hlist_del_rcu(&notifier->u.syscall.node);
1974 return 0;
1975 }
1976
1977 int lttng_syscall_filter_disable_event(
1978 struct lttng_channel *channel,
1979 struct lttng_event *event)
1980 {
1981 return lttng_syscall_filter_disable(channel->sc_filter,
1982 event->desc->name, event->u.syscall.abi,
1983 event->u.syscall.entryexit);
1984 }
1985
1986 static
1987 const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1988 {
1989 const struct trace_syscall_entry *entry;
1990 int iter = 0;
1991
1992 for (entry = sc_table;
1993 entry < sc_table + ARRAY_SIZE(sc_table);
1994 entry++) {
1995 if (iter++ >= *pos)
1996 return entry;
1997 }
1998 for (entry = compat_sc_table;
1999 entry < compat_sc_table + ARRAY_SIZE(compat_sc_table);
2000 entry++) {
2001 if (iter++ >= *pos)
2002 return entry;
2003 }
2004 /* End of list */
2005 return NULL;
2006 }
2007
2008 static
2009 void *syscall_list_start(struct seq_file *m, loff_t *pos)
2010 {
2011 return (void *) syscall_list_get_entry(pos);
2012 }
2013
2014 static
2015 void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
2016 {
2017 (*ppos)++;
2018 return (void *) syscall_list_get_entry(ppos);
2019 }
2020
2021 static
2022 void syscall_list_stop(struct seq_file *m, void *p)
2023 {
2024 }
2025
2026 static
2027 int get_sc_table(const struct trace_syscall_entry *entry,
2028 const struct trace_syscall_entry **table,
2029 unsigned int *bitness)
2030 {
2031 if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) {
2032 if (bitness)
2033 *bitness = BITS_PER_LONG;
2034 if (table)
2035 *table = sc_table;
2036 return 0;
2037 }
2038 if (!(entry >= compat_sc_table
2039 && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))) {
2040 return -EINVAL;
2041 }
2042 if (bitness)
2043 *bitness = 32;
2044 if (table)
2045 *table = compat_sc_table;
2046 return 0;
2047 }
2048
2049 static
2050 int syscall_list_show(struct seq_file *m, void *p)
2051 {
2052 const struct trace_syscall_entry *table, *entry = p;
2053 unsigned int bitness;
2054 unsigned long index;
2055 int ret;
2056 const char *name;
2057
2058 ret = get_sc_table(entry, &table, &bitness);
2059 if (ret)
2060 return ret;
2061 if (!entry->desc)
2062 return 0;
2063 if (table == sc_table) {
2064 index = entry - table;
2065 name = &entry->desc->name[strlen(SYSCALL_ENTRY_STR)];
2066 } else {
2067 index = (entry - table) + ARRAY_SIZE(sc_table);
2068 name = &entry->desc->name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
2069 }
2070 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
2071 index, name, bitness);
2072 return 0;
2073 }
2074
2075 static
2076 const struct seq_operations lttng_syscall_list_seq_ops = {
2077 .start = syscall_list_start,
2078 .next = syscall_list_next,
2079 .stop = syscall_list_stop,
2080 .show = syscall_list_show,
2081 };
2082
2083 static
2084 int lttng_syscall_list_open(struct inode *inode, struct file *file)
2085 {
2086 return seq_open(file, &lttng_syscall_list_seq_ops);
2087 }
2088
2089 const struct file_operations lttng_syscall_list_fops = {
2090 .owner = THIS_MODULE,
2091 .open = lttng_syscall_list_open,
2092 .read = seq_read,
2093 .llseek = seq_lseek,
2094 .release = seq_release,
2095 };
2096
2097 /*
2098 * A syscall is enabled if it is traced for either entry or exit.
2099 */
2100 long lttng_channel_syscall_mask(struct lttng_channel *channel,
2101 struct lttng_kernel_syscall_mask __user *usyscall_mask)
2102 {
2103 uint32_t len, sc_tables_len, bitmask_len;
2104 int ret = 0, bit;
2105 char *tmp_mask;
2106 struct lttng_syscall_filter *filter;
2107
2108 ret = get_user(len, &usyscall_mask->len);
2109 if (ret)
2110 return ret;
2111 sc_tables_len = get_sc_tables_len();
2112 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
2113 if (len < sc_tables_len) {
2114 return put_user(sc_tables_len, &usyscall_mask->len);
2115 }
2116 /* Array is large enough, we can copy array to user-space. */
2117 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
2118 if (!tmp_mask)
2119 return -ENOMEM;
2120 filter = channel->sc_filter;
2121
2122 for (bit = 0; bit < ARRAY_SIZE(sc_table); bit++) {
2123 char state;
2124
2125 if (channel->sc_table) {
2126 if (!READ_ONCE(channel->syscall_all) && filter)
2127 state = test_bit(bit, filter->sc_entry)
2128 || test_bit(bit, filter->sc_exit);
2129 else
2130 state = 1;
2131 } else {
2132 state = 0;
2133 }
2134 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
2135 }
2136 for (; bit < sc_tables_len; bit++) {
2137 char state;
2138
2139 if (channel->compat_sc_table) {
2140 if (!READ_ONCE(channel->syscall_all) && filter)
2141 state = test_bit(bit - ARRAY_SIZE(sc_table),
2142 filter->sc_compat_entry)
2143 || test_bit(bit - ARRAY_SIZE(sc_table),
2144 filter->sc_compat_exit);
2145 else
2146 state = 1;
2147 } else {
2148 state = 0;
2149 }
2150 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
2151 }
2152 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
2153 ret = -EFAULT;
2154 kfree(tmp_mask);
2155 return ret;
2156 }
2157
2158 int lttng_abi_syscall_list(void)
2159 {
2160 struct file *syscall_list_file;
2161 int file_fd, ret;
2162
2163 file_fd = lttng_get_unused_fd();
2164 if (file_fd < 0) {
2165 ret = file_fd;
2166 goto fd_error;
2167 }
2168
2169 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
2170 &lttng_syscall_list_fops,
2171 NULL, O_RDWR);
2172 if (IS_ERR(syscall_list_file)) {
2173 ret = PTR_ERR(syscall_list_file);
2174 goto file_error;
2175 }
2176 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
2177 if (ret < 0)
2178 goto open_error;
2179 fd_install(file_fd, syscall_list_file);
2180 return file_fd;
2181
2182 open_error:
2183 fput(syscall_list_file);
2184 file_error:
2185 put_unused_fd(file_fd);
2186 fd_error:
2187 return ret;
2188 }
This page took 0.123512 seconds and 3 git commands to generate.