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