noinline staticvoid real_init(void)
{ struct stub_init_data init_data; unsignedlong res; struct { void *ss_sp; int ss_flags;
size_t ss_size;
} stack = {
.ss_size = STUB_DATA_PAGES * UM_KERN_PAGE_SIZE,
}; struct { void *sa_handler_; unsignedlong sa_flags; void *sa_restorer; unsignedlonglong sa_mask;
} sa = { /* Need to set SA_RESTORER (but the handler never returns) */
.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO | 0x04000000,
};
/* set a nice name */
stub_syscall2(__NR_prctl, PR_SET_NAME, (unsignedlong)"uml-userspace");
/* Make sure this process dies if the kernel dies */
stub_syscall2(__NR_prctl, PR_SET_PDEATHSIG, SIGKILL);
/* Needed in SECCOMP mode (and safe to do anyway) */
stub_syscall5(__NR_prctl, PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
/* read information from STDIN and close it */
res = stub_syscall3(__NR_read, 0,
(unsignedlong)&init_data, sizeof(init_data)); if (res != sizeof(init_data))
stub_syscall1(__NR_exit, 10);
/* In SECCOMP mode, FD 0 is a socket and is later used for FD passing */ if (!init_data.seccomp)
stub_syscall1(__NR_close, 0); else
stub_syscall3(__NR_fcntl, 0, F_SETFL, O_NONBLOCK);
/* map stub code + data */
res = stub_syscall6(STUB_MMAP_NR,
init_data.stub_start, UM_KERN_PAGE_SIZE,
PROT_READ | PROT_EXEC, MAP_FIXED | MAP_SHARED,
init_data.stub_code_fd, init_data.stub_code_offset); if (res != init_data.stub_start)
stub_syscall1(__NR_exit, 11);
/* In SECCOMP mode, we only need the signalling FD from now on */ if (init_data.seccomp) {
res = stub_syscall3(__NR_close_range, 1, ~0U, 0); if (res != 0)
stub_syscall1(__NR_exit, 13);
}
/* setup signal stack inside stub data */
stack.ss_sp = (void *)init_data.stub_start + UM_KERN_PAGE_SIZE;
stub_syscall2(__NR_sigaltstack, (unsignedlong)&stack, 0);
/* register signal handlers */
sa.sa_handler_ = (void *) init_data.signal_handler;
sa.sa_restorer = (void *) init_data.signal_restorer; if (!init_data.seccomp) { /* In ptrace mode, the SIGSEGV handler never returns */
sa.sa_mask = 0;
res = stub_syscall4(__NR_rt_sigaction, SIGSEGV,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 14);
} else { /* SECCOMP mode uses rt_sigreturn, need to mask all signals */
sa.sa_mask = ~0ULL;
res = stub_syscall4(__NR_rt_sigaction, SIGSEGV,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 15);
res = stub_syscall4(__NR_rt_sigaction, SIGSYS,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 16);
res = stub_syscall4(__NR_rt_sigaction, SIGALRM,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 17);
res = stub_syscall4(__NR_rt_sigaction, SIGTRAP,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 18);
res = stub_syscall4(__NR_rt_sigaction, SIGILL,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 19);
res = stub_syscall4(__NR_rt_sigaction, SIGFPE,
(unsignedlong)&sa, 0, sizeof(sa.sa_mask)); if (res != 0)
stub_syscall1(__NR_exit, 20);
}
/* * If in seccomp mode, install the SECCOMP filter and trigger a syscall. * Otherwise set PTRACE_TRACEME and do a SIGSTOP.
*/ if (init_data.seccomp) { struct sock_filter filter[] = { #if __BITS_PER_LONG > 32 /* [0] Load upper 32bit of instruction pointer from seccomp_data */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, instruction_pointer) + 4)),
/* [1] Jump forward 3 instructions if the upper address is not identical */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (init_data.stub_start) >> 32, 0, 3), #endif /* [2] Load lower 32bit of instruction pointer from seccomp_data */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, instruction_pointer))),
__attribute__((naked)) void _start(void)
{ /* * Since the stack after exec() starts at the top-most address, * but that's exactly where we also want to map the stub data * and code, this must: * - push the stack by 1 code and STUB_DATA_PAGES data pages * - call real_init() * This way, real_init() can use the stack normally, while the * original stack further down (higher address) will become * inaccessible after the mmap() calls above.
*/
stub_start(real_init);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.29 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.