Skip to content

Commit

Permalink
[PATCH] i386: Fix places where using %gs changes the usermode ABI
Browse files Browse the repository at this point in the history
There are a few places where the change in struct pt_regs and the use of %gs
affect the userspace ABI.  These are primarily debugging interfaces where
thread state can be inspected or extracted.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
  • Loading branch information
Jeremy Fitzhardinge authored and Andi Kleen committed Dec 7, 2006
1 parent f95d47c commit 66e10a4
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 16 deletions.
6 changes: 3 additions & 3 deletions arch/i386/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ void show_regs(struct pt_regs * regs)
regs->eax,regs->ebx,regs->ecx,regs->edx);
printk("ESI: %08lx EDI: %08lx EBP: %08lx",
regs->esi, regs->edi, regs->ebp);
printk(" DS: %04x ES: %04x\n",
0xffff & regs->xds,0xffff & regs->xes);
printk(" DS: %04x ES: %04x GS: %04x\n",
0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xgs);

cr0 = read_cr0();
cr2 = read_cr2();
Expand Down Expand Up @@ -509,7 +509,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump->regs.ds = regs->xds;
dump->regs.es = regs->xes;
savesegment(fs,dump->regs.fs);
savesegment(gs,dump->regs.gs);
dump->regs.gs = regs->xgs;
dump->regs.orig_eax = regs->orig_eax;
dump->regs.eip = regs->eip;
dump->regs.cs = regs->xcs;
Expand Down
18 changes: 6 additions & 12 deletions arch/i386/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,9 @@ static int putreg(struct task_struct *child,
return -EIO;
child->thread.fs = value;
return 0;
case GS:
if (value && (value & 3) != 3)
return -EIO;
child->thread.gs = value;
return 0;
case DS:
case ES:
case GS:
if (value && (value & 3) != 3)
return -EIO;
value &= 0xffff;
Expand All @@ -116,8 +112,8 @@ static int putreg(struct task_struct *child,
value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK;
break;
}
if (regno > GS*4)
regno -= 2*4;
if (regno > ES*4)
regno -= 1*4;
put_stack_long(child, regno - sizeof(struct pt_regs), value);
return 0;
}
Expand All @@ -131,18 +127,16 @@ static unsigned long getreg(struct task_struct *child,
case FS:
retval = child->thread.fs;
break;
case GS:
retval = child->thread.gs;
break;
case DS:
case ES:
case GS:
case SS:
case CS:
retval = 0xffff;
/* fall through */
default:
if (regno > GS*4)
regno -= 2*4;
if (regno > ES*4)
regno -= 1*4;
regno = regno - sizeof(struct pt_regs);
retval &= get_stack_long(child, regno);
}
Expand Down
2 changes: 1 addition & 1 deletion include/asm-i386/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
pr_reg[7] = regs->xds; \
pr_reg[8] = regs->xes; \
savesegment(fs,pr_reg[9]); \
savesegment(gs,pr_reg[10]); \
pr_reg[10] = regs->xgs; \
pr_reg[11] = regs->orig_eax; \
pr_reg[12] = regs->eip; \
pr_reg[13] = regs->xcs; \
Expand Down
1 change: 1 addition & 0 deletions include/asm-i386/unwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
info->regs.xss = __KERNEL_DS;
info->regs.xds = __USER_DS;
info->regs.xes = __USER_DS;
info->regs.xgs = __KERNEL_PDA;
}

extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
Expand Down

0 comments on commit 66e10a4

Please sign in to comment.