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