diff options
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r-- | arch/x86/kernel/ptrace.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 8d7d5c9c1be3..7b058a2dc66a 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -325,16 +325,6 @@ static int putreg(struct task_struct *child, | |||
325 | return set_flags(child, value); | 325 | return set_flags(child, value); |
326 | 326 | ||
327 | #ifdef CONFIG_X86_64 | 327 | #ifdef CONFIG_X86_64 |
328 | /* | ||
329 | * Orig_ax is really just a flag with small positive and | ||
330 | * negative values, so make sure to always sign-extend it | ||
331 | * from 32 bits so that it works correctly regardless of | ||
332 | * whether we come from a 32-bit environment or not. | ||
333 | */ | ||
334 | case offsetof(struct user_regs_struct, orig_ax): | ||
335 | value = (long) (s32) value; | ||
336 | break; | ||
337 | |||
338 | case offsetof(struct user_regs_struct,fs_base): | 328 | case offsetof(struct user_regs_struct,fs_base): |
339 | if (value >= TASK_SIZE_OF(child)) | 329 | if (value >= TASK_SIZE_OF(child)) |
340 | return -EIO; | 330 | return -EIO; |
@@ -1126,10 +1116,15 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value) | |||
1126 | 1116 | ||
1127 | case offsetof(struct user32, regs.orig_eax): | 1117 | case offsetof(struct user32, regs.orig_eax): |
1128 | /* | 1118 | /* |
1129 | * Sign-extend the value so that orig_eax = -1 | 1119 | * A 32-bit debugger setting orig_eax means to restore |
1130 | * causes (long)orig_ax < 0 tests to fire correctly. | 1120 | * the state of the task restarting a 32-bit syscall. |
1121 | * Make sure we interpret the -ERESTART* codes correctly | ||
1122 | * in case the task is not actually still sitting at the | ||
1123 | * exit from a 32-bit syscall with TS_COMPAT still set. | ||
1131 | */ | 1124 | */ |
1132 | regs->orig_ax = (long) (s32) value; | 1125 | regs->orig_ax = value; |
1126 | if (syscall_get_nr(child, regs) >= 0) | ||
1127 | task_thread_info(child)->status |= TS_COMPAT; | ||
1133 | break; | 1128 | break; |
1134 | 1129 | ||
1135 | case offsetof(struct user32, regs.eflags): | 1130 | case offsetof(struct user32, regs.eflags): |