/* * Currently, the max observed size in the kernel code is * JUMP_LABEL_NOP_SIZE/RELATIVEJUMP_SIZE, which are 5. * Raise it if needed.
*/ #define TEXT_POKE_MAX_OPCODE_SIZE 5
/* * Clear and restore the kernel write-protection flag on the local CPU. * Allows the kernel to edit read-only pages. * Side-effect: any interrupt handler running between save and restore will have * the ability to write to read-only pages. * * Warning: * Code patching in the UP case is safe if NMIs and MCE handlers are stopped and * no thread can be preempted in the instructions being modified (no iret to an * invalid instruction possible) or if the instructions are changed from a * consistent state to another consistent state atomically. * On the local CPU you need to be protected against NMI or MCE handlers seeing * an inconsistent instruction while you patch.
*/ externvoid *text_poke(void *addr, constvoid *opcode, size_t len); externvoid smp_text_poke_sync_each_cpu(void); externvoid *text_poke_kgdb(void *addr, constvoid *opcode, size_t len); externvoid *text_poke_copy(void *addr, constvoid *opcode, size_t len); #define text_poke_copy text_poke_copy externvoid *text_poke_copy_locked(void *addr, constvoid *opcode, size_t len, bool core_ok); externvoid *text_poke_set(void *addr, int c, size_t len); externint smp_text_poke_int3_handler(struct pt_regs *regs); externvoid smp_text_poke_single(void *addr, constvoid *opcode, size_t len, constvoid *emulate);
static __always_inline void __text_gen_insn(void *buf, u8 opcode, constvoid *addr, constvoid *dest, int size)
{ union text_poke_insn *insn = buf;
BUG_ON(size < text_opcode_size(opcode));
/* * Hide the addresses to avoid the compiler folding in constants when * referencing code, these can mess up annotations like * ANNOTATE_NOENDBR.
*/
OPTIMIZER_HIDE_VAR(insn);
OPTIMIZER_HIDE_VAR(addr);
OPTIMIZER_HIDE_VAR(dest);
insn->opcode = opcode;
if (size > 1) {
insn->disp = (long)dest - (long)(addr + size); if (size == 2) { /* * Ensure that for JMP8 the displacement * actually fits the signed byte.
*/
BUG_ON((insn->disp >> 31) != (insn->disp >> 7));
}
}
}
static __always_inline void int3_emulate_push(struct pt_regs *regs, unsignedlong val)
{ /* * The INT3 handler in entry_64.S adds a gap between the * stack where the break point happened, and the saving of * pt_regs. We can extend the original stack because of * this gap. See the idtentry macro's X86_TRAP_BP logic. * * Similarly, entry_32.S will have a gap on the stack for * (any) hardware exception and pt_regs; see the * FIXUP_FRAME macro.
*/
regs->sp -= sizeof(unsignedlong);
*(unsignedlong *)regs->sp = val;
}
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.