RE: ptrace bug

Gian-Yan Xu (kids@linux.ee.tku.edu.tw)
Tue, 16 Oct 2001 17:52:12 +0800 (CST)


On Mon, 15 Oct 2001, Monty Vanderbilt wrote:

> I don't think the problem is what you identified.
> arch/i386/kernel/ptrace.c:getreg() takes the extra FS,GS offsets into
> account and performs special handling for them. I suspect this is because
> they are not stable per-thread registers and not saved into the register
> structure on an interrupt or system call.

Before the reply, I dont examin getreg() carefully. But now, I still
believe the bug is exist. see the blow (ptrace.c case PTRACE_GETREGS):

for ( i = 0; i < FRAME_SIZE*sizeof(long); i += sizeof(long) ) {
__put_user(getreg(child, i),(unsigned long *) data);
data += sizeof(long);
}

when i = FS*sizeof(long), the getreg() return child->thread.fs,
and the value will be copy into *data of user-space, but
*data is point to orig_eax of struct pt_regs.

So, when i = ORIG_EAX*sizeof(long), even getreg() adjust his regno,
that let us get accurate registers, but it copy value into wrong member of
struct pt_regs ( the *data is point to xcs member, not orig_eax member,
because the line: data += sizeof(long); never be adjust)

If we dont modify struct pt_regs, maybe we should fix the ptrace.c?

>
> ptrace.c:getreg() ...
> switch (regno >> 2) {
> case FS:
> retval = child->thread.fs;
> break;
> case GS:
> retval = child->thread.gs;
> break;
> case DS:
> case ES:
> case SS:
> case CS:
> retval = 0xffff;
> /* fall through */
> default:
> if (regno > GS*4) // *** Adusts for missing FS,GS fields *** //
> regno -= 2*4;
> regno = regno - sizeof(struct pt_regs);
> retval &= get_stack_long(child, regno);
> }
>

-- 
Best regards,
Gian-Yan Xu.

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/