Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ade2920 authored by Chuck Ebbert's avatar Chuck Ebbert Committed by Andi Kleen
Browse files

[PATCH] i386/x86-64: rename is_at_popf(), add iret to tests and fix



is_at_popf() needs to test for the iret instruction as well as
popf.  So add that test and rename it to is_setting_trap_flag().

Also change max insn length from 16 to 15 to match reality.

LAHF / SAHF can't affect TF, so the comment in x86_64 is removed.

Signed-off-by: default avatarChuck Ebbert <76306.1226@compuserve.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 91cd444e
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -185,17 +185,17 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_
	return addr;
}

static inline int is_at_popf(struct task_struct *child, struct pt_regs *regs)
static inline int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
{
	int i, copied;
	unsigned char opcode[16];
	unsigned char opcode[15];
	unsigned long addr = convert_eip_to_linear(child, regs);

	copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
	for (i = 0; i < copied; i++) {
		switch (opcode[i]) {
		/* popf */
		case 0x9d:
		/* popf and iret */
		case 0x9d: case 0xcf:
			return 1;
		/* opcode and address size prefixes */
		case 0x66: case 0x67:
@@ -247,7 +247,7 @@ static void set_singlestep(struct task_struct *child)
	 * don't mark it as being "us" that set it, so that we
	 * won't clear it by hand later.
	 */
	if (is_at_popf(child, regs))
	if (is_setting_trap_flag(child, regs))
		return;
	
	child->ptrace |= PT_DTRACE;
+5 −7
Original line number Diff line number Diff line
@@ -116,17 +116,17 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r
	return addr;
}

static int is_at_popf(struct task_struct *child, struct pt_regs *regs)
static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
{
	int i, copied;
	unsigned char opcode[16];
	unsigned char opcode[15];
	unsigned long addr = convert_rip_to_linear(child, regs);

	copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
	for (i = 0; i < copied; i++) {
		switch (opcode[i]) {
		/* popf */
		case 0x9d:
		/* popf and iret */
		case 0x9d: case 0xcf:
			return 1;

			/* CHECKME: 64 65 */
@@ -189,10 +189,8 @@ static void set_singlestep(struct task_struct *child)
	 * ..but if TF is changed by the instruction we will trace,
	 * don't mark it as being "us" that set it, so that we
	 * won't clear it by hand later.
	 *
	 * AK: this is not enough, LAHF and IRET can change TF in user space too.
	 */
	if (is_at_popf(child, regs))
	if (is_setting_trap_flag(child, regs))
		return;

	child->ptrace |= PT_DTRACE;