Messages in this thread | | | Date | Thu, 29 Nov 2007 10:09:00 -0800 (PST) | From | Linus Torvalds <> | Subject | Re: [PATCH x86/mm 6/6] x86-64 ia32 ptrace get/putreg32 current task |
| |
Chuck seems to have caught a bug, although the wrong one:
On Thu, 29 Nov 2007, Chuck Ebbert wrote: > > On 11/28/2007 07:42 PM, Roland McGrath wrote: > > --- a/arch/x86/ia32/ptrace32.c > > +++ b/arch/x86/ia32/ptrace32.c > > ... > > + if (child == current) > > + load_gs_index(child->thread.gsindex);
This is correct.
But the ones that do the same thing for fs/es/ds are *not*. Those three registers are kernel mode registers (ds/es are the regular kernel data segment, fs is the per-cpu data segment), and restored on return to user space from the stack.
For similar reasons, this is wrong:
> > @@ -129,15 +137,23 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) > > switch (regno) { > > case offsetof(struct user32, regs.fs): > > *val = child->thread.fsindex; > > + if (child == current) > > + asm("movl %%fs,%0" : "=r" (*val)); > > break;
That %fs is the kernel per-cpu thing, not the user %fs.
But this one is correct:
> > case offsetof(struct user32, regs.gs): > > *val = child->thread.gsindex; > > + if (child == current) > > + asm("movl %%gs,%0" : "=r" (*val)); > > Won't this return the kernel's GS instead of the user's?
No, %gs is untouched by the kernel, so it contains user space version, and getting the value directly from %gs looks correct.
Linus - 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/
| |