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