|
5 | 5 |
|
6 | 6 | #include <sysdep/stub.h> |
7 | 7 |
|
| 8 | +#include <linux/futex.h> |
| 9 | +#include <errno.h> |
| 10 | + |
8 | 11 | static __always_inline int syscall_handler(struct stub_data *d) |
9 | 12 | { |
10 | 13 | int i; |
@@ -57,3 +60,49 @@ stub_syscall_handler(void) |
57 | 60 |
|
58 | 61 | trap_myself(); |
59 | 62 | } |
| 63 | + |
| 64 | +void __section(".__syscall_stub") |
| 65 | +stub_signal_interrupt(int sig, siginfo_t *info, void *p) |
| 66 | +{ |
| 67 | + struct stub_data *d = get_stub_data(); |
| 68 | + ucontext_t *uc = p; |
| 69 | + long res; |
| 70 | + |
| 71 | + d->signal = sig; |
| 72 | + d->si_offset = (unsigned long)info - (unsigned long)&d->sigstack[0]; |
| 73 | + d->mctx_offset = (unsigned long)&uc->uc_mcontext - (unsigned long)&d->sigstack[0]; |
| 74 | + |
| 75 | +restart_wait: |
| 76 | + d->futex = FUTEX_IN_KERN; |
| 77 | + do { |
| 78 | + res = stub_syscall3(__NR_futex, (unsigned long)&d->futex, |
| 79 | + FUTEX_WAKE, 1); |
| 80 | + } while (res == -EINTR); |
| 81 | + do { |
| 82 | + res = stub_syscall4(__NR_futex, (unsigned long)&d->futex, |
| 83 | + FUTEX_WAIT, FUTEX_IN_KERN, 0); |
| 84 | + } while (res == -EINTR || d->futex == FUTEX_IN_KERN); |
| 85 | + |
| 86 | + if (res < 0 && res != -EAGAIN) |
| 87 | + stub_syscall1(__NR_exit_group, 1); |
| 88 | + |
| 89 | + /* Try running queued syscalls. */ |
| 90 | + if (syscall_handler(d) < 0 || d->restart_wait) { |
| 91 | + /* Report SIGSYS if we restart. */ |
| 92 | + d->signal = SIGSYS; |
| 93 | + d->restart_wait = 0; |
| 94 | + goto restart_wait; |
| 95 | + } |
| 96 | + |
| 97 | + /* Restore arch dependent state that is not part of the mcontext */ |
| 98 | + stub_seccomp_restore_state(&d->arch_data); |
| 99 | + |
| 100 | + /* Return so that the host modified mcontext is restored. */ |
| 101 | +} |
| 102 | + |
| 103 | +void __section(".__syscall_stub") |
| 104 | +stub_signal_restorer(void) |
| 105 | +{ |
| 106 | + /* We must not have anything on the stack when doing rt_sigreturn */ |
| 107 | + stub_syscall0(__NR_rt_sigreturn); |
| 108 | +} |
0 commit comments