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