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