/* * Returns the target address and the expected type when regs->epc points * to a compiler-generated CFI trap.
*/ staticbool decode_cfi_insn(struct pt_regs *regs, unsignedlong *target,
u32 *type)
{ unsignedlong *regs_ptr = (unsignedlong *)regs; int rs1_num;
u32 insn;
*target = *type = 0;
/* * The compiler generates the following instruction sequence * for indirect call checks: * * lw t1, -4(<reg>) * lui t2, <hi20> * addiw t2, t2, <lo12> * beq t1, t2, .Ltmp1 * ebreak ; <- regs->epc * .Ltmp1: * jalr <reg> * * We can read the expected type and the target address from the * registers passed to the beq/jalr instructions.
*/ if (get_kernel_nofault(insn, (void *)regs->epc - 4)) returnfalse; if (!riscv_insn_is_beq(insn)) returnfalse;
/* * Checks if the ebreak trap is because of a CFI failure, and handles the trap * if needed. Returns a bug_trap_type value similarly to report_bug.
*/ enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{ unsignedlong target;
u32 type;
if (!is_cfi_trap(regs->epc)) return BUG_TRAP_TYPE_NONE;
if (!decode_cfi_insn(regs, &target, &type)) return report_cfi_failure_noaddr(regs, regs->epc);
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.