Commit | Line | Data |
---|---|---|
fd0db102 ACM |
1 | /* |
2 | * System call table mapper | |
3 | * | |
4 | * (C) 2016 Arnaldo Carvalho de Melo <acme@redhat.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms and conditions of the GNU General Public License, | |
8 | * version 2, as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | * more details. | |
14 | */ | |
15 | ||
16 | #include "syscalltbl.h" | |
5af56fab ACM |
17 | #include <stdlib.h> |
18 | ||
19 | #ifdef HAVE_SYSCALL_TABLE | |
20 | #include <linux/compiler.h> | |
fd0db102 | 21 | #include <string.h> |
5af56fab ACM |
22 | #include "util.h" |
23 | ||
1b700c99 ACM |
24 | #if defined(__x86_64__) |
25 | #include <asm/syscalls_64.c> | |
26 | const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID; | |
27 | static const char **syscalltbl_native = syscalltbl_x86_64; | |
28 | #endif | |
29 | ||
5af56fab ACM |
30 | struct syscall { |
31 | int id; | |
32 | const char *name; | |
33 | }; | |
fd0db102 | 34 | |
5af56fab ACM |
35 | static int syscallcmpname(const void *vkey, const void *ventry) |
36 | { | |
37 | const char *key = vkey; | |
38 | const struct syscall *entry = ventry; | |
39 | ||
40 | return strcmp(key, entry->name); | |
41 | } | |
42 | ||
43 | static int syscallcmp(const void *va, const void *vb) | |
44 | { | |
45 | const struct syscall *a = va, *b = vb; | |
46 | ||
47 | return strcmp(a->name, b->name); | |
48 | } | |
49 | ||
50 | static int syscalltbl__init_native(struct syscalltbl *tbl) | |
51 | { | |
52 | int nr_entries = 0, i, j; | |
53 | struct syscall *entries; | |
54 | ||
55 | for (i = 0; i <= syscalltbl_native_max_id; ++i) | |
56 | if (syscalltbl_native[i]) | |
57 | ++nr_entries; | |
58 | ||
59 | entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries); | |
60 | if (tbl->syscalls.entries == NULL) | |
61 | return -1; | |
62 | ||
63 | for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) { | |
64 | if (syscalltbl_native[i]) { | |
65 | entries[j].name = syscalltbl_native[i]; | |
66 | entries[j].id = i; | |
67 | ++j; | |
68 | } | |
69 | } | |
70 | ||
71 | qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp); | |
72 | tbl->syscalls.nr_entries = nr_entries; | |
73 | return 0; | |
74 | } | |
fd0db102 ACM |
75 | |
76 | struct syscalltbl *syscalltbl__new(void) | |
77 | { | |
78 | struct syscalltbl *tbl = malloc(sizeof(*tbl)); | |
79 | if (tbl) { | |
5af56fab ACM |
80 | if (syscalltbl__init_native(tbl)) { |
81 | free(tbl); | |
82 | return NULL; | |
83 | } | |
fd0db102 ACM |
84 | } |
85 | return tbl; | |
86 | } | |
87 | ||
5af56fab ACM |
88 | void syscalltbl__delete(struct syscalltbl *tbl) |
89 | { | |
90 | zfree(&tbl->syscalls.entries); | |
91 | free(tbl); | |
92 | } | |
93 | ||
94 | const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id) | |
95 | { | |
96 | return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL; | |
97 | } | |
98 | ||
99 | int syscalltbl__id(struct syscalltbl *tbl, const char *name) | |
100 | { | |
101 | struct syscall *sc = bsearch(name, tbl->syscalls.entries, | |
102 | tbl->syscalls.nr_entries, sizeof(*sc), | |
103 | syscallcmpname); | |
104 | ||
105 | return sc ? sc->id : -1; | |
106 | } | |
107 | ||
108 | #else /* HAVE_SYSCALL_TABLE */ | |
109 | ||
110 | #include <libaudit.h> | |
111 | ||
112 | struct syscalltbl *syscalltbl__new(void) | |
113 | { | |
114 | struct syscalltbl *tbl = malloc(sizeof(*tbl)); | |
115 | if (tbl) | |
116 | tbl->audit_machine = audit_detect_machine(); | |
117 | return tbl; | |
118 | } | |
119 | ||
fd0db102 ACM |
120 | void syscalltbl__delete(struct syscalltbl *tbl) |
121 | { | |
122 | free(tbl); | |
123 | } | |
124 | ||
125 | const char *syscalltbl__name(const struct syscalltbl *tbl, int id) | |
126 | { | |
127 | return audit_syscall_to_name(id, tbl->audit_machine); | |
128 | } | |
129 | ||
130 | int syscalltbl__id(struct syscalltbl *tbl, const char *name) | |
131 | { | |
132 | return audit_name_to_syscall(name, tbl->audit_machine); | |
133 | } | |
5af56fab | 134 | #endif /* HAVE_SYSCALL_TABLE */ |