/* * The sys_call_table[] is no longer used for system calls, but * kernel/trace/trace_syscalls.c still wants to know the system * call address.
*/ #define __SYSCALL(nr, sym) __x64_##sym, const sys_call_ptr_t sys_call_table[] = { #include <asm/syscalls_64.h>
}; #undef __SYSCALL
static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr)
{ /* * Convert negative numbers to very high and thus out of range * numbers for comparisons.
*/ unsignedint unr = nr;
static __always_inline bool do_syscall_x32(struct pt_regs *regs, int nr)
{ /* * Adjust the starting offset of the table, and convert numbers * < __X32_SYSCALL_BIT to very high and thus out of range * numbers for comparisons.
*/ unsignedint xnr = nr - __X32_SYSCALL_BIT;
/* Returns true to return using SYSRET, or false to use IRET */
__visible noinstr bool do_syscall_64(struct pt_regs *regs, int nr)
{
add_random_kstack_offset();
nr = syscall_enter_from_user_mode(regs, nr);
instrumentation_begin();
if (!do_syscall_x64(regs, nr) && !do_syscall_x32(regs, nr) && nr != -1) { /* Invalid system call, but still a system call. */
regs->ax = __x64_sys_ni_syscall(regs);
}
/* * Check that the register state is valid for using SYSRET to exit * to userspace. Otherwise use the slower but fully capable IRET * exit path.
*/
/* XEN PV guests always use the IRET path */ if (cpu_feature_enabled(X86_FEATURE_XENPV)) returnfalse;
/* SYSRET requires RCX == RIP and R11 == EFLAGS */ if (unlikely(regs->cx != regs->ip || regs->r11 != regs->flags)) returnfalse;
/* CS and SS must match the values set in MSR_STAR */ if (unlikely(regs->cs != __USER_CS || regs->ss != __USER_DS)) returnfalse;
/* * On Intel CPUs, SYSRET with non-canonical RCX/RIP will #GP * in kernel space. This essentially lets the user take over * the kernel, since userspace controls RSP. * * TASK_SIZE_MAX covers all user-accessible addresses other than * the deprecated vsyscall page.
*/ if (unlikely(regs->ip >= TASK_SIZE_MAX)) returnfalse;
/* * SYSRET cannot restore RF. It can restore TF, but unlike IRET, * restoring TF results in a trap from userspace immediately after * SYSRET.
*/ if (unlikely(regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF))) returnfalse;
/* Use SYSRET to exit to userspace */ returntrue;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.18 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.