stub.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2021 Benjamin Berg <benjamin@sipsolutions.net>
  4. */
  5. #include <sysdep/stub.h>
  6. static __always_inline int syscall_handler(struct stub_data *d)
  7. {
  8. int i;
  9. unsigned long res;
  10. for (i = 0; i < d->syscall_data_len; i++) {
  11. struct stub_syscall *sc = &d->syscall_data[i];
  12. switch (sc->syscall) {
  13. case STUB_SYSCALL_MMAP:
  14. res = stub_syscall6(STUB_MMAP_NR,
  15. sc->mem.addr, sc->mem.length,
  16. sc->mem.prot,
  17. MAP_SHARED | MAP_FIXED,
  18. sc->mem.fd, sc->mem.offset);
  19. if (res != sc->mem.addr) {
  20. d->err = res;
  21. d->syscall_data_len = i;
  22. return -1;
  23. }
  24. break;
  25. case STUB_SYSCALL_MUNMAP:
  26. res = stub_syscall2(__NR_munmap,
  27. sc->mem.addr, sc->mem.length);
  28. if (res) {
  29. d->err = res;
  30. d->syscall_data_len = i;
  31. return -1;
  32. }
  33. break;
  34. case STUB_SYSCALL_MPROTECT:
  35. res = stub_syscall3(__NR_mprotect,
  36. sc->mem.addr, sc->mem.length,
  37. sc->mem.prot);
  38. if (res) {
  39. d->err = res;
  40. d->syscall_data_len = i;
  41. return -1;
  42. }
  43. break;
  44. default:
  45. d->err = -95; /* EOPNOTSUPP */
  46. d->syscall_data_len = i;
  47. return -1;
  48. }
  49. }
  50. d->err = 0;
  51. d->syscall_data_len = 0;
  52. return 0;
  53. }
  54. void __section(".__syscall_stub")
  55. stub_syscall_handler(void)
  56. {
  57. struct stub_data *d = get_stub_data();
  58. syscall_handler(d);
  59. trap_myself();
  60. }