syscalltbl.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. #include "syscalltbl.h"
  16. #include <stdlib.h>
  17. #include <linux/compiler.h>
  18. #ifdef HAVE_SYSCALL_TABLE_SUPPORT
  19. #include <string.h>
  20. #include "string2.h"
  21. #include "util.h"
  22. #if defined(__x86_64__)
  23. #include <asm/syscalls_64.c>
  24. const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
  25. static const char **syscalltbl_native = syscalltbl_x86_64;
  26. #elif defined(__s390x__)
  27. #include <asm/syscalls_64.c>
  28. const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
  29. static const char **syscalltbl_native = syscalltbl_s390_64;
  30. #elif defined(__powerpc64__)
  31. #include <asm/syscalls_64.c>
  32. const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
  33. static const char **syscalltbl_native = syscalltbl_powerpc_64;
  34. #elif defined(__powerpc__)
  35. #include <asm/syscalls_32.c>
  36. const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
  37. static const char **syscalltbl_native = syscalltbl_powerpc_32;
  38. #elif defined(__aarch64__)
  39. #include <asm/syscalls.c>
  40. const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
  41. static const char **syscalltbl_native = syscalltbl_arm64;
  42. #endif
  43. struct syscall {
  44. int id;
  45. const char *name;
  46. };
  47. static int syscallcmpname(const void *vkey, const void *ventry)
  48. {
  49. const char *key = vkey;
  50. const struct syscall *entry = ventry;
  51. return strcmp(key, entry->name);
  52. }
  53. static int syscallcmp(const void *va, const void *vb)
  54. {
  55. const struct syscall *a = va, *b = vb;
  56. return strcmp(a->name, b->name);
  57. }
  58. static int syscalltbl__init_native(struct syscalltbl *tbl)
  59. {
  60. int nr_entries = 0, i, j;
  61. struct syscall *entries;
  62. for (i = 0; i <= syscalltbl_native_max_id; ++i)
  63. if (syscalltbl_native[i])
  64. ++nr_entries;
  65. entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
  66. if (tbl->syscalls.entries == NULL)
  67. return -1;
  68. for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
  69. if (syscalltbl_native[i]) {
  70. entries[j].name = syscalltbl_native[i];
  71. entries[j].id = i;
  72. ++j;
  73. }
  74. }
  75. qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
  76. tbl->syscalls.nr_entries = nr_entries;
  77. return 0;
  78. }
  79. struct syscalltbl *syscalltbl__new(void)
  80. {
  81. struct syscalltbl *tbl = malloc(sizeof(*tbl));
  82. if (tbl) {
  83. if (syscalltbl__init_native(tbl)) {
  84. free(tbl);
  85. return NULL;
  86. }
  87. }
  88. return tbl;
  89. }
  90. void syscalltbl__delete(struct syscalltbl *tbl)
  91. {
  92. zfree(&tbl->syscalls.entries);
  93. free(tbl);
  94. }
  95. const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
  96. {
  97. return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
  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. return sc ? sc->id : -1;
  105. }
  106. int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
  107. {
  108. int i;
  109. struct syscall *syscalls = tbl->syscalls.entries;
  110. for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
  111. if (strglobmatch(syscalls[i].name, syscall_glob)) {
  112. *idx = i;
  113. return syscalls[i].id;
  114. }
  115. }
  116. return -1;
  117. }
  118. int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
  119. {
  120. *idx = -1;
  121. return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
  122. }
  123. #else /* HAVE_SYSCALL_TABLE_SUPPORT */
  124. #include <libaudit.h>
  125. struct syscalltbl *syscalltbl__new(void)
  126. {
  127. struct syscalltbl *tbl = malloc(sizeof(*tbl));
  128. if (tbl)
  129. tbl->audit_machine = audit_detect_machine();
  130. return tbl;
  131. }
  132. void syscalltbl__delete(struct syscalltbl *tbl)
  133. {
  134. free(tbl);
  135. }
  136. const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
  137. {
  138. return audit_syscall_to_name(id, tbl->audit_machine);
  139. }
  140. int syscalltbl__id(struct syscalltbl *tbl, const char *name)
  141. {
  142. return audit_name_to_syscall(name, tbl->audit_machine);
  143. }
  144. int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
  145. const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
  146. {
  147. return -1;
  148. }
  149. int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
  150. {
  151. return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
  152. }
  153. #endif /* HAVE_SYSCALL_TABLE_SUPPORT */