x86: Remove force_iret()
authorBrian Gerst <brgerst@gmail.com>
Thu, 19 Dec 2019 11:58:12 +0000 (06:58 -0500)
committerBorislav Petkov <bp@suse.de>
Wed, 8 Jan 2020 18:40:51 +0000 (19:40 +0100)
force_iret() was originally intended to prevent the return to user mode with
the SYSRET or SYSEXIT instructions, in cases where the register state could
have been changed to be incompatible with those instructions.  The entry code
has been significantly reworked since then, and register state is validated
before SYSRET or SYSEXIT are used.  force_iret() no longer serves its original
purpose and can be eliminated.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lkml.kernel.org/r/20191219115812.102620-1-brgerst@gmail.com
arch/x86/ia32/ia32_signal.c
arch/x86/include/asm/ptrace.h
arch/x86/include/asm/thread_info.h
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/signal.c
arch/x86/kernel/vm86_32.c

index 30416d7f19d4f8b94248e9e4e149fb21b5e26f8b..a3aefe9b94012ab028a62f0f8b97e20b238f0076 100644 (file)
@@ -114,8 +114,6 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
 
        err |= fpu__restore_sig(buf, 1);
 
-       force_iret();
-
        return err;
 }
 
index 5057a8ed100b8234a9e0dddfeae2a712b98b3101..78897a8da01f7c230e860f12962bebdc2b1a2954 100644 (file)
@@ -339,22 +339,6 @@ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
 
 #define ARCH_HAS_USER_SINGLE_STEP_REPORT
 
-/*
- * When hitting ptrace_stop(), we cannot return using SYSRET because
- * that does not restore the full CPU state, only a minimal set.  The
- * ptracer can change arbitrary register values, which is usually okay
- * because the usual ptrace stops run off the signal delivery path which
- * forces IRET; however, ptrace_event() stops happen in arbitrary places
- * in the kernel and don't force IRET path.
- *
- * So force IRET path after a ptrace stop.
- */
-#define arch_ptrace_stop_needed(code, info)                            \
-({                                                                     \
-       force_iret();                                                   \
-       false;                                                          \
-})
-
 struct user_desc;
 extern int do_get_thread_area(struct task_struct *p, int idx,
                              struct user_desc __user *info);
index d779366ce3f89f161c977e7fad5389659108a1bd..cf4327986e98d5bb6ef8a322d4314d0d76e5c9fd 100644 (file)
@@ -239,15 +239,6 @@ static inline int arch_within_stack_frames(const void * const stack,
                           current_thread_info()->status & TS_COMPAT)
 #endif
 
-/*
- * Force syscall return via IRET by making it look as if there was
- * some work pending. IRET is our most capable (but slowest) syscall
- * return path, which is able to restore modified SS, CS and certain
- * EFLAGS values that other (fast) syscall return instructions
- * are not able to restore properly.
- */
-#define force_iret() set_thread_flag(TIF_NOTIFY_RESUME)
-
 extern void arch_task_cache_init(void);
 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 extern void arch_release_task_struct(struct task_struct *tsk);
index 323499f48858b87b7dc034574e53f2896b7cc395..5052ced433734be371a619ac31daa71516f539ec 100644 (file)
@@ -124,7 +124,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
        regs->ip                = new_ip;
        regs->sp                = new_sp;
        regs->flags             = X86_EFLAGS_IF;
-       force_iret();
 }
 EXPORT_SYMBOL_GPL(start_thread);
 
index 506d66830d4d7ea70444a54f5be7aa8ad9c73860..ffd497804dbc3406426eb95589db30c90111d255 100644 (file)
@@ -394,7 +394,6 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip,
        regs->cs                = _cs;
        regs->ss                = _ss;
        regs->flags             = X86_EFLAGS_IF;
-       force_iret();
 }
 
 void
index 8eb7193e158dd8741beb11eece6e5f11ca28b0dd..8a29573851a3273b2ca9831f8dab87f41d1f1c76 100644 (file)
@@ -151,8 +151,6 @@ static int restore_sigcontext(struct pt_regs *regs,
 
        err |= fpu__restore_sig(buf, IS_ENABLED(CONFIG_X86_32));
 
-       force_iret();
-
        return err;
 }
 
index a76c12b38e925a378cab92dba4ca5638dcf29645..91d55454e7022aa7b93a1a1da1202cded5dc3e99 100644 (file)
@@ -381,7 +381,6 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
                mark_screen_rdonly(tsk->mm);
 
        memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
-       force_iret();
        return regs->ax;
 }