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