Implement event notifiers for syscalls
[lttng-modules.git] / src / lttng-syscalls.c
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-syscalls.c
4 *
5 * LTTng syscall probes.
6 *
7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 */
9
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/compat.h>
13 #include <linux/err.h>
14 #include <linux/bitmap.h>
15 #include <linux/in.h>
16 #include <linux/in6.h>
17 #include <linux/seq_file.h>
18 #include <linux/stringify.h>
19 #include <linux/file.h>
20 #include <linux/anon_inodes.h>
21 #include <linux/fcntl.h>
22 #include <linux/mman.h>
23 #include <asm/ptrace.h>
24 #include <asm/syscall.h>
25
26 #include <lttng/bitfield.h>
27 #include <wrapper/tracepoint.h>
28 #include <wrapper/file.h>
29 #include <wrapper/rcu.h>
30 #include <wrapper/syscall.h>
31 #include <lttng/events.h>
32 #include <lttng/utils.h>
33
34 #ifndef CONFIG_COMPAT
35 # ifndef is_compat_task
36 # define is_compat_task() (0)
37 # endif
38 #endif
39
40 /* in_compat_syscall appears in kernel 4.6. */
41 #ifndef in_compat_syscall
42 #define in_compat_syscall() is_compat_task()
43 #endif
44
45 enum sc_type {
46 SC_TYPE_ENTRY,
47 SC_TYPE_EXIT,
48 SC_TYPE_COMPAT_ENTRY,
49 SC_TYPE_COMPAT_EXIT,
50 };
51
52 #define SYSCALL_ENTRY_TOK syscall_entry_
53 #define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
54 #define SYSCALL_EXIT_TOK syscall_exit_
55 #define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
56
57 #define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
58 #define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
59 #define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
60 #define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
61
62 static
63 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
64 static
65 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
66
67 static
68 void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
69 long id);
70
71 /*
72 * Forward declarations for old kernels.
73 */
74 struct mmsghdr;
75 struct rlimit64;
76 struct oldold_utsname;
77 struct old_utsname;
78 struct sel_arg_struct;
79 struct mmap_arg_struct;
80 struct file_handle;
81 struct user_msghdr;
82
83 /*
84 * Forward declaration for kernels >= 5.6
85 */
86 struct timex;
87 struct timeval;
88 struct itimerval;
89 struct itimerspec;
90
91 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
92 typedef __kernel_old_time_t time_t;
93 #endif
94
95 #ifdef IA32_NR_syscalls
96 #define NR_compat_syscalls IA32_NR_syscalls
97 #else
98 #define NR_compat_syscalls NR_syscalls
99 #endif
100
101 /*
102 * Create LTTng tracepoint probes.
103 */
104 #define LTTNG_PACKAGE_BUILD
105 #define CREATE_TRACE_POINTS
106 #define TP_MODULE_NOINIT
107 #define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
108
109 #define PARAMS(args...) args
110
111 /* Handle unknown syscalls */
112 #undef TRACE_SYSTEM
113 #define TRACE_SYSTEM syscalls_unknown
114 #include <instrumentation/syscalls/headers/syscalls_unknown.h>
115 #undef TRACE_SYSTEM
116
117 #define SC_ENTER
118
119 #undef sc_exit
120 #define sc_exit(...)
121 #undef sc_in
122 #define sc_in(...) __VA_ARGS__
123 #undef sc_out
124 #define sc_out(...)
125 #undef sc_inout
126 #define sc_inout(...) __VA_ARGS__
127
128 /* Hijack probe callback for system call enter */
129 #undef TP_PROBE_CB
130 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
131 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
132 LTTNG_TRACEPOINT_EVENT(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
133 PARAMS(_fields))
134 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
135 LTTNG_TRACEPOINT_EVENT_CODE(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
136 PARAMS(_locvar), PARAMS(_code_pre), \
137 PARAMS(_fields), PARAMS(_code_post))
138 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
139 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
140 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
141 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
142 /* Enumerations only defined at first inclusion. */
143 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
144 LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
145 #undef TRACE_SYSTEM
146 #define TRACE_SYSTEM syscall_entry_integers
147 #define TRACE_INCLUDE_FILE syscalls_integers
148 #include <instrumentation/syscalls/headers/syscalls_integers.h>
149 #undef TRACE_INCLUDE_FILE
150 #undef TRACE_SYSTEM
151 #define TRACE_SYSTEM syscall_entry_pointers
152 #define TRACE_INCLUDE_FILE syscalls_pointers
153 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
154 #undef TRACE_INCLUDE_FILE
155 #undef TRACE_SYSTEM
156 #undef SC_LTTNG_TRACEPOINT_ENUM
157 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
158 #undef SC_LTTNG_TRACEPOINT_EVENT
159 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
160 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
161 #undef TP_PROBE_CB
162 #undef _TRACE_SYSCALLS_INTEGERS_H
163 #undef _TRACE_SYSCALLS_POINTERS_H
164
165 /* Hijack probe callback for compat system call enter */
166 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
167 #define LTTNG_SC_COMPAT
168 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
169 LTTNG_TRACEPOINT_EVENT(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
170 PARAMS(_fields))
171 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
172 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
173 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
174 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
175 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_entry_##_name, PARAMS(_fields))
176 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
177 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
178 compat_syscall_entry_##_name)
179 /* Enumerations only defined at inital inclusion (not here). */
180 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
181 #define TRACE_SYSTEM compat_syscall_entry_integers
182 #define TRACE_INCLUDE_FILE compat_syscalls_integers
183 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
184 #undef TRACE_INCLUDE_FILE
185 #undef TRACE_SYSTEM
186 #define TRACE_SYSTEM compat_syscall_entry_pointers
187 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
188 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
189 #undef TRACE_INCLUDE_FILE
190 #undef TRACE_SYSTEM
191 #undef SC_LTTNG_TRACEPOINT_ENUM
192 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
193 #undef SC_LTTNG_TRACEPOINT_EVENT
194 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
195 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
196 #undef TP_PROBE_CB
197 #undef _TRACE_SYSCALLS_INTEGERS_H
198 #undef _TRACE_SYSCALLS_POINTERS_H
199 #undef LTTNG_SC_COMPAT
200
201 #undef SC_ENTER
202
203 #define SC_EXIT
204
205 #undef sc_exit
206 #define sc_exit(...) __VA_ARGS__
207 #undef sc_in
208 #define sc_in(...)
209 #undef sc_out
210 #define sc_out(...) __VA_ARGS__
211 #undef sc_inout
212 #define sc_inout(...) __VA_ARGS__
213
214 /* Hijack probe callback for system call exit */
215 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
216 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
217 LTTNG_TRACEPOINT_EVENT(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
218 PARAMS(_fields))
219 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
220 LTTNG_TRACEPOINT_EVENT_CODE(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
221 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
222 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
223 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_exit_##_name, PARAMS(_fields))
224 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
225 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \
226 syscall_exit_##_name)
227 /* Enumerations only defined at inital inclusion (not here). */
228 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
229 #define TRACE_SYSTEM syscall_exit_integers
230 #define TRACE_INCLUDE_FILE syscalls_integers
231 #include <instrumentation/syscalls/headers/syscalls_integers.h>
232 #undef TRACE_INCLUDE_FILE
233 #undef TRACE_SYSTEM
234 #define TRACE_SYSTEM syscall_exit_pointers
235 #define TRACE_INCLUDE_FILE syscalls_pointers
236 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
237 #undef TRACE_INCLUDE_FILE
238 #undef TRACE_SYSTEM
239 #undef SC_LTTNG_TRACEPOINT_ENUM
240 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
241 #undef SC_LTTNG_TRACEPOINT_EVENT
242 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
243 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
244 #undef TP_PROBE_CB
245 #undef _TRACE_SYSCALLS_INTEGERS_H
246 #undef _TRACE_SYSCALLS_POINTERS_H
247
248
249 /* Hijack probe callback for compat system call exit */
250 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
251 #define LTTNG_SC_COMPAT
252 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
253 LTTNG_TRACEPOINT_EVENT(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
254 PARAMS(_fields))
255 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
256 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
257 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
258 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
259 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_exit_##_name, PARAMS(_fields))
260 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
261 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
262 compat_syscall_exit_##_name)
263 /* Enumerations only defined at inital inclusion (not here). */
264 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
265 #define TRACE_SYSTEM compat_syscall_exit_integers
266 #define TRACE_INCLUDE_FILE compat_syscalls_integers
267 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
268 #undef TRACE_INCLUDE_FILE
269 #undef TRACE_SYSTEM
270 #define TRACE_SYSTEM compat_syscall_exit_pointers
271 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
272 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
273 #undef TRACE_INCLUDE_FILE
274 #undef TRACE_SYSTEM
275 #undef SC_LTTNG_TRACEPOINT_ENUM
276 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
277 #undef SC_LTTNG_TRACEPOINT_EVENT
278 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
279 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
280 #undef TP_PROBE_CB
281 #undef _TRACE_SYSCALLS_INTEGERS_H
282 #undef _TRACE_SYSCALLS_POINTERS_H
283 #undef LTTNG_SC_COMPAT
284
285 #undef SC_EXIT
286
287 #undef TP_MODULE_NOINIT
288 #undef LTTNG_PACKAGE_BUILD
289 #undef CREATE_TRACE_POINTS
290
291 struct trace_syscall_entry {
292 void *event_func;
293 void *event_notifier_func;
294 const struct lttng_event_desc *desc;
295 const struct lttng_event_field *fields;
296 unsigned int nrargs;
297 };
298
299 #define CREATE_SYSCALL_TABLE
300
301 #define SC_ENTER
302
303 #undef sc_exit
304 #define sc_exit(...)
305
306 #undef TRACE_SYSCALL_TABLE
307 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
308 [ _nr ] = { \
309 .event_func = __event_probe__syscall_entry_##_template, \
310 .event_notifier_func = __event_notifier_probe__syscall_entry_##_template, \
311 .nrargs = (_nrargs), \
312 .fields = __event_fields___syscall_entry_##_template, \
313 .desc = &__event_desc___syscall_entry_##_name, \
314 },
315
316 /* Event syscall enter tracing table */
317 static const struct trace_syscall_entry sc_table[] = {
318 #include <instrumentation/syscalls/headers/syscalls_integers.h>
319 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
320 };
321
322 #undef TRACE_SYSCALL_TABLE
323 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
324 [ _nr ] = { \
325 .event_func = __event_probe__compat_syscall_entry_##_template, \
326 .event_notifier_func = __event_notifier_probe__compat_syscall_entry_##_template, \
327 .nrargs = (_nrargs), \
328 .fields = __event_fields___compat_syscall_entry_##_template, \
329 .desc = &__event_desc___compat_syscall_entry_##_name, \
330 },
331
332 /* Event compat syscall enter table */
333 const struct trace_syscall_entry compat_sc_table[] = {
334 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
335 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
336 };
337
338 #undef SC_ENTER
339
340 #define SC_EXIT
341
342 #undef sc_exit
343 #define sc_exit(...) __VA_ARGS__
344
345 #undef TRACE_SYSCALL_TABLE
346 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
347 [ _nr ] = { \
348 .event_func = __event_probe__syscall_exit_##_template, \
349 .event_notifier_func = __event_notifier_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 .event_notifier_func = __event_notifier_probe__compat_syscall_exit_##_template, \
366 .nrargs = (_nrargs), \
367 .fields = __event_fields___compat_syscall_exit_##_template, \
368 .desc = &__event_desc___compat_syscall_exit_##_name, \
369 },
370
371 /* Event compat syscall exit table */
372 const struct trace_syscall_entry compat_sc_exit_table[] = {
373 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
374 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
375 };
376
377 #undef SC_EXIT
378
379 #undef CREATE_SYSCALL_TABLE
380
381 struct lttng_syscall_filter {
382 DECLARE_BITMAP(sc_entry, NR_syscalls);
383 DECLARE_BITMAP(sc_exit, NR_syscalls);
384 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
385 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
386 };
387
388 static void syscall_entry_event_unknown(struct lttng_event *event,
389 struct pt_regs *regs, unsigned int id)
390 {
391 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
392
393 lttng_syscall_get_arguments(current, regs, args);
394 if (unlikely(in_compat_syscall()))
395 __event_probe__compat_syscall_entry_unknown(event, id, args);
396 else
397 __event_probe__syscall_entry_unknown(event, id, args);
398 }
399
400 static void syscall_entry_event_notifier_unknown(
401 struct lttng_event_notifier_group *notifier_group,
402 struct pt_regs *regs, unsigned int id)
403 {
404 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
405 struct lttng_event *event;
406
407 lttng_syscall_get_arguments(current, regs, args);
408 if (unlikely(in_compat_syscall()))
409 __event_probe__compat_syscall_notifier_entry_unknown(event, id, args);
410 else
411 __event_probe__syscall_notifier_entry_unknown(event, id, args);
412 }
413
414 static __always_inline
415 void syscall_entry_call_func(void *func, unsigned int nrargs, void *data,
416 struct pt_regs *regs)
417 {
418 switch (nrargs) {
419 case 0:
420 {
421 void (*fptr)(void *__data) = func;
422
423 fptr(data);
424 break;
425 }
426 case 1:
427 {
428 void (*fptr)(void *__data, unsigned long arg0) = func;
429 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
430
431 lttng_syscall_get_arguments(current, regs, args);
432 fptr(data, args[0]);
433 break;
434 }
435 case 2:
436 {
437 void (*fptr)(void *__data,
438 unsigned long arg0,
439 unsigned long arg1) = func;
440 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
441
442 lttng_syscall_get_arguments(current, regs, args);
443 fptr(data, args[0], args[1]);
444 break;
445 }
446 case 3:
447 {
448 void (*fptr)(void *__data,
449 unsigned long arg0,
450 unsigned long arg1,
451 unsigned long arg2) = func;
452 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
453
454 lttng_syscall_get_arguments(current, regs, args);
455 fptr(data, args[0], args[1], args[2]);
456 break;
457 }
458 case 4:
459 {
460 void (*fptr)(void *__data,
461 unsigned long arg0,
462 unsigned long arg1,
463 unsigned long arg2,
464 unsigned long arg3) = func;
465 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
466
467 lttng_syscall_get_arguments(current, regs, args);
468 fptr(data, args[0], args[1], args[2], args[3]);
469 break;
470 }
471 case 5:
472 {
473 void (*fptr)(void *__data,
474 unsigned long arg0,
475 unsigned long arg1,
476 unsigned long arg2,
477 unsigned long arg3,
478 unsigned long arg4) = func;
479 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
480
481 lttng_syscall_get_arguments(current, regs, args);
482 fptr(data, args[0], args[1], args[2], args[3], args[4]);
483 break;
484 }
485 case 6:
486 {
487 void (*fptr)(void *__data,
488 unsigned long arg0,
489 unsigned long arg1,
490 unsigned long arg2,
491 unsigned long arg3,
492 unsigned long arg4,
493 unsigned long arg5) = func;
494 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
495
496 lttng_syscall_get_arguments(current, regs, args);
497 fptr(data, args[0], args[1], args[2],
498 args[3], args[4], args[5]);
499 break;
500 }
501 default:
502 break;
503 }
504 }
505
506 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
507 {
508 struct lttng_channel *chan = __data;
509 struct lttng_event *event, *unknown_event;
510 const struct trace_syscall_entry *table, *entry;
511 size_t table_len;
512
513 if (unlikely(in_compat_syscall())) {
514 struct lttng_syscall_filter *filter = chan->sc_filter;
515
516 if (id < 0 || id >= NR_compat_syscalls
517 || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_compat_entry))) {
518 /* System call filtered out. */
519 return;
520 }
521 table = compat_sc_table;
522 table_len = ARRAY_SIZE(compat_sc_table);
523 unknown_event = chan->sc_compat_unknown;
524 } else {
525 struct lttng_syscall_filter *filter = chan->sc_filter;
526
527 if (id < 0 || id >= NR_syscalls
528 || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_entry))) {
529 /* System call filtered out. */
530 return;
531 }
532 table = sc_table;
533 table_len = ARRAY_SIZE(sc_table);
534 unknown_event = chan->sc_unknown;
535 }
536 if (unlikely(id < 0 || id >= table_len)) {
537 syscall_entry_event_unknown(unknown_event, regs, id);
538 return;
539 }
540 if (unlikely(in_compat_syscall()))
541 event = chan->compat_sc_table[id];
542 else
543 event = chan->sc_table[id];
544 if (unlikely(!event)) {
545 syscall_entry_event_unknown(unknown_event, regs, id);
546 return;
547 }
548 entry = &table[id];
549 WARN_ON_ONCE(!entry);
550 syscall_entry_call_func(entry->event_func, entry->nrargs, event, regs);
551 }
552
553 void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs, long id)
554 {
555 struct lttng_event_notifier_group *event_notifier_group = __data;
556 const struct trace_syscall_entry *entry;
557 struct list_head *dispatch_list;
558 struct lttng_event_notifier *iter;
559 size_t table_len;
560
561 if (unlikely(in_compat_syscall())) {
562 table_len = ARRAY_SIZE(compat_sc_table);
563 if (unlikely(id < 0 || id >= table_len)) {
564 return;
565 }
566 entry = &compat_sc_table[id];
567 dispatch_list = &event_notifier_group->event_notifier_compat_syscall_dispatch[id];
568 } else {
569 table_len = ARRAY_SIZE(sc_table);
570 if (unlikely(id < 0 || id >= table_len)) {
571 return;
572 }
573 entry = &sc_table[id];
574 dispatch_list = &event_notifier_group->event_notifier_syscall_dispatch[id];
575 }
576
577 if (unlikely(id < 0 || id >= table_len)) {
578 syscall_entry_event_notifier_unknown(event_notifier_group, regs, id);
579 return;
580 }
581
582 /* TODO handle unknown syscall */
583
584 list_for_each_entry_rcu(iter, dispatch_list, u.syscall.node) {
585 BUG_ON(iter->u.syscall.syscall_id != id);
586 syscall_entry_call_func(entry->event_notifier_func,
587 entry->nrargs, iter, regs);
588 }
589 }
590
591 static void syscall_exit_event_unknown(struct lttng_event *event,
592 struct pt_regs *regs, int id, long ret)
593 {
594 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
595
596 lttng_syscall_get_arguments(current, regs, args);
597 if (unlikely(in_compat_syscall()))
598 __event_probe__compat_syscall_exit_unknown(event, id, ret,
599 args);
600 else
601 __event_probe__syscall_exit_unknown(event, id, ret, args);
602 }
603
604 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
605 {
606 struct lttng_channel *chan = __data;
607 struct lttng_event *event, *unknown_event;
608 const struct trace_syscall_entry *table, *entry;
609 size_t table_len;
610 long id;
611
612 id = syscall_get_nr(current, regs);
613 if (unlikely(in_compat_syscall())) {
614 struct lttng_syscall_filter *filter = chan->sc_filter;
615
616 if (id < 0 || id >= NR_compat_syscalls
617 || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_compat_exit))) {
618 /* System call filtered out. */
619 return;
620 }
621 table = compat_sc_exit_table;
622 table_len = ARRAY_SIZE(compat_sc_exit_table);
623 unknown_event = chan->compat_sc_exit_unknown;
624 } else {
625 struct lttng_syscall_filter *filter = chan->sc_filter;
626
627 if (id < 0 || id >= NR_syscalls
628 || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_exit))) {
629 /* System call filtered out. */
630 return;
631 }
632 table = sc_exit_table;
633 table_len = ARRAY_SIZE(sc_exit_table);
634 unknown_event = chan->sc_exit_unknown;
635 }
636 if (unlikely(id < 0 || id >= table_len)) {
637 syscall_exit_event_unknown(unknown_event, regs, id, ret);
638 return;
639 }
640 if (unlikely(in_compat_syscall()))
641 event = chan->compat_sc_exit_table[id];
642 else
643 event = chan->sc_exit_table[id];
644 if (unlikely(!event)) {
645 syscall_exit_event_unknown(unknown_event, regs, id, ret);
646 return;
647 }
648 entry = &table[id];
649 WARN_ON_ONCE(!entry);
650
651 switch (entry->nrargs) {
652 case 0:
653 {
654 void (*fptr)(void *__data, long ret) = entry->event_func;
655
656 fptr(event, ret);
657 break;
658 }
659 case 1:
660 {
661 void (*fptr)(void *__data,
662 long ret,
663 unsigned long arg0) = entry->event_func;
664 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
665
666 lttng_syscall_get_arguments(current, regs, args);
667 fptr(event, ret, args[0]);
668 break;
669 }
670 case 2:
671 {
672 void (*fptr)(void *__data,
673 long ret,
674 unsigned long arg0,
675 unsigned long arg1) = entry->event_func;
676 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
677
678 lttng_syscall_get_arguments(current, regs, args);
679 fptr(event, ret, args[0], args[1]);
680 break;
681 }
682 case 3:
683 {
684 void (*fptr)(void *__data,
685 long ret,
686 unsigned long arg0,
687 unsigned long arg1,
688 unsigned long arg2) = entry->event_func;
689 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
690
691 lttng_syscall_get_arguments(current, regs, args);
692 fptr(event, ret, args[0], args[1], args[2]);
693 break;
694 }
695 case 4:
696 {
697 void (*fptr)(void *__data,
698 long ret,
699 unsigned long arg0,
700 unsigned long arg1,
701 unsigned long arg2,
702 unsigned long arg3) = entry->event_func;
703 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
704
705 lttng_syscall_get_arguments(current, regs, args);
706 fptr(event, ret, args[0], args[1], args[2], args[3]);
707 break;
708 }
709 case 5:
710 {
711 void (*fptr)(void *__data,
712 long ret,
713 unsigned long arg0,
714 unsigned long arg1,
715 unsigned long arg2,
716 unsigned long arg3,
717 unsigned long arg4) = entry->event_func;
718 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
719
720 lttng_syscall_get_arguments(current, regs, args);
721 fptr(event, ret, args[0], args[1], args[2], args[3], args[4]);
722 break;
723 }
724 case 6:
725 {
726 void (*fptr)(void *__data,
727 long ret,
728 unsigned long arg0,
729 unsigned long arg1,
730 unsigned long arg2,
731 unsigned long arg3,
732 unsigned long arg4,
733 unsigned long arg5) = entry->event_func;
734 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
735
736 lttng_syscall_get_arguments(current, regs, args);
737 fptr(event, ret, args[0], args[1], args[2],
738 args[3], args[4], args[5]);
739 break;
740 }
741 default:
742 break;
743 }
744 }
745
746 /*
747 * noinline to diminish caller stack size.
748 * Should be called with sessions lock held.
749 */
750 static
751 int fill_event_table(const struct trace_syscall_entry *table, size_t table_len,
752 struct lttng_event **chan_table, struct lttng_channel *chan,
753 void *filter, enum sc_type type)
754 {
755 const struct lttng_event_desc *desc;
756 unsigned int i;
757
758 /* Allocate events for each syscall, insert into table */
759 for (i = 0; i < table_len; i++) {
760 struct lttng_kernel_event ev;
761 desc = table[i].desc;
762
763 if (!desc) {
764 /* Unknown syscall */
765 continue;
766 }
767 /*
768 * Skip those already populated by previous failed
769 * register for this channel.
770 */
771 if (chan_table[i])
772 continue;
773 memset(&ev, 0, sizeof(ev));
774 switch (type) {
775 case SC_TYPE_ENTRY:
776 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
777 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
778 break;
779 case SC_TYPE_EXIT:
780 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
781 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
782 break;
783 case SC_TYPE_COMPAT_ENTRY:
784 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
785 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
786 break;
787 case SC_TYPE_COMPAT_EXIT:
788 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
789 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
790 break;
791 }
792 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN - 1);
793 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
794 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
795 chan_table[i] = _lttng_event_create(chan, &ev, filter,
796 desc, ev.instrumentation);
797 WARN_ON_ONCE(!chan_table[i]);
798 if (IS_ERR(chan_table[i])) {
799 /*
800 * If something goes wrong in event registration
801 * after the first one, we have no choice but to
802 * leave the previous events in there, until
803 * deleted by session teardown.
804 */
805 return PTR_ERR(chan_table[i]);
806 }
807 }
808 return 0;
809 }
810
811 /*
812 * Should be called with sessions lock held.
813 */
814 int lttng_syscalls_register_event(struct lttng_channel *chan, void *filter)
815 {
816 struct lttng_kernel_event ev;
817 int ret;
818
819 wrapper_vmalloc_sync_mappings();
820
821 if (!chan->sc_table) {
822 /* create syscall table mapping syscall to events */
823 chan->sc_table = kzalloc(sizeof(struct lttng_event *)
824 * ARRAY_SIZE(sc_table), GFP_KERNEL);
825 if (!chan->sc_table)
826 return -ENOMEM;
827 }
828 if (!chan->sc_exit_table) {
829 /* create syscall table mapping syscall to events */
830 chan->sc_exit_table = kzalloc(sizeof(struct lttng_event *)
831 * ARRAY_SIZE(sc_exit_table), GFP_KERNEL);
832 if (!chan->sc_exit_table)
833 return -ENOMEM;
834 }
835
836
837 #ifdef CONFIG_COMPAT
838 if (!chan->compat_sc_table) {
839 /* create syscall table mapping compat syscall to events */
840 chan->compat_sc_table = kzalloc(sizeof(struct lttng_event *)
841 * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
842 if (!chan->compat_sc_table)
843 return -ENOMEM;
844 }
845
846 if (!chan->compat_sc_exit_table) {
847 /* create syscall table mapping compat syscall to events */
848 chan->compat_sc_exit_table = kzalloc(sizeof(struct lttng_event *)
849 * ARRAY_SIZE(compat_sc_exit_table), GFP_KERNEL);
850 if (!chan->compat_sc_exit_table)
851 return -ENOMEM;
852 }
853 #endif
854 if (!chan->sc_unknown) {
855 const struct lttng_event_desc *desc =
856 &__event_desc___syscall_entry_unknown;
857
858 memset(&ev, 0, sizeof(ev));
859 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
860 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
861 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
862 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
863 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
864 chan->sc_unknown = _lttng_event_create(chan, &ev, filter,
865 desc,
866 ev.instrumentation);
867 WARN_ON_ONCE(!chan->sc_unknown);
868 if (IS_ERR(chan->sc_unknown)) {
869 return PTR_ERR(chan->sc_unknown);
870 }
871 }
872
873 if (!chan->sc_compat_unknown) {
874 const struct lttng_event_desc *desc =
875 &__event_desc___compat_syscall_entry_unknown;
876
877 memset(&ev, 0, sizeof(ev));
878 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
879 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
880 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
881 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
882 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
883 chan->sc_compat_unknown = _lttng_event_create(chan, &ev, filter,
884 desc,
885 ev.instrumentation);
886 WARN_ON_ONCE(!chan->sc_unknown);
887 if (IS_ERR(chan->sc_compat_unknown)) {
888 return PTR_ERR(chan->sc_compat_unknown);
889 }
890 }
891
892 if (!chan->compat_sc_exit_unknown) {
893 const struct lttng_event_desc *desc =
894 &__event_desc___compat_syscall_exit_unknown;
895
896 memset(&ev, 0, sizeof(ev));
897 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
898 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
899 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
900 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
901 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT;
902 chan->compat_sc_exit_unknown = _lttng_event_create(chan, &ev,
903 filter, desc,
904 ev.instrumentation);
905 WARN_ON_ONCE(!chan->compat_sc_exit_unknown);
906 if (IS_ERR(chan->compat_sc_exit_unknown)) {
907 return PTR_ERR(chan->compat_sc_exit_unknown);
908 }
909 }
910
911 if (!chan->sc_exit_unknown) {
912 const struct lttng_event_desc *desc =
913 &__event_desc___syscall_exit_unknown;
914
915 memset(&ev, 0, sizeof(ev));
916 strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
917 ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
918 ev.instrumentation = LTTNG_KERNEL_SYSCALL;
919 ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
920 ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE;
921 chan->sc_exit_unknown = _lttng_event_create(chan, &ev, filter,
922 desc, ev.instrumentation);
923 WARN_ON_ONCE(!chan->sc_exit_unknown);
924 if (IS_ERR(chan->sc_exit_unknown)) {
925 return PTR_ERR(chan->sc_exit_unknown);
926 }
927 }
928
929 ret = fill_event_table(sc_table, ARRAY_SIZE(sc_table),
930 chan->sc_table, chan, filter, SC_TYPE_ENTRY);
931 if (ret)
932 return ret;
933 ret = fill_event_table(sc_exit_table, ARRAY_SIZE(sc_exit_table),
934 chan->sc_exit_table, chan, filter, SC_TYPE_EXIT);
935 if (ret)
936 return ret;
937
938 #ifdef CONFIG_COMPAT
939 ret = fill_event_table(compat_sc_table, ARRAY_SIZE(compat_sc_table),
940 chan->compat_sc_table, chan, filter,
941 SC_TYPE_COMPAT_ENTRY);
942 if (ret)
943 return ret;
944 ret = fill_event_table(compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
945 chan->compat_sc_exit_table, chan, filter,
946 SC_TYPE_COMPAT_EXIT);
947 if (ret)
948 return ret;
949 #endif
950
951 if (!chan->sc_filter) {
952 chan->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
953 GFP_KERNEL);
954 if (!chan->sc_filter)
955 return -ENOMEM;
956 }
957
958 if (!chan->sys_enter_registered) {
959 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
960 (void *) syscall_entry_event_probe, chan);
961 if (ret)
962 return ret;
963 chan->sys_enter_registered = 1;
964 }
965 /*
966 * We change the name of sys_exit tracepoint due to namespace
967 * conflict with sys_exit syscall entry.
968 */
969 if (!chan->sys_exit_registered) {
970 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
971 (void *) syscall_exit_event_probe, chan);
972 if (ret) {
973 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
974 (void *) syscall_entry_event_probe, chan));
975 return ret;
976 }
977 chan->sys_exit_registered = 1;
978 }
979 return ret;
980 }
981
982 /*
983 * Should be called with sessions lock held.
984 */
985 int lttng_syscalls_register_event_notifier(struct lttng_event_notifier_enabler *event_notifier_enabler, void *filter)
986 {
987 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
988 unsigned int i;
989 int ret = 0;
990
991 wrapper_vmalloc_sync_mappings();
992
993 if (!group->event_notifier_syscall_dispatch) {
994 group->event_notifier_syscall_dispatch = kzalloc(sizeof(struct list_head)
995 * ARRAY_SIZE(sc_table), GFP_KERNEL);
996 if (!group->event_notifier_syscall_dispatch)
997 return -ENOMEM;
998
999 /* Initialize all list_head */
1000 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1001 INIT_LIST_HEAD(&group->event_notifier_syscall_dispatch[i]);
1002 }
1003
1004 #ifdef CONFIG_COMPAT
1005 if (!group->event_notifier_compat_syscall_dispatch) {
1006 group->event_notifier_compat_syscall_dispatch = kzalloc(sizeof(struct list_head)
1007 * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
1008 if (!group->event_notifier_syscall_dispatch)
1009 return -ENOMEM;
1010
1011 /* Initialize all list_head */
1012 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++)
1013 INIT_LIST_HEAD(&group->event_notifier_compat_syscall_dispatch[i]);
1014 }
1015 #endif
1016
1017 if (!group->sys_enter_registered) {
1018 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
1019 (void *) syscall_entry_event_notifier_probe, group);
1020 if (ret)
1021 return ret;
1022 group->sys_enter_registered = 1;
1023 }
1024
1025 return ret;
1026 }
1027
1028 static int create_matching_event_notifiers(struct lttng_event_notifier_enabler *event_notifier_enabler,
1029 void *filter, const struct trace_syscall_entry *table,
1030 size_t table_len, bool is_compat)
1031 {
1032 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1033 const struct lttng_event_desc *desc;
1034 uint64_t user_token = event_notifier_enabler->base.user_token;
1035 unsigned int i;
1036 int ret = 0;
1037
1038 /* iterate over all syscall and create event_notifier that match */
1039 for (i = 0; i < table_len; i++) {
1040 struct lttng_event_notifier *event_notifier;
1041 struct lttng_kernel_event_notifier event_notifier_param;
1042 struct hlist_head *head;
1043 int found = 0;
1044
1045 desc = table[i].desc;
1046 if (!desc) {
1047 /* Unknown syscall */
1048 continue;
1049 }
1050
1051 if (!lttng_desc_match_enabler(desc,
1052 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
1053 continue;
1054
1055 /*
1056 * Check if already created.
1057 */
1058 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
1059 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->name);
1060 lttng_hlist_for_each_entry(event_notifier, head, hlist) {
1061 if (event_notifier->desc == desc
1062 && event_notifier->user_token == event_notifier_enabler->base.user_token)
1063 found = 1;
1064 }
1065 if (found)
1066 continue;
1067
1068 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1069 strncat(event_notifier_param.event.name, desc->name,
1070 LTTNG_KERNEL_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1071 event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
1072 event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL;
1073
1074 event_notifier = _lttng_event_notifier_create(desc, user_token, group,
1075 &event_notifier_param, filter,
1076 event_notifier_param.event.instrumentation);
1077 if (IS_ERR(event_notifier)) {
1078 printk(KERN_INFO "Unable to create event_notifier %s\n",
1079 desc->name);
1080 ret = -ENOMEM;
1081 goto end;
1082 }
1083
1084 event_notifier->u.syscall.syscall_id = i;
1085 event_notifier->u.syscall.is_compat = is_compat;
1086 }
1087 end:
1088 return ret;
1089
1090 }
1091
1092 int lttng_syscals_create_matching_event_notifiers(struct lttng_event_notifier_enabler *event_notifier_enabler, void *filter)
1093 {
1094 int ret;
1095
1096 ret = create_matching_event_notifiers(event_notifier_enabler, filter, sc_table,
1097 ARRAY_SIZE(sc_table), false);
1098 if (ret)
1099 goto end;
1100
1101 ret = create_matching_event_notifiers(event_notifier_enabler, filter, compat_sc_table,
1102 ARRAY_SIZE(compat_sc_table), true);
1103 end:
1104 return ret;
1105 }
1106
1107 /*
1108 * Unregister the syscall event_notifier probes from the callsites.
1109 */
1110 int lttng_syscalls_unregister_event_notifier(struct lttng_event_notifier_group *event_notifier_group)
1111 {
1112 int ret;
1113
1114 /*
1115 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1116 * At the moment, we don't think it's desirable to have one fired
1117 * event_notifier for the entry and one for the exit of a syscall.
1118 */
1119 if (event_notifier_group->sys_enter_registered) {
1120 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1121 (void *) syscall_entry_event_notifier_probe, event_notifier_group);
1122 if (ret)
1123 return ret;
1124 event_notifier_group->sys_enter_registered = 0;
1125 }
1126
1127 kfree(event_notifier_group->event_notifier_syscall_dispatch);
1128 #ifdef CONFIG_COMPAT
1129 kfree(event_notifier_group->event_notifier_compat_syscall_dispatch);
1130 #endif
1131 return 0;
1132 }
1133
1134 int lttng_syscalls_unregister_event(struct lttng_channel *chan)
1135 {
1136 int ret;
1137
1138 if (!chan->sc_table)
1139 return 0;
1140 if (chan->sys_enter_registered) {
1141 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1142 (void *) syscall_entry_event_probe, chan);
1143 if (ret)
1144 return ret;
1145 chan->sys_enter_registered = 0;
1146 }
1147 if (chan->sys_exit_registered) {
1148 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1149 (void *) syscall_exit_event_probe, chan);
1150 if (ret)
1151 return ret;
1152 chan->sys_exit_registered = 0;
1153 }
1154 return 0;
1155 }
1156
1157 int lttng_syscalls_destroy_event(struct lttng_channel *chan)
1158 {
1159 kfree(chan->sc_table);
1160 kfree(chan->sc_exit_table);
1161 #ifdef CONFIG_COMPAT
1162 kfree(chan->compat_sc_table);
1163 kfree(chan->compat_sc_exit_table);
1164 #endif
1165 kfree(chan->sc_filter);
1166 return 0;
1167 }
1168
1169 static
1170 int get_syscall_nr(const char *syscall_name)
1171 {
1172 int syscall_nr = -1;
1173 int i;
1174
1175 for (i = 0; i < ARRAY_SIZE(sc_table); i++) {
1176 const struct trace_syscall_entry *entry;
1177 const char *it_name;
1178
1179 entry = &sc_table[i];
1180 if (!entry->desc)
1181 continue;
1182 it_name = entry->desc->name;
1183 it_name += strlen(SYSCALL_ENTRY_STR);
1184 if (!strcmp(syscall_name, it_name)) {
1185 syscall_nr = i;
1186 break;
1187 }
1188 }
1189 return syscall_nr;
1190 }
1191
1192 static
1193 int get_compat_syscall_nr(const char *syscall_name)
1194 {
1195 int syscall_nr = -1;
1196 int i;
1197
1198 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++) {
1199 const struct trace_syscall_entry *entry;
1200 const char *it_name;
1201
1202 entry = &compat_sc_table[i];
1203 if (!entry->desc)
1204 continue;
1205 it_name = entry->desc->name;
1206 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1207 if (!strcmp(syscall_name, it_name)) {
1208 syscall_nr = i;
1209 break;
1210 }
1211 }
1212 return syscall_nr;
1213 }
1214
1215 static
1216 uint32_t get_sc_tables_len(void)
1217 {
1218 return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table);
1219 }
1220
1221 static
1222 const char *get_syscall_name(struct lttng_event *event)
1223 {
1224 size_t prefix_len = 0;
1225
1226 WARN_ON_ONCE(event->instrumentation != LTTNG_KERNEL_SYSCALL);
1227
1228 switch (event->u.syscall.entryexit) {
1229 case LTTNG_SYSCALL_ENTRY:
1230 switch (event->u.syscall.abi) {
1231 case LTTNG_SYSCALL_ABI_NATIVE:
1232 prefix_len = strlen(SYSCALL_ENTRY_STR);
1233 break;
1234 case LTTNG_SYSCALL_ABI_COMPAT:
1235 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1236 break;
1237 }
1238 break;
1239 case LTTNG_SYSCALL_EXIT:
1240 switch (event->u.syscall.abi) {
1241 case LTTNG_SYSCALL_ABI_NATIVE:
1242 prefix_len = strlen(SYSCALL_EXIT_STR);
1243 break;
1244 case LTTNG_SYSCALL_ABI_COMPAT:
1245 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1246 break;
1247 }
1248 break;
1249 }
1250 WARN_ON_ONCE(prefix_len == 0);
1251 return event->desc->name + prefix_len;
1252 }
1253
1254 int lttng_syscall_filter_enable_event(struct lttng_channel *chan,
1255 struct lttng_event *event)
1256 {
1257 struct lttng_syscall_filter *filter = chan->sc_filter;
1258 const char *syscall_name;
1259 unsigned long *bitmap;
1260 int syscall_nr;
1261
1262 WARN_ON_ONCE(!chan->sc_table);
1263
1264 syscall_name = get_syscall_name(event);
1265
1266 switch (event->u.syscall.abi) {
1267 case LTTNG_SYSCALL_ABI_NATIVE:
1268 syscall_nr = get_syscall_nr(syscall_name);
1269 break;
1270 case LTTNG_SYSCALL_ABI_COMPAT:
1271 syscall_nr = get_compat_syscall_nr(syscall_name);
1272 break;
1273 default:
1274 return -EINVAL;
1275 }
1276 if (syscall_nr < 0)
1277 return -ENOENT;
1278
1279 switch (event->u.syscall.entryexit) {
1280 case LTTNG_SYSCALL_ENTRY:
1281 switch (event->u.syscall.abi) {
1282 case LTTNG_SYSCALL_ABI_NATIVE:
1283 bitmap = filter->sc_entry;
1284 break;
1285 case LTTNG_SYSCALL_ABI_COMPAT:
1286 bitmap = filter->sc_compat_entry;
1287 break;
1288 default:
1289 return -EINVAL;
1290 }
1291 break;
1292 case LTTNG_SYSCALL_EXIT:
1293 switch (event->u.syscall.abi) {
1294 case LTTNG_SYSCALL_ABI_NATIVE:
1295 bitmap = filter->sc_exit;
1296 break;
1297 case LTTNG_SYSCALL_ABI_COMPAT:
1298 bitmap = filter->sc_compat_exit;
1299 break;
1300 default:
1301 return -EINVAL;
1302 }
1303 break;
1304 default:
1305 return -EINVAL;
1306 }
1307 if (test_bit(syscall_nr, bitmap))
1308 return -EEXIST;
1309 bitmap_set(bitmap, syscall_nr, 1);
1310 return 0;
1311 }
1312
1313 int lttng_syscall_filter_enable_event_notifier(
1314 struct lttng_event_notifier *event_notifier)
1315 {
1316 struct lttng_event_notifier_group *group = event_notifier->group;
1317 unsigned int syscall_id = event_notifier->u.syscall.syscall_id;
1318 struct list_head *dispatch_list;
1319
1320 if (event_notifier->u.syscall.is_compat)
1321 dispatch_list = &group->event_notifier_compat_syscall_dispatch[syscall_id];
1322 else
1323 dispatch_list = &group->event_notifier_syscall_dispatch[syscall_id];
1324
1325 list_add_rcu(&event_notifier->u.syscall.node, dispatch_list);
1326
1327 return 0;
1328 }
1329
1330 int lttng_syscall_filter_disable_event(struct lttng_channel *chan,
1331 struct lttng_event *event)
1332 {
1333 struct lttng_syscall_filter *filter = chan->sc_filter;
1334 const char *syscall_name;
1335 unsigned long *bitmap;
1336 int syscall_nr;
1337
1338 WARN_ON_ONCE(!chan->sc_table);
1339
1340 syscall_name = get_syscall_name(event);
1341
1342 switch (event->u.syscall.abi) {
1343 case LTTNG_SYSCALL_ABI_NATIVE:
1344 syscall_nr = get_syscall_nr(syscall_name);
1345 break;
1346 case LTTNG_SYSCALL_ABI_COMPAT:
1347 syscall_nr = get_compat_syscall_nr(syscall_name);
1348 break;
1349 default:
1350 return -EINVAL;
1351 }
1352 if (syscall_nr < 0)
1353 return -ENOENT;
1354
1355 switch (event->u.syscall.entryexit) {
1356 case LTTNG_SYSCALL_ENTRY:
1357 switch (event->u.syscall.abi) {
1358 case LTTNG_SYSCALL_ABI_NATIVE:
1359 bitmap = filter->sc_entry;
1360 break;
1361 case LTTNG_SYSCALL_ABI_COMPAT:
1362 bitmap = filter->sc_compat_entry;
1363 break;
1364 default:
1365 return -EINVAL;
1366 }
1367 break;
1368 case LTTNG_SYSCALL_EXIT:
1369 switch (event->u.syscall.abi) {
1370 case LTTNG_SYSCALL_ABI_NATIVE:
1371 bitmap = filter->sc_exit;
1372 break;
1373 case LTTNG_SYSCALL_ABI_COMPAT:
1374 bitmap = filter->sc_compat_exit;
1375 break;
1376 default:
1377 return -EINVAL;
1378 }
1379 break;
1380 default:
1381 return -EINVAL;
1382 }
1383 if (!test_bit(syscall_nr, bitmap))
1384 return -EEXIST;
1385 bitmap_clear(bitmap, syscall_nr, 1);
1386
1387 return 0;
1388 }
1389
1390 int lttng_syscall_filter_disable_event_notifier(
1391 struct lttng_event_notifier *event_notifier)
1392 {
1393 list_del_rcu(&event_notifier->u.syscall.node);
1394 return 0;
1395 }
1396
1397 static
1398 const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1399 {
1400 const struct trace_syscall_entry *entry;
1401 int iter = 0;
1402
1403 for (entry = sc_table;
1404 entry < sc_table + ARRAY_SIZE(sc_table);
1405 entry++) {
1406 if (iter++ >= *pos)
1407 return entry;
1408 }
1409 for (entry = compat_sc_table;
1410 entry < compat_sc_table + ARRAY_SIZE(compat_sc_table);
1411 entry++) {
1412 if (iter++ >= *pos)
1413 return entry;
1414 }
1415 /* End of list */
1416 return NULL;
1417 }
1418
1419 static
1420 void *syscall_list_start(struct seq_file *m, loff_t *pos)
1421 {
1422 return (void *) syscall_list_get_entry(pos);
1423 }
1424
1425 static
1426 void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1427 {
1428 (*ppos)++;
1429 return (void *) syscall_list_get_entry(ppos);
1430 }
1431
1432 static
1433 void syscall_list_stop(struct seq_file *m, void *p)
1434 {
1435 }
1436
1437 static
1438 int get_sc_table(const struct trace_syscall_entry *entry,
1439 const struct trace_syscall_entry **table,
1440 unsigned int *bitness)
1441 {
1442 if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) {
1443 if (bitness)
1444 *bitness = BITS_PER_LONG;
1445 if (table)
1446 *table = sc_table;
1447 return 0;
1448 }
1449 if (!(entry >= compat_sc_table
1450 && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))) {
1451 return -EINVAL;
1452 }
1453 if (bitness)
1454 *bitness = 32;
1455 if (table)
1456 *table = compat_sc_table;
1457 return 0;
1458 }
1459
1460 static
1461 int syscall_list_show(struct seq_file *m, void *p)
1462 {
1463 const struct trace_syscall_entry *table, *entry = p;
1464 unsigned int bitness;
1465 unsigned long index;
1466 int ret;
1467 const char *name;
1468
1469 ret = get_sc_table(entry, &table, &bitness);
1470 if (ret)
1471 return ret;
1472 if (!entry->desc)
1473 return 0;
1474 if (table == sc_table) {
1475 index = entry - table;
1476 name = &entry->desc->name[strlen(SYSCALL_ENTRY_STR)];
1477 } else {
1478 index = (entry - table) + ARRAY_SIZE(sc_table);
1479 name = &entry->desc->name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
1480 }
1481 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
1482 index, name, bitness);
1483 return 0;
1484 }
1485
1486 static
1487 const struct seq_operations lttng_syscall_list_seq_ops = {
1488 .start = syscall_list_start,
1489 .next = syscall_list_next,
1490 .stop = syscall_list_stop,
1491 .show = syscall_list_show,
1492 };
1493
1494 static
1495 int lttng_syscall_list_open(struct inode *inode, struct file *file)
1496 {
1497 return seq_open(file, &lttng_syscall_list_seq_ops);
1498 }
1499
1500 const struct file_operations lttng_syscall_list_fops = {
1501 .owner = THIS_MODULE,
1502 .open = lttng_syscall_list_open,
1503 .read = seq_read,
1504 .llseek = seq_lseek,
1505 .release = seq_release,
1506 };
1507
1508 /*
1509 * A syscall is enabled if it is traced for either entry or exit.
1510 */
1511 long lttng_channel_syscall_mask(struct lttng_channel *channel,
1512 struct lttng_kernel_syscall_mask __user *usyscall_mask)
1513 {
1514 uint32_t len, sc_tables_len, bitmask_len;
1515 int ret = 0, bit;
1516 char *tmp_mask;
1517 struct lttng_syscall_filter *filter;
1518
1519 ret = get_user(len, &usyscall_mask->len);
1520 if (ret)
1521 return ret;
1522 sc_tables_len = get_sc_tables_len();
1523 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1524 if (len < sc_tables_len) {
1525 return put_user(sc_tables_len, &usyscall_mask->len);
1526 }
1527 /* Array is large enough, we can copy array to user-space. */
1528 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1529 if (!tmp_mask)
1530 return -ENOMEM;
1531 filter = channel->sc_filter;
1532
1533 for (bit = 0; bit < ARRAY_SIZE(sc_table); bit++) {
1534 char state;
1535
1536 if (channel->sc_table) {
1537 if (!READ_ONCE(channel->syscall_all) && filter)
1538 state = test_bit(bit, filter->sc_entry)
1539 || test_bit(bit, filter->sc_exit);
1540 else
1541 state = 1;
1542 } else {
1543 state = 0;
1544 }
1545 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
1546 }
1547 for (; bit < sc_tables_len; bit++) {
1548 char state;
1549
1550 if (channel->compat_sc_table) {
1551 if (!READ_ONCE(channel->syscall_all) && filter)
1552 state = test_bit(bit - ARRAY_SIZE(sc_table),
1553 filter->sc_compat_entry)
1554 || test_bit(bit - ARRAY_SIZE(sc_table),
1555 filter->sc_compat_exit);
1556 else
1557 state = 1;
1558 } else {
1559 state = 0;
1560 }
1561 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
1562 }
1563 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1564 ret = -EFAULT;
1565 kfree(tmp_mask);
1566 return ret;
1567 }
1568
1569 int lttng_abi_syscall_list(void)
1570 {
1571 struct file *syscall_list_file;
1572 int file_fd, ret;
1573
1574 file_fd = lttng_get_unused_fd();
1575 if (file_fd < 0) {
1576 ret = file_fd;
1577 goto fd_error;
1578 }
1579
1580 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
1581 &lttng_syscall_list_fops,
1582 NULL, O_RDWR);
1583 if (IS_ERR(syscall_list_file)) {
1584 ret = PTR_ERR(syscall_list_file);
1585 goto file_error;
1586 }
1587 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
1588 if (ret < 0)
1589 goto open_error;
1590 fd_install(file_fd, syscall_list_file);
1591 return file_fd;
1592
1593 open_error:
1594 fput(syscall_list_file);
1595 file_error:
1596 put_unused_fd(file_fd);
1597 fd_error:
1598 return ret;
1599 }
This page took 0.080404 seconds and 4 git commands to generate.