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