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