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