Fix: lttng_event_enabler_create_syscall_events_if_missing() uninitialized ret variable
[lttng-modules.git] / src / lttng-syscalls.c
CommitLineData
b7cdc182 1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
9f36eaed 2 *
259b6cb3
MD
3 * lttng-syscalls.c
4 *
2faf7d1b 5 * LTTng syscall probes.
259b6cb3 6 *
886d51a3 7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
259b6cb3
MD
8 */
9
10#include <linux/module.h>
11#include <linux/slab.h>
6333ace3 12#include <linux/compat.h>
abc0446a 13#include <linux/err.h>
80f87dd2 14#include <linux/bitmap.h>
7ca580f8
MD
15#include <linux/in.h>
16#include <linux/in6.h>
2d2464bd 17#include <linux/seq_file.h>
d4291869 18#include <linux/stringify.h>
082d4946
MD
19#include <linux/file.h>
20#include <linux/anon_inodes.h>
c8dfb724 21#include <linux/fcntl.h>
3cf55950 22#include <linux/mman.h>
259b6cb3
MD
23#include <asm/ptrace.h>
24#include <asm/syscall.h>
25
a071f25d 26#include <lttng/bitfield.h>
241ae9a8
MD
27#include <wrapper/tracepoint.h>
28#include <wrapper/file.h>
29#include <wrapper/rcu.h>
1b7b9c65 30#include <wrapper/syscall.h>
5987e66c 31#include <wrapper/limits.h>
2df37e95 32#include <lttng/events.h>
6f156b09 33#include <lttng/events-internal.h>
8a8ac9a8 34#include <lttng/utils.h>
259b6cb3 35
ebcc64cd
FD
36#include "lttng-syscalls.h"
37
6333ace3 38#ifndef CONFIG_COMPAT
bfa949bf
MD
39# ifndef is_compat_task
40# define is_compat_task() (0)
41# endif
6333ace3
MD
42#endif
43
1aa3298b
MD
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
5b7ac358
MD
49enum sc_type {
50 SC_TYPE_ENTRY,
51 SC_TYPE_EXIT,
52 SC_TYPE_COMPAT_ENTRY,
53 SC_TYPE_COMPAT_EXIT,
54};
55
d4291869
MD
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)
5b7ac358 65
2d6d88c6 66void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
2d6d88c6 67void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
259b6cb3 68
3a523f5b
MD
69/*
70 * Forward declarations for old kernels.
71 */
72struct mmsghdr;
73struct rlimit64;
74struct oldold_utsname;
75struct old_utsname;
76struct sel_arg_struct;
77struct mmap_arg_struct;
c0b71117 78struct file_handle;
a292e6f1 79struct user_msghdr;
3a523f5b 80
9eb15e8b
MJ
81/*
82 * Forward declaration for kernels >= 5.6
83 */
84struct timex;
edfdcb68
MJ
85struct timeval;
86struct itimerval;
87struct itimerspec;
88
5f4c791e 89#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
edfdcb68
MJ
90typedef __kernel_old_time_t time_t;
91#endif
9eb15e8b 92
80f87dd2
MD
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
259b6cb3
MD
99/*
100 * Create LTTng tracepoint probes.
101 */
102#define LTTNG_PACKAGE_BUILD
103#define CREATE_TRACE_POINTS
2655f9ad 104#define TP_MODULE_NOINIT
c075712b 105#define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
259b6cb3 106
a93244f8
MD
107#define PARAMS(args...) args
108
5b7ac358 109/* Handle unknown syscalls */
72a52753 110#undef TRACE_SYSTEM
5b7ac358 111#define TRACE_SYSTEM syscalls_unknown
241ae9a8 112#include <instrumentation/syscalls/headers/syscalls_unknown.h>
5b7ac358
MD
113#undef TRACE_SYSTEM
114
5b7ac358 115#undef TP_PROBE_CB
fc4f7161 116
e42c4f49
FD
117extern const struct trace_syscall_table sc_table;
118extern const struct trace_syscall_table compat_sc_table;
5b7ac358 119
2d6d88c6 120/* Event syscall exit table */
e42c4f49
FD
121extern const struct trace_syscall_table sc_exit_table;
122extern const struct trace_syscall_table compat_sc_exit_table;
ebcc64cd
FD
123
124
fc4f7161
MD
125#undef SC_EXIT
126
a93244f8 127#undef CREATE_SYSCALL_TABLE
2faf7d1b 128
80f87dd2 129struct lttng_syscall_filter {
badfe9f5
MD
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);
7f52f0d4
MD
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];
80f87dd2
MD
143};
144
3b82c4e1 145static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 146 struct pt_regs *regs, long id)
f405cfce 147{
1b7b9c65 148 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 149 struct lttng_kernel_event_common_private *event_priv;
f405cfce 150
1b7b9c65 151 lttng_syscall_get_arguments(current, regs, args);
a67ba386 152 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
8a8ac9a8 153 if (unlikely(in_compat_syscall()))
e2d5dbc7 154 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8 155 else
e2d5dbc7 156 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8
FD
157 }
158}
159
63aa9160 160static __always_inline
e2d5dbc7 161void syscall_entry_event_call_func(struct hlist_head *action_list,
3b82c4e1 162 void *func, unsigned int nrargs,
63aa9160 163 struct pt_regs *regs)
259b6cb3 164{
a67ba386 165 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 166
63aa9160 167 switch (nrargs) {
259b6cb3
MD
168 case 0:
169 {
63aa9160 170 void (*fptr)(void *__data) = func;
259b6cb3 171
e2d5dbc7
MD
172 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
173 fptr(event_priv->pub);
259b6cb3
MD
174 break;
175 }
176 case 1:
177 {
63aa9160 178 void (*fptr)(void *__data, unsigned long arg0) = func;
1b7b9c65 179 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 180
1b7b9c65 181 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
182 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
183 fptr(event_priv->pub, args[0]);
259b6cb3
MD
184 break;
185 }
186 case 2:
187 {
188 void (*fptr)(void *__data,
189 unsigned long arg0,
63aa9160 190 unsigned long arg1) = func;
1b7b9c65 191 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 192
1b7b9c65 193 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
194 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
195 fptr(event_priv->pub, args[0], args[1]);
259b6cb3
MD
196 break;
197 }
198 case 3:
199 {
200 void (*fptr)(void *__data,
201 unsigned long arg0,
202 unsigned long arg1,
63aa9160 203 unsigned long arg2) = func;
1b7b9c65 204 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 205
1b7b9c65 206 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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]);
259b6cb3
MD
209 break;
210 }
211 case 4:
212 {
213 void (*fptr)(void *__data,
214 unsigned long arg0,
215 unsigned long arg1,
216 unsigned long arg2,
63aa9160 217 unsigned long arg3) = func;
1b7b9c65 218 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 219
1b7b9c65 220 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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]);
259b6cb3
MD
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,
63aa9160 232 unsigned long arg4) = func;
1b7b9c65 233 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 234
1b7b9c65 235 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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]);
259b6cb3
MD
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,
63aa9160 248 unsigned long arg5) = func;
1b7b9c65 249 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 250
1b7b9c65 251 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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],
3b82c4e1 254 args[3], args[4], args[5]);
8a8ac9a8
FD
255 break;
256 }
257 default:
258 break;
259 }
260}
261
63aa9160
FD
262void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
263{
0bb716a8 264 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1 265 struct hlist_head *action_list, *unknown_action_list;
63aa9160
FD
266 const struct trace_syscall_entry *table, *entry;
267 size_t table_len;
268
269 if (unlikely(in_compat_syscall())) {
0bb716a8 270 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
271
272 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 273 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
63aa9160
FD
274 /* System call filtered out. */
275 return;
276 }
ebcc64cd
FD
277 table = compat_sc_table.table;
278 table_len = compat_sc_table.len;
0bb716a8 279 unknown_action_list = &syscall_table->compat_unknown_syscall_dispatch;
63aa9160 280 } else {
0bb716a8 281 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
282
283 if (id < 0 || id >= NR_syscalls
0bb716a8 284 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
63aa9160
FD
285 /* System call filtered out. */
286 return;
287 }
ebcc64cd
FD
288 table = sc_table.table;
289 table_len = sc_table.len;
0bb716a8 290 unknown_action_list = &syscall_table->unknown_syscall_dispatch;
63aa9160
FD
291 }
292 if (unlikely(id < 0 || id >= table_len)) {
3b82c4e1 293 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
294 return;
295 }
3b82c4e1
MD
296
297 entry = &table[id];
298 if (!entry->event_func) {
299 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
300 return;
301 }
3b82c4e1
MD
302
303 if (unlikely(in_compat_syscall())) {
0bb716a8 304 action_list = &syscall_table->compat_syscall_dispatch[id];
3b82c4e1 305 } else {
0bb716a8 306 action_list = &syscall_table->syscall_dispatch[id];
3b82c4e1
MD
307 }
308 if (unlikely(hlist_empty(action_list)))
309 return;
310
e2d5dbc7 311 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
63aa9160
FD
312}
313
3b82c4e1 314static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 315 struct pt_regs *regs, long id, long ret)
5b7ac358 316{
1b7b9c65 317 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 318 struct lttng_kernel_event_common_private *event_priv;
5b7ac358 319
1b7b9c65 320 lttng_syscall_get_arguments(current, regs, args);
a67ba386 321 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
3b82c4e1 322 if (unlikely(in_compat_syscall()))
e2d5dbc7 323 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
3b82c4e1
MD
324 args);
325 else
e2d5dbc7 326 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
3b82c4e1 327 }
5b7ac358
MD
328}
329
3b82c4e1 330static __always_inline
e2d5dbc7 331void syscall_exit_event_call_func(struct hlist_head *action_list,
3b82c4e1
MD
332 void *func, unsigned int nrargs,
333 struct pt_regs *regs, long ret)
5b7ac358 334{
a67ba386 335 struct lttng_kernel_event_common_private *event_priv;
badfe9f5 336
3b82c4e1 337 switch (nrargs) {
5b7ac358
MD
338 case 0:
339 {
3b82c4e1 340 void (*fptr)(void *__data, long ret) = func;
5b7ac358 341
e2d5dbc7
MD
342 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
343 fptr(event_priv->pub, ret);
5b7ac358
MD
344 break;
345 }
346 case 1:
347 {
348 void (*fptr)(void *__data,
fc4f7161 349 long ret,
3b82c4e1 350 unsigned long arg0) = func;
1b7b9c65 351 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 352
1b7b9c65 353 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
354 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
355 fptr(event_priv->pub, ret, args[0]);
5b7ac358
MD
356 break;
357 }
358 case 2:
359 {
360 void (*fptr)(void *__data,
fc4f7161 361 long ret,
5b7ac358 362 unsigned long arg0,
3b82c4e1 363 unsigned long arg1) = func;
1b7b9c65 364 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 365
1b7b9c65 366 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
367 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
368 fptr(event_priv->pub, ret, args[0], args[1]);
5b7ac358
MD
369 break;
370 }
371 case 3:
372 {
373 void (*fptr)(void *__data,
fc4f7161 374 long ret,
5b7ac358
MD
375 unsigned long arg0,
376 unsigned long arg1,
3b82c4e1 377 unsigned long arg2) = func;
1b7b9c65 378 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 379
1b7b9c65 380 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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]);
5b7ac358
MD
383 break;
384 }
385 case 4:
386 {
387 void (*fptr)(void *__data,
fc4f7161 388 long ret,
5b7ac358
MD
389 unsigned long arg0,
390 unsigned long arg1,
391 unsigned long arg2,
3b82c4e1 392 unsigned long arg3) = func;
1b7b9c65 393 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 394
1b7b9c65 395 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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]);
5b7ac358
MD
398 break;
399 }
400 case 5:
401 {
402 void (*fptr)(void *__data,
fc4f7161 403 long ret,
5b7ac358
MD
404 unsigned long arg0,
405 unsigned long arg1,
406 unsigned long arg2,
407 unsigned long arg3,
3b82c4e1 408 unsigned long arg4) = func;
1b7b9c65 409 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 410
1b7b9c65 411 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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]);
5b7ac358
MD
414 break;
415 }
416 case 6:
417 {
418 void (*fptr)(void *__data,
fc4f7161 419 long ret,
5b7ac358
MD
420 unsigned long arg0,
421 unsigned long arg1,
422 unsigned long arg2,
423 unsigned long arg3,
424 unsigned long arg4,
3b82c4e1 425 unsigned long arg5) = func;
1b7b9c65 426 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 427
1b7b9c65 428 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
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],
3b82c4e1 431 args[3], args[4], args[5]);
5b7ac358
MD
432 break;
433 }
434 default:
435 break;
436 }
437}
438
3b82c4e1
MD
439void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
440{
0bb716a8 441 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1
MD
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())) {
0bb716a8 450 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
451
452 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 453 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
3b82c4e1
MD
454 /* System call filtered out. */
455 return;
456 }
ebcc64cd
FD
457 table = compat_sc_exit_table.table;
458 table_len = compat_sc_exit_table.len;
0bb716a8 459 unknown_action_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
3b82c4e1 460 } else {
0bb716a8 461 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
462
463 if (id < 0 || id >= NR_syscalls
0bb716a8 464 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
3b82c4e1
MD
465 /* System call filtered out. */
466 return;
467 }
ebcc64cd
FD
468 table = sc_exit_table.table;
469 table_len = sc_exit_table.len;
0bb716a8 470 unknown_action_list = &syscall_table->unknown_syscall_exit_dispatch;
3b82c4e1
MD
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())) {
0bb716a8 484 action_list = &syscall_table->compat_syscall_exit_dispatch[id];
3b82c4e1 485 } else {
0bb716a8 486 action_list = &syscall_table->syscall_exit_dispatch[id];
3b82c4e1
MD
487 }
488 if (unlikely(hlist_empty(action_list)))
489 return;
490
e2d5dbc7 491 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
3b82c4e1
MD
492 regs, ret);
493}
494
0bb716a8
MD
495static
496struct lttng_kernel_syscall_table *get_syscall_table_from_enabler(struct lttng_event_enabler_common *event_enabler)
8a8ac9a8 497{
0bb716a8
MD
498 switch (event_enabler->enabler_type) {
499 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
500 {
1ae083ba
MD
501 struct lttng_event_recorder_enabler *event_recorder_enabler =
502 container_of(event_enabler, struct lttng_event_recorder_enabler, parent);
0bb716a8 503 return &event_recorder_enabler->chan->priv->parent.syscall_table;
8a8ac9a8 504 }
0bb716a8
MD
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;
8a8ac9a8 510 }
0bb716a8
MD
511 default:
512 return NULL;
8a8ac9a8 513 }
0bb716a8 514}
8a8ac9a8 515
0bb716a8
MD
516static
517struct 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;
8a8ac9a8 534 }
8a8ac9a8 535}
0bb716a8 536
5408b6d6
MD
537static
538void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common *syscall_event_enabler,
99903379 539 const struct lttng_kernel_event_desc *desc, enum sc_type type, unsigned int syscall_nr)
5408b6d6
MD
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);
c3fb484e 580 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 581 lttng_event_enabler_destroy(&event_recorder_enabler->parent);
c3fb484e 582 if (IS_ERR(event)) {
5408b6d6
MD
583 printk(KERN_INFO "Unable to create event recorder %s\n", desc->event_name);
584 return;
585 }
9cd106a6 586 event->priv->u.syscall.syscall_id = syscall_nr;
5408b6d6
MD
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);
c3fb484e 628 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 629 lttng_event_enabler_destroy(&event_notifier_enabler->parent);
c3fb484e 630 if (IS_ERR(event)) {
5408b6d6
MD
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
49c50022 642static
67233a18
MD
643void 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)
259b6cb3 645{
063f0825
MD
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;
259b6cb3 648 unsigned int i;
49c50022 649
1d303f69
MD
650#ifndef CONFIG_COMPAT
651 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 652 return;
1d303f69 653#endif
67233a18 654 /* iterate over all syscall and create event that match */
49c50022 655 for (i = 0; i < table_len; i++) {
19bef247 656 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 657 struct hlist_head *head;
6768203a 658 bool found = false;
49c50022 659
063f0825 660 desc = table[i].desc;
49c50022
MD
661 if (!desc) {
662 /* Unknown syscall */
663 continue;
664 }
063f0825
MD
665
666 if (!lttng_desc_match_enabler(desc, syscall_event_enabler_common))
3b82c4e1 667 continue;
063f0825 668
49c50022 669 /*
3b82c4e1 670 * Check if already created.
49c50022 671 */
0def9170 672 head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
19bef247 673 lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
6768203a
MD
674 if (lttng_event_enabler_desc_match_event(syscall_event_enabler_common, desc, event_priv->pub)) {
675 found = true;
676 break;
677 }
3b82c4e1
MD
678 }
679 if (found)
49c50022 680 continue;
3b82c4e1 681
99903379 682 lttng_syscall_event_enabler_create_event(syscall_event_enabler_common, desc, type, i);
49c50022 683 }
49c50022
MD
684}
685
552f7c79
MD
686static
687bool 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
9f6f4507
MD
700static
701void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type)
702{
9f6f4507
MD
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;
9f6f4507
MD
706 bool found = false;
707 struct hlist_head *head;
708
1d303f69
MD
709#ifndef CONFIG_COMPAT
710 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 711 return;
1d303f69 712#endif
552f7c79
MD
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
9f6f4507
MD
725 switch (type) {
726 case SC_TYPE_ENTRY:
727 desc = &__event_desc___syscall_entry_unknown;
9f6f4507
MD
728 break;
729 case SC_TYPE_EXIT:
730 desc = &__event_desc___syscall_exit_unknown;
9f6f4507
MD
731 break;
732 case SC_TYPE_COMPAT_ENTRY:
733 desc = &__event_desc___compat_syscall_entry_unknown;
9f6f4507
MD
734 break;
735 case SC_TYPE_COMPAT_EXIT:
736 desc = &__event_desc___compat_syscall_exit_unknown;
9f6f4507
MD
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) {
6768203a 747 if (lttng_event_enabler_desc_match_event(event_enabler, desc, event_priv->pub)) {
9f6f4507 748 found = true;
6768203a
MD
749 break;
750 }
9f6f4507
MD
751 }
752 if (!found)
99903379 753 lttng_syscall_event_enabler_create_event(event_enabler, desc, type, -1U);
9f6f4507
MD
754}
755
d26015f6 756static
15a00134 757void lttng_syscall_event_enabler_create_matching_events(struct lttng_event_enabler_common *event_enabler)
49c50022 758{
15a00134 759 enum lttng_kernel_abi_syscall_entryexit entryexit = event_enabler->event_param.u.syscall.entryexit;
5b7ac358 760
15a00134
MD
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 }
1ab4126a 769
15a00134
MD
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 }
259b6cb3
MD
778}
779
780/*
8a8ac9a8
FD
781 * Should be called with sessions lock held.
782 */
b2f63bde 783int lttng_event_enabler_create_syscall_events_if_missing(struct lttng_event_enabler_common *syscall_event_enabler)
8a8ac9a8 784{
d26015f6
MD
785 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(syscall_event_enabler);
786 int ret;
8a8ac9a8 787
0bb716a8 788 if (!syscall_table->syscall_dispatch) {
d26015f6 789 /* create syscall table mapping syscall to events */
0bb716a8
MD
790 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
791 if (!syscall_table->syscall_dispatch)
8a8ac9a8 792 return -ENOMEM;
8a8ac9a8 793 }
0bb716a8 794 if (!syscall_table->syscall_exit_dispatch) {
d26015f6
MD
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);
0bb716a8 797 if (!syscall_table->syscall_exit_dispatch)
8a8ac9a8 798 return -ENOMEM;
8a8ac9a8
FD
799 }
800
801#ifdef CONFIG_COMPAT
0bb716a8 802 if (!syscall_table->compat_syscall_dispatch) {
d26015f6 803 /* create syscall table mapping compat syscall to events */
0bb716a8
MD
804 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
805 if (!syscall_table->compat_syscall_dispatch)
8a8ac9a8 806 return -ENOMEM;
8a8ac9a8
FD
807 }
808
0bb716a8 809 if (!syscall_table->compat_syscall_exit_dispatch) {
d26015f6
MD
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);
0bb716a8 812 if (!syscall_table->compat_syscall_exit_dispatch)
8a8ac9a8 813 return -ENOMEM;
8a8ac9a8
FD
814 }
815#endif
0bb716a8
MD
816 if (!syscall_table->sc_filter) {
817 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
8a8ac9a8 818 GFP_KERNEL);
0bb716a8 819 if (!syscall_table->sc_filter)
8a8ac9a8
FD
820 return -ENOMEM;
821 }
822
0bb716a8 823 if (!syscall_table->sys_enter_registered) {
8a8ac9a8 824 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
0bb716a8 825 (void *) syscall_entry_event_probe, syscall_table);
8a8ac9a8
FD
826 if (ret)
827 return ret;
0bb716a8 828 syscall_table->sys_enter_registered = 1;
8a8ac9a8 829 }
0bb716a8 830 if (!syscall_table->sys_exit_registered) {
8a8ac9a8 831 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
0bb716a8 832 (void *) syscall_exit_event_probe, syscall_table);
8a8ac9a8
FD
833 if (ret) {
834 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 835 (void *) syscall_entry_event_probe, syscall_table));
8a8ac9a8
FD
836 return ret;
837 }
0bb716a8 838 syscall_table->sys_exit_registered = 1;
8a8ac9a8 839 }
0fab709d 840
86e12a51
MD
841 lttng_syscall_event_enabler_create_matching_events(syscall_event_enabler);
842
fad51c94 843 return 0;
8a8ac9a8
FD
844}
845
6053e75e 846int lttng_syscalls_unregister_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
259b6cb3
MD
847{
848 int ret;
849
0bb716a8 850 if (!syscall_table->syscall_dispatch)
259b6cb3 851 return 0;
0bb716a8 852 if (syscall_table->sys_enter_registered) {
2d9cd7f3 853 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 854 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
855 if (ret)
856 return ret;
0bb716a8 857 syscall_table->sys_enter_registered = 0;
80f87dd2 858 }
0bb716a8 859 if (syscall_table->sys_exit_registered) {
2d9cd7f3 860 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
0bb716a8 861 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
862 if (ret)
863 return ret;
0bb716a8 864 syscall_table->sys_exit_registered = 0;
80f87dd2 865 }
badfe9f5
MD
866 return 0;
867}
868
6053e75e 869int lttng_syscalls_destroy_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
badfe9f5 870{
0bb716a8
MD
871 kfree(syscall_table->syscall_dispatch);
872 kfree(syscall_table->syscall_exit_dispatch);
49c50022 873#ifdef CONFIG_COMPAT
0bb716a8
MD
874 kfree(syscall_table->compat_syscall_dispatch);
875 kfree(syscall_table->compat_syscall_exit_dispatch);
49c50022 876#endif
0bb716a8 877 kfree(syscall_table->sc_filter);
80f87dd2
MD
878 return 0;
879}
880
12e579db
MD
881static
882uint32_t get_sc_tables_len(void)
883{
ebcc64cd 884 return sc_table.len + compat_sc_table.len;
12e579db
MD
885}
886
badfe9f5 887static
ade8a729
FD
888const char *get_syscall_name(const char *desc_name,
889 enum lttng_syscall_abi abi,
890 enum lttng_syscall_entryexit entryexit)
80f87dd2 891{
badfe9f5 892 size_t prefix_len = 0;
80f87dd2 893
80f87dd2 894
ade8a729 895 switch (entryexit) {
badfe9f5 896 case LTTNG_SYSCALL_ENTRY:
ade8a729 897 switch (abi) {
badfe9f5
MD
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;
80f87dd2 904 }
badfe9f5
MD
905 break;
906 case LTTNG_SYSCALL_EXIT:
ade8a729 907 switch (abi) {
badfe9f5
MD
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;
80f87dd2 914 }
badfe9f5 915 break;
80f87dd2 916 }
badfe9f5 917 WARN_ON_ONCE(prefix_len == 0);
ade8a729 918 return desc_name + prefix_len;
badfe9f5
MD
919}
920
ade8a729
FD
921static
922int lttng_syscall_filter_enable(
923 struct lttng_syscall_filter *filter,
924 const char *desc_name, enum lttng_syscall_abi abi,
99903379
MD
925 enum lttng_syscall_entryexit entryexit,
926 unsigned int syscall_id)
badfe9f5 927{
badfe9f5
MD
928 const char *syscall_name;
929 unsigned long *bitmap;
7f52f0d4 930 u32 *refcount_map;
badfe9f5 931
ade8a729 932 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 933
ade8a729 934 switch (entryexit) {
badfe9f5 935 case LTTNG_SYSCALL_ENTRY:
ade8a729 936 switch (abi) {
badfe9f5
MD
937 case LTTNG_SYSCALL_ABI_NATIVE:
938 bitmap = filter->sc_entry;
7f52f0d4 939 refcount_map = filter->sc_entry_refcount_map;
badfe9f5
MD
940 break;
941 case LTTNG_SYSCALL_ABI_COMPAT:
942 bitmap = filter->sc_compat_entry;
7f52f0d4 943 refcount_map = filter->sc_compat_entry_refcount_map;
badfe9f5 944 break;
6d9694d8
MD
945 default:
946 return -EINVAL;
80f87dd2 947 }
badfe9f5
MD
948 break;
949 case LTTNG_SYSCALL_EXIT:
ade8a729 950 switch (abi) {
badfe9f5
MD
951 case LTTNG_SYSCALL_ABI_NATIVE:
952 bitmap = filter->sc_exit;
7f52f0d4 953 refcount_map = filter->sc_exit_refcount_map;
badfe9f5
MD
954 break;
955 case LTTNG_SYSCALL_ABI_COMPAT:
956 bitmap = filter->sc_compat_exit;
7f52f0d4 957 refcount_map = filter->sc_compat_exit_refcount_map;
badfe9f5 958 break;
6d9694d8
MD
959 default:
960 return -EINVAL;
80f87dd2 961 }
badfe9f5
MD
962 break;
963 default:
964 return -EINVAL;
80f87dd2 965 }
99903379 966 if (refcount_map[syscall_id] == U32_MAX)
7f52f0d4 967 return -EOVERFLOW;
99903379
MD
968 if (refcount_map[syscall_id]++ == 0)
969 bitmap_set(bitmap, syscall_id, 1);
80f87dd2 970 return 0;
80f87dd2
MD
971}
972
9b2f1c54 973int lttng_syscall_filter_enable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 974{
9b2f1c54 975 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
9cd106a6
MD
976 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
977 struct hlist_head *dispatch_list;
ca62543e 978 int ret = 0;
8a8ac9a8 979
9b2f1c54 980 WARN_ON_ONCE(event->priv->instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 981
99903379
MD
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 }
9cd106a6 997 break;
99903379
MD
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 }
9cd106a6
MD
1010 break;
1011 default:
1012 ret = -EINVAL;
1013 goto end;
1014 }
99903379
MD
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 }
8a8ac9a8 1035 break;
99903379
MD
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 }
8a8ac9a8 1048 break;
6866b1c7
MJ
1049 default:
1050 ret = -EINVAL;
1051 goto end;
8a8ac9a8 1052 }
8a8ac9a8 1053 }
9cd106a6
MD
1054
1055 hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_list);
8a8ac9a8 1056end:
9b2f1c54 1057 return ret;
ade8a729
FD
1058}
1059
1060static
f2db8be3 1061int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter,
ade8a729 1062 const char *desc_name, enum lttng_syscall_abi abi,
99903379
MD
1063 enum lttng_syscall_entryexit entryexit,
1064 unsigned int syscall_id)
ade8a729 1065{
badfe9f5
MD
1066 const char *syscall_name;
1067 unsigned long *bitmap;
7f52f0d4 1068 u32 *refcount_map;
80f87dd2 1069
ade8a729 1070 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1071
ade8a729 1072 switch (entryexit) {
badfe9f5 1073 case LTTNG_SYSCALL_ENTRY:
ade8a729 1074 switch (abi) {
badfe9f5
MD
1075 case LTTNG_SYSCALL_ABI_NATIVE:
1076 bitmap = filter->sc_entry;
7f52f0d4 1077 refcount_map = filter->sc_entry_refcount_map;
badfe9f5
MD
1078 break;
1079 case LTTNG_SYSCALL_ABI_COMPAT:
1080 bitmap = filter->sc_compat_entry;
7f52f0d4 1081 refcount_map = filter->sc_compat_entry_refcount_map;
badfe9f5 1082 break;
6d9694d8
MD
1083 default:
1084 return -EINVAL;
80f87dd2 1085 }
badfe9f5
MD
1086 break;
1087 case LTTNG_SYSCALL_EXIT:
ade8a729 1088 switch (abi) {
badfe9f5
MD
1089 case LTTNG_SYSCALL_ABI_NATIVE:
1090 bitmap = filter->sc_exit;
7f52f0d4 1091 refcount_map = filter->sc_exit_refcount_map;
badfe9f5
MD
1092 break;
1093 case LTTNG_SYSCALL_ABI_COMPAT:
1094 bitmap = filter->sc_compat_exit;
7f52f0d4 1095 refcount_map = filter->sc_compat_exit_refcount_map;
badfe9f5 1096 break;
6d9694d8
MD
1097 default:
1098 return -EINVAL;
80f87dd2 1099 }
badfe9f5
MD
1100 break;
1101 default:
1102 return -EINVAL;
80f87dd2 1103 }
99903379 1104 if (refcount_map[syscall_id] == 0)
7f52f0d4 1105 return -ENOENT;
99903379
MD
1106 if (--refcount_map[syscall_id] == 0)
1107 bitmap_clear(bitmap, syscall_id, 1);
badfe9f5 1108 return 0;
259b6cb3 1109}
2d2464bd 1110
9b2f1c54 1111int lttng_syscall_filter_disable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 1112{
9b2f1c54 1113 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
7f52f0d4 1114 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
8a8ac9a8
FD
1115 int ret;
1116
99903379
MD
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 }
9cd106a6 1125 hlist_del_rcu(&event->priv->u.syscall.node);
8a8ac9a8
FD
1126 return 0;
1127}
1128
9cb5be7e
MD
1129void 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
552f7c79 1135 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
9cb5be7e 1136 return;
9cb5be7e
MD
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
2d2464bd
MD
1145static
1146const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1147{
1148 const struct trace_syscall_entry *entry;
1149 int iter = 0;
1150
ebcc64cd
FD
1151 for (entry = sc_table.table;
1152 entry < sc_table.table + sc_table.len;
2d2464bd
MD
1153 entry++) {
1154 if (iter++ >= *pos)
1155 return entry;
1156 }
ebcc64cd
FD
1157 for (entry = compat_sc_table.table;
1158 entry < compat_sc_table.table + compat_sc_table.len;
2d2464bd
MD
1159 entry++) {
1160 if (iter++ >= *pos)
1161 return entry;
1162 }
1163 /* End of list */
1164 return NULL;
1165}
1166
1167static
1168void *syscall_list_start(struct seq_file *m, loff_t *pos)
1169{
1170 return (void *) syscall_list_get_entry(pos);
1171}
1172
1173static
1174void *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
1180static
1181void syscall_list_stop(struct seq_file *m, void *p)
1182{
1183}
1184
12e579db
MD
1185static
1186int get_sc_table(const struct trace_syscall_entry *entry,
1187 const struct trace_syscall_entry **table,
1188 unsigned int *bitness)
1189{
ebcc64cd 1190 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
12e579db
MD
1191 if (bitness)
1192 *bitness = BITS_PER_LONG;
1193 if (table)
ebcc64cd 1194 *table = sc_table.table;
12e579db
MD
1195 return 0;
1196 }
ebcc64cd
FD
1197 if (!(entry >= compat_sc_table.table
1198 && entry < compat_sc_table.table + compat_sc_table.len)) {
12e579db
MD
1199 return -EINVAL;
1200 }
1201 if (bitness)
1202 *bitness = 32;
1203 if (table)
ebcc64cd 1204 *table = compat_sc_table.table;
12e579db
MD
1205 return 0;
1206}
1207
2d2464bd
MD
1208static
1209int syscall_list_show(struct seq_file *m, void *p)
1210{
1211 const struct trace_syscall_entry *table, *entry = p;
1212 unsigned int bitness;
d4291869 1213 unsigned long index;
12e579db 1214 int ret;
d4291869 1215 const char *name;
2d2464bd 1216
12e579db
MD
1217 ret = get_sc_table(entry, &table, &bitness);
1218 if (ret)
1219 return ret;
f4855b46
MD
1220 if (!entry->desc)
1221 return 0;
ebcc64cd 1222 if (table == sc_table.table) {
d4291869 1223 index = entry - table;
437d5aa5 1224 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869 1225 } else {
ebcc64cd 1226 index = (entry - table) + sc_table.len;
437d5aa5 1227 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1228 }
12e579db 1229 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1230 index, name, bitness);
2d2464bd
MD
1231 return 0;
1232}
1233
1234static
1235const 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
1242static
1243int lttng_syscall_list_open(struct inode *inode, struct file *file)
1244{
1245 return seq_open(file, &lttng_syscall_list_seq_ops);
1246}
1247
1248const 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};
12e579db 1255
badfe9f5
MD
1256/*
1257 * A syscall is enabled if it is traced for either entry or exit.
1258 */
c970b655 1259long lttng_syscall_table_get_active_mask(struct lttng_kernel_syscall_table *syscall_table,
606828e4 1260 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db
MD
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;
0bb716a8 1279 filter = syscall_table->sc_filter;
12e579db 1280
ebcc64cd 1281 for (bit = 0; bit < sc_table.len; bit++) {
e2129868 1282 char state;
2f25059d 1283
0bb716a8
MD
1284 if (syscall_table->syscall_dispatch) {
1285 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1286 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
badfe9f5
MD
1287 state = test_bit(bit, filter->sc_entry)
1288 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1289 else
1290 state = 1;
1291 } else {
1292 state = 0;
1293 }
1294 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1295 }
1296 for (; bit < sc_tables_len; bit++) {
e2129868 1297 char state;
2f25059d 1298
0bb716a8
MD
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)
ebcc64cd 1302 state = test_bit(bit - sc_table.len,
badfe9f5 1303 filter->sc_compat_entry)
ebcc64cd 1304 || test_bit(bit - sc_table.len,
badfe9f5 1305 filter->sc_compat_exit);
2f25059d
MD
1306 else
1307 state = 1;
1308 } else {
1309 state = 0;
1310 }
1311 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1312 }
1313 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1314 ret = -EFAULT;
1315 kfree(tmp_mask);
1316 return ret;
1317}
082d4946
MD
1318
1319int lttng_abi_syscall_list(void)
1320{
1321 struct file *syscall_list_file;
1322 int file_fd, ret;
1323
4ac10b76 1324 file_fd = lttng_get_unused_fd();
082d4946
MD
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);
082d4946
MD
1341 return file_fd;
1342
1343open_error:
1344 fput(syscall_list_file);
1345file_error:
1346 put_unused_fd(file_fd);
1347fd_error:
1348 return ret;
1349}
This page took 0.129967 seconds and 4 git commands to generate.