Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
"Two fixes and a cleanup-fix, to the syscall entry code and to ptrace"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/syscalls/64: Add compat_sys_keyctl for 32-bit userspace
x86/ptrace: Stop setting TS_COMPAT in ptrace code
x86/vdso: Error out if the vDSO isn't a valid DSO

+49 -14
+5 -1
arch/x86/entry/common.c
··· 204 204 * handling, because syscall restart has a fixup for compat 205 205 * syscalls. The fixup is exercised by the ptrace_syscall_32 206 206 * selftest. 207 + * 208 + * We also need to clear TS_REGS_POKED_I386: the 32-bit tracer 209 + * special case only applies after poking regs and before the 210 + * very next return to user mode. 207 211 */ 208 - ti->status &= ~TS_COMPAT; 212 + ti->status &= ~(TS_COMPAT|TS_I386_REGS_POKED); 209 213 #endif 210 214 211 215 user_enter_irqoff();
+1 -1
arch/x86/entry/syscalls/syscall_32.tbl
··· 294 294 # 285 sys_setaltroot 295 295 286 i386 add_key sys_add_key 296 296 287 i386 request_key sys_request_key 297 - 288 i386 keyctl sys_keyctl 297 + 288 i386 keyctl sys_keyctl compat_sys_keyctl 298 298 289 i386 ioprio_set sys_ioprio_set 299 299 290 i386 ioprio_get sys_ioprio_get 300 300 291 i386 inotify_init sys_inotify_init
+6
arch/x86/entry/vdso/vdso2c.h
··· 22 22 23 23 ELF(Phdr) *pt = (ELF(Phdr) *)(raw_addr + GET_LE(&hdr->e_phoff)); 24 24 25 + if (hdr->e_type != ET_DYN) 26 + fail("input is not a shared object\n"); 27 + 25 28 /* Walk the segment table. */ 26 29 for (i = 0; i < GET_LE(&hdr->e_phnum); i++) { 27 30 if (GET_LE(&pt[i].p_type) == PT_LOAD) { ··· 51 48 52 49 if (stripped_len < load_size) 53 50 fail("stripped input is too short\n"); 51 + 52 + if (!dyn) 53 + fail("input has no PT_DYNAMIC section -- your toolchain is buggy\n"); 54 54 55 55 /* Walk the dynamic table */ 56 56 for (i = 0; dyn + i < dyn_end &&
+1 -4
arch/x86/include/asm/syscall.h
··· 60 60 * TS_COMPAT is set for 32-bit syscall entries and then 61 61 * remains set until we return to user mode. 62 62 */ 63 - if (task_thread_info(task)->status & TS_COMPAT) 63 + if (task_thread_info(task)->status & (TS_COMPAT|TS_I386_REGS_POKED)) 64 64 /* 65 65 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO 66 66 * and will match correctly in comparisons. ··· 238 238 /* 239 239 * TS_COMPAT is set for 32-bit syscall entry and then 240 240 * remains set until we return to user mode. 241 - * 242 - * TIF_IA32 tasks should always have TS_COMPAT set at 243 - * system call time. 244 241 * 245 242 * x32 tasks should be considered AUDIT_ARCH_X86_64. 246 243 */
+3
arch/x86/include/asm/thread_info.h
··· 219 219 * have to worry about atomic accesses. 220 220 */ 221 221 #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ 222 + #ifdef CONFIG_COMPAT 223 + #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ 224 + #endif 222 225 223 226 #ifndef __ASSEMBLY__ 224 227
+9 -6
arch/x86/kernel/ptrace.c
··· 923 923 924 924 case offsetof(struct user32, regs.orig_eax): 925 925 /* 926 - * A 32-bit debugger setting orig_eax means to restore 927 - * the state of the task restarting a 32-bit syscall. 928 - * Make sure we interpret the -ERESTART* codes correctly 929 - * in case the task is not actually still sitting at the 930 - * exit from a 32-bit syscall with TS_COMPAT still set. 926 + * Warning: bizarre corner case fixup here. A 32-bit 927 + * debugger setting orig_eax to -1 wants to disable 928 + * syscall restart. Make sure that the syscall 929 + * restart code sign-extends orig_ax. Also make sure 930 + * we interpret the -ERESTART* codes correctly if 931 + * loaded into regs->ax in case the task is not 932 + * actually still sitting at the exit from a 32-bit 933 + * syscall with TS_COMPAT still set. 931 934 */ 932 935 regs->orig_ax = value; 933 936 if (syscall_get_nr(child, regs) >= 0) 934 - task_thread_info(child)->status |= TS_COMPAT; 937 + task_thread_info(child)->status |= TS_I386_REGS_POKED; 935 938 break; 936 939 937 940 case offsetof(struct user32, regs.eflags):
+24 -2
arch/x86/kernel/signal.c
··· 760 760 761 761 static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) 762 762 { 763 - #ifdef CONFIG_X86_64 764 - if (in_ia32_syscall()) 763 + /* 764 + * This function is fundamentally broken as currently 765 + * implemented. 766 + * 767 + * The idea is that we want to trigger a call to the 768 + * restart_block() syscall and that we want in_ia32_syscall(), 769 + * in_x32_syscall(), etc. to match whatever they were in the 770 + * syscall being restarted. We assume that the syscall 771 + * instruction at (regs->ip - 2) matches whatever syscall 772 + * instruction we used to enter in the first place. 773 + * 774 + * The problem is that we can get here when ptrace pokes 775 + * syscall-like values into regs even if we're not in a syscall 776 + * at all. 777 + * 778 + * For now, we maintain historical behavior and guess based on 779 + * stored state. We could do better by saving the actual 780 + * syscall arch in restart_block or (with caveats on x32) by 781 + * checking if regs->ip points to 'int $0x80'. The current 782 + * behavior is incorrect if a tracer has a different bitness 783 + * than the tracee. 784 + */ 785 + #ifdef CONFIG_IA32_EMULATION 786 + if (current_thread_info()->status & (TS_COMPAT|TS_I386_REGS_POKED)) 765 787 return __NR_ia32_restart_syscall; 766 788 #endif 767 789 #ifdef CONFIG_X86_X32_ABI