Exemplo n.º 1
0
static int arch_copy_kprobe(struct kprobe *p)
{
	struct insn insn;
	kprobe_opcode_t buf[MAX_INSN_SIZE];
	int len;

	/* Copy an instruction with recovering if other optprobe modifies it.*/
	len = __copy_instruction(buf, p->addr, p->ainsn.insn, &insn);
	if (!len)
		return -EINVAL;

	/*
	 * __copy_instruction can modify the displacement of the instruction,
	 * but it doesn't affect boostable check.
	 */
	len = prepare_boost(buf, p, &insn);

	/* Check whether the instruction modifies Interrupt Flag or not */
	p->ainsn.if_modifier = is_IF_modifier(buf);

	/* Also, displacement change doesn't affect the first byte */
	p->opcode = buf[0];

	/* OK, write back the instruction(s) into ROX insn buffer */
	text_poke(p->ainsn.insn, buf, len);

	return 0;
}
Exemplo n.º 2
0
Arquivo: core.c Projeto: AdvEnc/linux
static int arch_copy_kprobe(struct kprobe *p)
{
	int ret;

	/* Copy an instruction with recovering if other optprobe modifies it.*/
	ret = __copy_instruction(p->ainsn.insn, p->addr);
	if (!ret)
		return -EINVAL;

	/*
	 * __copy_instruction can modify the displacement of the instruction,
	 * but it doesn't affect boostable check.
	 */
	if (can_boost(p->ainsn.insn))
		p->ainsn.boostable = 0;
	else
		p->ainsn.boostable = -1;

	/* Check whether the instruction modifies Interrupt Flag or not */
	p->ainsn.if_modifier = is_IF_modifier(p->ainsn.insn);

	/* Also, displacement change doesn't affect the first byte */
	p->opcode = p->ainsn.insn[0];

	return 0;
}
Exemplo n.º 3
0
static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                                      struct kprobe_ctlblk *kcb)
{
    __get_cpu_var(current_kprobe) = p;
    kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
                               = (regs->eflags & (TF_MASK | IF_MASK));
    if (is_IF_modifier(p->opcode))
        kcb->kprobe_saved_eflags &= ~IF_MASK;
}
Exemplo n.º 4
0
/*
 * Returns non-zero if opcode modifies the interrupt flag.
 */
static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
{
	switch (*insn) {
	case 0xfa:		/* cli */
	case 0xfb:		/* sti */
	case 0xcf:		/* iret/iretd */
	case 0x9d:		/* popf/popfd */
		return 1;
	}

	/*
	 * on X86_64, 0x40-0x4f are REX prefixes so we need to look
	 * at the next byte instead.. but of course not recurse infinitely
	 */
	if (is_REX_prefix(insn))
		return is_IF_modifier(++insn);

	return 0;
}