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