^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * System call table mapper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (C) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "syscalltbl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #ifdef HAVE_SYSCALL_TABLE_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #if defined(__x86_64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/syscalls_64.c>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static const char **syscalltbl_native = syscalltbl_x86_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #elif defined(__s390x__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/syscalls_64.c>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static const char **syscalltbl_native = syscalltbl_s390_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #elif defined(__powerpc64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/syscalls_64.c>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static const char **syscalltbl_native = syscalltbl_powerpc_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #elif defined(__powerpc__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/syscalls_32.c>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static const char **syscalltbl_native = syscalltbl_powerpc_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #elif defined(__aarch64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/syscalls.c>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static const char **syscalltbl_native = syscalltbl_arm64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct syscall {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int syscallcmpname(const void *vkey, const void *ventry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const char *key = vkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const struct syscall *entry = ventry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return strcmp(key, entry->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int syscallcmp(const void *va, const void *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) const struct syscall *a = va, *b = vb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return strcmp(a->name, b->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int syscalltbl__init_native(struct syscalltbl *tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int nr_entries = 0, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct syscall *entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) for (i = 0; i <= syscalltbl_native_max_id; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (syscalltbl_native[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ++nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (tbl->syscalls.entries == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (syscalltbl_native[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) entries[j].name = syscalltbl_native[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) entries[j].id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ++j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) tbl->syscalls.nr_entries = nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) tbl->syscalls.max_id = syscalltbl_native_max_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct syscalltbl *syscalltbl__new(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct syscalltbl *tbl = malloc(sizeof(*tbl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (tbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (syscalltbl__init_native(tbl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) free(tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void syscalltbl__delete(struct syscalltbl *tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) zfree(&tbl->syscalls.entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) free(tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int syscalltbl__id(struct syscalltbl *tbl, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct syscall *sc = bsearch(name, tbl->syscalls.entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) tbl->syscalls.nr_entries, sizeof(*sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) syscallcmpname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return sc ? sc->id : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct syscall *syscalls = tbl->syscalls.entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (strglobmatch(syscalls[i].name, syscall_glob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return syscalls[i].id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #else /* HAVE_SYSCALL_TABLE_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #include <libaudit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct syscalltbl *syscalltbl__new(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct syscalltbl *tbl = zalloc(sizeof(*tbl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) tbl->audit_machine = audit_detect_machine();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) void syscalltbl__delete(struct syscalltbl *tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) free(tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return audit_syscall_to_name(id, tbl->audit_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int syscalltbl__id(struct syscalltbl *tbl, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return audit_name_to_syscall(name, tbl->audit_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #endif /* HAVE_SYSCALL_TABLE_SUPPORT */