/* *Onx86-64,weendupbeingimprecisewith'access_ok()',andallow *non-canonicaluseraddressestomaketherangecomparisonssimpler, *andtonothavetoworryaboutLAMbeingenabled. * *Infact,weallowuptoonepageof"slop"atthesignboundary, *whichmeansthatwecandoaccess_ok()byjustcheckingthesign *ofthepointerforthecommoncaseofhavingasmallaccesssize.
*/ staticbool gp_fault_address_ok(unsignedlong fault_address)
{ #ifdef CONFIG_X86_64 /* Is it in the "user space" part of the non-canonical space? */ if (valid_user_address(fault_address)) returntrue;
/* .. or just above it? */
fault_address -= PAGE_SIZE; if (valid_user_address(fault_address)) returntrue; #endif returnfalse;
}
staticbool ex_handler_uaccess(conststruct exception_table_entry *fixup, struct pt_regs *regs, int trapnr, unsignedlong fault_address)
{
WARN_ONCE(trapnr == X86_TRAP_GP && !gp_fault_address_ok(fault_address), "General protection fault in user access. Non-canonical address?"); return ex_handler_default(fixup, regs);
}
staticbool ex_handler_msr(conststruct exception_table_entry *fixup, struct pt_regs *regs, bool wrmsr, bool safe, int reg)
{ if (__ONCE_LITE_IF(!safe && wrmsr)) {
pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
(unsignedint)regs->cx, (unsignedint)regs->dx,
(unsignedint)regs->ax, regs->ip, (void *)regs->ip);
show_stack_regs(regs);
}
if (__ONCE_LITE_IF(!safe && !wrmsr)) {
pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
(unsignedint)regs->cx, regs->ip, (void *)regs->ip);
show_stack_regs(regs);
}
if (!wrmsr) { /* Pretend that the read succeeded and returned 0. */
regs->ax = 0;
regs->dx = 0;
}
switch (type) { case EX_TYPE_DEFAULT: case EX_TYPE_DEFAULT_MCE_SAFE: return ex_handler_default(e, regs); case EX_TYPE_FAULT: case EX_TYPE_FAULT_MCE_SAFE: return ex_handler_fault(e, regs, trapnr); case EX_TYPE_UACCESS: return ex_handler_uaccess(e, regs, trapnr, fault_addr); case EX_TYPE_CLEAR_FS: return ex_handler_clear_fs(e, regs); case EX_TYPE_FPU_RESTORE: return ex_handler_fprestore(e, regs); case EX_TYPE_BPF: return ex_handler_bpf(e, regs); case EX_TYPE_WRMSR: return ex_handler_msr(e, regs, true, false, reg); case EX_TYPE_RDMSR: return ex_handler_msr(e, regs, false, false, reg); case EX_TYPE_WRMSR_SAFE: return ex_handler_msr(e, regs, true, true, reg); case EX_TYPE_RDMSR_SAFE: return ex_handler_msr(e, regs, false, true, reg); case EX_TYPE_WRMSR_IN_MCE:
ex_handler_msr_mce(regs, true); break; case EX_TYPE_RDMSR_IN_MCE:
ex_handler_msr_mce(regs, false); break; case EX_TYPE_POP_REG:
regs->sp += sizeof(long);
fallthrough; case EX_TYPE_IMM_REG: return ex_handler_imm_reg(e, regs, reg, imm); case EX_TYPE_FAULT_SGX: return ex_handler_sgx(e, regs, trapnr); case EX_TYPE_UCOPY_LEN: return ex_handler_ucopy_len(e, regs, trapnr, fault_addr, reg, imm); case EX_TYPE_ZEROPAD: return ex_handler_zeropad(e, regs, fault_addr); #ifdef CONFIG_X86_FRED case EX_TYPE_ERETU: return ex_handler_eretu(e, regs, error_code); #endif
}
BUG();
}
externunsignedint early_recursion_flag;
/* Restricted version used during very early boot */ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
{ /* Ignore early NMIs. */ if (trapnr == X86_TRAP_NMI) return;
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.