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