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