All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86: signal: move save_altstack_ex out of generic headers
@ 2020-03-24 22:08 Nick Desaulniers
  2020-04-03 23:16 ` [PATCH v2] " Nick Desaulniers
  0 siblings, 1 reply; 10+ messages in thread
From: Nick Desaulniers @ 2020-03-24 22:08 UTC (permalink / raw)
  To: tglx, mingo, bp
  Cc: Nick Desaulniers, Peter Zijlstra, clang-built-linux,
	Linus Torvalds, H. Peter Anvin, x86, Marco Elver,
	Andrey Ryabinin, Sami Tolvanen, Brian Gerst,
	Sebastian Andrzej Siewior, Andrew Morton, Jann Horn,
	Mathieu Desnoyers, Arnd Bergmann, Oleg Nesterov, Ben Hutchings,
	Eric W. Biederman, linux-kernel

In some configurations (clang+KASAN), sas_ss_reset() may emit calls to
memset().  This is a problem for SMAP protections on x86, which should
try to minimize calls to any function not already on short whitelist, in
order to prevent leaking AC flags or being used as a gadget.

Linus noted that save_altstack_ex() only has two callsites, in the
arch-specific arch/x86/kernel/signal.c, and shouldn't be defined in arch
independent headers. Move the definitions there, make them static
functions, then split the reset logic out, and move it outside of the
put_user_try/put_user_catch SMAP guards. This does less work with the
SMAP guards down.

Link: https://github.com/ClangBuiltLinux/linux/issues/876
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: <clang-built-linux@googlegroups.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
---
Notes to reviewers:
* The macro was maybe nicer since the compat_ versions have different
  type signatures.
* There's still some duplication, and the code could be DRY'er. Thoughts
  on whether to:
  a) move these to arch/x86/include/asm/sigframe.h as static inline
     functions.
  b) move these to a new header as static inline function.
  c) keep them as functions, but non-static, in their own new
     translation unit.
  d) patch is fine as it.
  e) other.


 arch/x86/ia32/ia32_signal.c | 18 +++++++++++++++++-
 arch/x86/kernel/signal.c    | 35 ++++++++++++++++++++++++++++++++---
 include/linux/compat.h      |  9 ---------
 include/linux/signal.h      | 10 ----------
 4 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index a3aefe9b9401..dadcc30d1138 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -325,6 +325,21 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
 	return 0;
 }
 
+static void compat_save_altstack_unsafe(compat_stack_t *uss, unsigned long sp)
+{
+	compat_stack_t __user *__uss = uss;
+	struct task_struct *t = current;
+	put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp);
+	put_user_ex(t->sas_ss_flags, &__uss->ss_flags);
+	put_user_ex(t->sas_ss_size, &__uss->ss_size);
+}
+
+static void reset_altstack(void)
+{
+	if (current->sas_ss_flags & SS_AUTODISARM)
+		sas_ss_reset(current);
+}
+
 int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
 			compat_sigset_t *set, struct pt_regs *regs)
 {
@@ -362,7 +377,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
 		else
 			put_user_ex(0, &frame->uc.uc_flags);
 		put_user_ex(0, &frame->uc.uc_link);
-		compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
+		compat_save_altstack_unsafe(&frame->uc.uc_stack, regs->sp);
 
 		if (ksig->ka.sa.sa_flags & SA_RESTORER)
 			restorer = ksig->ka.sa.sa_restorer;
@@ -377,6 +392,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
 		 */
 		put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
 	} put_user_catch(err);
+	reset_altstack();
 
 	err |= __copy_siginfo_to_user32(&frame->info, &ksig->info, false);
 	err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 8a29573851a3..03ea56ee86ec 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -213,6 +213,32 @@ int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
 	return err;
 }
 
+#ifdef CONFIG_X86_X32_ABI
+static void compat_save_altstack_unsafe(compat_stack_t *uss, unsigned long sp)
+{
+	compat_stack_t __user *__uss = uss;
+	struct task_struct *t = current;
+	put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp);
+	put_user_ex(t->sas_ss_flags, &__uss->ss_flags);
+	put_user_ex(t->sas_ss_size, &__uss->ss_size);
+}
+#endif
+
+static void save_altstack_unsafe(stack_t *uss, unsigned long sp)
+{
+	struct task_struct *t = current;
+	stack_t __user *__uss = uss;
+	put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp);
+	put_user_ex(t->sas_ss_flags, &__uss->ss_flags);
+	put_user_ex(t->sas_ss_size, &__uss->ss_size);
+}
+
+static void reset_altstack(void)
+{
+	if (current->sas_ss_flags & SS_AUTODISARM)
+		sas_ss_reset(current);
+}
+
 /*
  * Set up a signal frame.
  */
@@ -394,7 +420,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 		else
 			put_user_ex(0, &frame->uc.uc_flags);
 		put_user_ex(0, &frame->uc.uc_link);
-		save_altstack_ex(&frame->uc.uc_stack, regs->sp);
+		save_altstack_unsafe(&frame->uc.uc_stack, regs->sp);
 
 		/* Set up to return from userspace.  */
 		restorer = current->mm->context.vdso +
@@ -412,6 +438,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 		 */
 		put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
 	} put_user_catch(err);
+	reset_altstack();
 	
 	err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 	err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
@@ -475,7 +502,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 		/* Create the ucontext.  */
 		put_user_ex(uc_flags, &frame->uc.uc_flags);
 		put_user_ex(0, &frame->uc.uc_link);
-		save_altstack_ex(&frame->uc.uc_stack, regs->sp);
+		save_altstack_unsafe(&frame->uc.uc_stack, regs->sp);
 
 		/* Set up to return from userspace.  If provided, use a stub
 		   already in userspace.  */
@@ -487,6 +514,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 			err |= -EFAULT;
 		}
 	} put_user_catch(err);
+	reset_altstack();
 
 	err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
@@ -560,7 +588,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
 		/* Create the ucontext.  */
 		put_user_ex(uc_flags, &frame->uc.uc_flags);
 		put_user_ex(0, &frame->uc.uc_link);
-		compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
+		compat_save_altstack_unsafe(&frame->uc.uc_stack, regs->sp);
 		put_user_ex(0, &frame->uc.uc__pad0);
 
 		if (ksig->ka.sa.sa_flags & SA_RESTORER) {
@@ -572,6 +600,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
 		}
 		put_user_ex(restorer, (unsigned long __user *)&frame->pretcode);
 	} put_user_catch(err);
+	reset_altstack();
 
 	err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
 				regs, set->sig[0]);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index df2475be134a..083a771decb8 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -454,15 +454,6 @@ extern void __user *compat_alloc_user_space(unsigned long len);
 
 int compat_restore_altstack(const compat_stack_t __user *uss);
 int __compat_save_altstack(compat_stack_t __user *, unsigned long);
-#define compat_save_altstack_ex(uss, sp) do { \
-	compat_stack_t __user *__uss = uss; \
-	struct task_struct *t = current; \
-	put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \
-	put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
-	put_user_ex(t->sas_ss_size, &__uss->ss_size); \
-	if (t->sas_ss_flags & SS_AUTODISARM) \
-		sas_ss_reset(t); \
-} while (0);
 
 /*
  * These syscall function prototypes are kept in the same order as
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 1a5f88316b08..1732114989f7 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -444,16 +444,6 @@ void signals_init(void);
 int restore_altstack(const stack_t __user *);
 int __save_altstack(stack_t __user *, unsigned long);
 
-#define save_altstack_ex(uss, sp) do { \
-	stack_t __user *__uss = uss; \
-	struct task_struct *t = current; \
-	put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \
-	put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
-	put_user_ex(t->sas_ss_size, &__uss->ss_size); \
-	if (t->sas_ss_flags & SS_AUTODISARM) \
-		sas_ss_reset(t); \
-} while (0);
-
 #ifdef CONFIG_PROC_FS
 struct seq_file;
 extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
-- 
2.25.1.696.g5e7596f4ac-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-03-24 22:08 [PATCH] x86: signal: move save_altstack_ex out of generic headers Nick Desaulniers
@ 2020-04-03 23:16 ` Nick Desaulniers
  2020-04-03 23:39   ` Al Viro
  2020-04-04 16:01   ` Oleg Nesterov
  0 siblings, 2 replies; 10+ messages in thread
From: Nick Desaulniers @ 2020-04-03 23:16 UTC (permalink / raw)
  To: tglx, mingo, bp
  Cc: Nick Desaulniers, Peter Zijlstra, clang-built-linux,
	Linus Torvalds, H. Peter Anvin, x86, Al Viro,
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Oleg Nesterov, Eric W. Biederman, linux-kernel

In some configurations (clang+KASAN), sas_ss_reset() may emit calls to
memset().  This is a problem for SMAP protections on x86, which should
try to minimize calls to any function not already on short whitelist, in
order to prevent leaking AC flags or being used as a gadget.

Linus noted that unsafe_save_altstack() only has callsites in the
arch-specific arch/x86/kernel/signal.c, and shouldn't be defined in arch
independent headers.

Split the logic of unsafe_save_altstack() into two, and move the definitions
to arch/x86/include/asm/sigframe.h.  This does less work with the SMAP
guards down.

Link: https://github.com/ClangBuiltLinux/linux/issues/876
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: <clang-built-linux@googlegroups.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
---
Changes V1 -> V2:
* Rebased on top of
  commit 39f16c1c0f14 ("x86: get rid of put_user_try in {ia32,x32}_setup_rt_frame()")
* went back to macros instead of static inline functions I had in v1.
Note:
Technically, this is a functional change that does more work if we jump
to Efault before calling {__compat|unsafe}_save_altstack, though the
hope is that that is an exceptional case.

 arch/x86/ia32/ia32_signal.c     |  2 ++
 arch/x86/include/asm/sigframe.h | 13 +++++++++++++
 arch/x86/kernel/signal.c        |  4 ++++
 include/linux/compat.h          |  2 --
 include/linux/signal.h          | 10 ----------
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index f9d8804144d0..e18f6d9dc393 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -349,6 +349,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
 	unsafe_put_sigcontext32(&frame->uc.uc_mcontext, fp, regs, set, Efault);
 	unsafe_put_user(*(__u64 *)set, (__u64 *)&frame->uc.uc_sigmask, Efault);
 	user_access_end();
+	reset_altstack();
 
 	if (__copy_siginfo_to_user32(&frame->info, &ksig->info, false))
 		return -EFAULT;
@@ -371,5 +372,6 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
 	return 0;
 Efault:
 	user_access_end();
+	reset_altstack();
 	return -EFAULT;
 }
diff --git a/arch/x86/include/asm/sigframe.h b/arch/x86/include/asm/sigframe.h
index 84eab2724875..67c317b8585d 100644
--- a/arch/x86/include/asm/sigframe.h
+++ b/arch/x86/include/asm/sigframe.h
@@ -85,4 +85,17 @@ struct rt_sigframe_x32 {
 
 #endif /* CONFIG_X86_64 */
 
+#define unsafe_save_altstack(uss, sp, label) do { \
+	stack_t __user *__uss = uss; \
+	struct task_struct *t = current; \
+	unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
+	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
+	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
+} while (0);
+
+#define reset_altstack() do { \
+	if (current->sas_ss_flags & SS_AUTODISARM) \
+		sas_ss_reset(current); \
+} while (0);
+
 #endif /* _ASM_X86_SIGFRAME_H */
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 83b74fb38c8f..1e9a900929b3 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -416,6 +416,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 	return 0;
 Efault:
 	user_access_end();
+	reset_altstack();
 	return -EFAULT;
 }
 #else /* !CONFIG_X86_32 */
@@ -507,6 +508,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 
 Efault:
 	user_access_end();
+	reset_altstack();
 	return -EFAULT;
 }
 #endif /* CONFIG_X86_32 */
@@ -541,6 +543,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
 	unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault);
 	unsafe_put_sigmask(set, frame, Efault);
 	user_access_end();
+	reset_altstack();
 
 	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
 		if (__copy_siginfo_to_user32(&frame->info, &ksig->info, true))
@@ -567,6 +570,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
 #ifdef CONFIG_X86_X32_ABI
 Efault:
 	user_access_end();
+	reset_altstack();
 	return -EFAULT;
 #endif
 }
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 0480ba4db592..f614967374f5 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -461,8 +461,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 			&__uss->ss_sp, label); \
 	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
 	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
-	if (t->sas_ss_flags & SS_AUTODISARM) \
-		sas_ss_reset(t); \
 } while (0);
 
 /*
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 05bacd2ab135..1732114989f7 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -444,16 +444,6 @@ void signals_init(void);
 int restore_altstack(const stack_t __user *);
 int __save_altstack(stack_t __user *, unsigned long);
 
-#define unsafe_save_altstack(uss, sp, label) do { \
-	stack_t __user *__uss = uss; \
-	struct task_struct *t = current; \
-	unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
-	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
-	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
-	if (t->sas_ss_flags & SS_AUTODISARM) \
-		sas_ss_reset(t); \
-} while (0);
-
 #ifdef CONFIG_PROC_FS
 struct seq_file;
 extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
-- 
2.26.0.292.g33ef6b2f38-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-03 23:16 ` [PATCH v2] " Nick Desaulniers
@ 2020-04-03 23:39   ` Al Viro
  2020-04-04 16:01   ` Oleg Nesterov
  1 sibling, 0 replies; 10+ messages in thread
From: Al Viro @ 2020-04-03 23:39 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: tglx, mingo, bp, Peter Zijlstra, clang-built-linux,
	Linus Torvalds, H. Peter Anvin, x86, Sebastian Andrzej Siewior,
	Andy Lutomirski, Sami Tolvanen, Marco Elver, Brian Gerst,
	Arnd Bergmann, Andrew Morton, Oleg Nesterov, Eric W. Biederman,
	linux-kernel

On Fri, Apr 03, 2020 at 04:16:06PM -0700, Nick Desaulniers wrote:
> In some configurations (clang+KASAN), sas_ss_reset() may emit calls to
> memset().  This is a problem for SMAP protections on x86, which should
> try to minimize calls to any function not already on short whitelist, in
> order to prevent leaking AC flags or being used as a gadget.
> 
> Linus noted that unsafe_save_altstack() only has callsites in the
> arch-specific arch/x86/kernel/signal.c, and shouldn't be defined in arch
> independent headers.
> 
> Split the logic of unsafe_save_altstack() into two, and move the definitions
> to arch/x86/include/asm/sigframe.h.  This does less work with the SMAP
> guards down.

Just move that into signal_delivered() and that's it.  SMAP or no SMAP -
doing that until the sigframe is set and we are committed to entering
the handler is wrong.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-03 23:16 ` [PATCH v2] " Nick Desaulniers
  2020-04-03 23:39   ` Al Viro
@ 2020-04-04 16:01   ` Oleg Nesterov
  2020-04-04 17:06     ` Al Viro
  1 sibling, 1 reply; 10+ messages in thread
From: Oleg Nesterov @ 2020-04-04 16:01 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: tglx, mingo, bp, Peter Zijlstra, clang-built-linux,
	Linus Torvalds, H. Peter Anvin, x86, Al Viro,
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, linux-kernel

On 04/03, Nick Desaulniers wrote:
>
> --- a/arch/x86/kernel/signal.c
> +++ b/arch/x86/kernel/signal.c
> @@ -416,6 +416,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
>  	return 0;
>  Efault:
>  	user_access_end();
> +	reset_altstack();
>  	return -EFAULT;
>  }
>  #else /* !CONFIG_X86_32 */
> @@ -507,6 +508,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
>  
>  Efault:
>  	user_access_end();
> +	reset_altstack();
>  	return -EFAULT;
>  }

I must have missed something, but this looks just wrong.

reset_altstack() should be called when __setup_rt_frame() (and
unsafe_save_altstack() in particular) succeeds, not when it fails.

Nevermind, Al has already suggested to use signal_delivered()...

Oleg.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-04 16:01   ` Oleg Nesterov
@ 2020-04-04 17:06     ` Al Viro
  2020-04-04 17:31       ` Linus Torvalds
                         ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Al Viro @ 2020-04-04 17:06 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Nick Desaulniers, tglx, mingo, bp, Peter Zijlstra,
	clang-built-linux, Linus Torvalds, H. Peter Anvin, x86,
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, linux-kernel

On Sat, Apr 04, 2020 at 06:01:00PM +0200, Oleg Nesterov wrote:
> On 04/03, Nick Desaulniers wrote:
> >
> > --- a/arch/x86/kernel/signal.c
> > +++ b/arch/x86/kernel/signal.c
> > @@ -416,6 +416,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> >  	return 0;
> >  Efault:
> >  	user_access_end();
> > +	reset_altstack();
> >  	return -EFAULT;
> >  }
> >  #else /* !CONFIG_X86_32 */
> > @@ -507,6 +508,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> >  
> >  Efault:
> >  	user_access_end();
> > +	reset_altstack();
> >  	return -EFAULT;
> >  }
> 
> I must have missed something, but this looks just wrong.
> 
> reset_altstack() should be called when __setup_rt_frame() (and
> unsafe_save_altstack() in particular) succeeds, not when it fails.
> 
> Nevermind, Al has already suggested to use signal_delivered()...

FWIW, I propose to do is the patch below (against the current mainline);
objections?

Don't do sas_ss_reset() until we are certain that sigframe won't be abandoned

Currently we handle SS_AUTODISARM as soon as we have stored the
altstack settings into sigframe - that's the point when we have
set the things up for eventual sigreturn to restore the old settings.
And if we manage to set the sigframe up (we are not done with that
yet), everything's fine.  However, in case of failure we end up
with sigframe-to-be abandoned and SIGSEGV force-delivered.  And
in that case we end up with inconsistent rules - late failures
have altstack reset, early ones do not.

It's trivial to get consistent behaviour - just handle SS_AUTODISARM
once we have set the sigframe up and are committed to entering
the handler, i.e. in signal_delivered().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 0480ba4db592..f614967374f5 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -461,8 +461,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 			&__uss->ss_sp, label); \
 	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
 	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
-	if (t->sas_ss_flags & SS_AUTODISARM) \
-		sas_ss_reset(t); \
 } while (0);
 
 /*
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 05bacd2ab135..28fe9cc134f7 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -450,8 +450,6 @@ int __save_altstack(stack_t __user *, unsigned long);
 	unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
 	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
 	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
-	if (t->sas_ss_flags & SS_AUTODISARM) \
-		sas_ss_reset(t); \
 } while (0);
 
 #ifdef CONFIG_PROC_FS
diff --git a/kernel/signal.c b/kernel/signal.c
index e58a6c619824..4cfe0b9af588 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2769,6 +2769,8 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
 	if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
 		sigaddset(&blocked, ksig->sig);
 	set_current_blocked(&blocked);
+	if (current->sas_ss_flags & SS_AUTODISARM)
+		sas_ss_reset(current);
 	tracehook_signal_handler(stepping);
 }
 
@@ -4070,11 +4072,7 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
 	int err = __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
 		__put_user(t->sas_ss_flags, &uss->ss_flags) |
 		__put_user(t->sas_ss_size, &uss->ss_size);
-	if (err)
-		return err;
-	if (t->sas_ss_flags & SS_AUTODISARM)
-		sas_ss_reset(t);
-	return 0;
+	return err;
 }
 
 #ifdef CONFIG_COMPAT
@@ -4129,11 +4127,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
 			 &uss->ss_sp) |
 		__put_user(t->sas_ss_flags, &uss->ss_flags) |
 		__put_user(t->sas_ss_size, &uss->ss_size);
-	if (err)
-		return err;
-	if (t->sas_ss_flags & SS_AUTODISARM)
-		sas_ss_reset(t);
-	return 0;
+	return err;
 }
 #endif
 

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-04 17:06     ` Al Viro
@ 2020-04-04 17:31       ` Linus Torvalds
  2020-04-04 17:50       ` Oleg Nesterov
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Linus Torvalds @ 2020-04-04 17:31 UTC (permalink / raw)
  To: Al Viro
  Cc: Oleg Nesterov, Nick Desaulniers, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Peter Zijlstra, clang-built-linux,
	H. Peter Anvin, the arch/x86 maintainers,
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, Linux Kernel Mailing List

On Sat, Apr 4, 2020 at 10:06 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> FWIW, I propose to do is the patch below (against the current mainline);
> objections?

Lovely. Simple and clean.

               Linus

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-04 17:06     ` Al Viro
  2020-04-04 17:31       ` Linus Torvalds
@ 2020-04-04 17:50       ` Oleg Nesterov
  2020-04-04 22:50       ` Nathan Chancellor
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Oleg Nesterov @ 2020-04-04 17:50 UTC (permalink / raw)
  To: Al Viro
  Cc: Nick Desaulniers, tglx, mingo, bp, Peter Zijlstra,
	clang-built-linux, Linus Torvalds, H. Peter Anvin, x86,
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, linux-kernel

On 04/04, Al Viro wrote:
>
> On Sat, Apr 04, 2020 at 06:01:00PM +0200, Oleg Nesterov wrote:
> >
> > Nevermind, Al has already suggested to use signal_delivered()...
>
> FWIW, I propose to do is the patch below (against the current mainline);
> objections?

Looks great, fwiw

Acked-by: Oleg Nesterov <oleg@redhat.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-04 17:06     ` Al Viro
  2020-04-04 17:31       ` Linus Torvalds
  2020-04-04 17:50       ` Oleg Nesterov
@ 2020-04-04 22:50       ` Nathan Chancellor
  2020-04-13 19:12       ` Nick Desaulniers
  2020-06-26 18:18       ` Nick Desaulniers
  4 siblings, 0 replies; 10+ messages in thread
From: Nathan Chancellor @ 2020-04-04 22:50 UTC (permalink / raw)
  To: Al Viro
  Cc: Oleg Nesterov, Nick Desaulniers, tglx, mingo, bp, Peter Zijlstra,
	clang-built-linux, Linus Torvalds, H. Peter Anvin, x86,
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, linux-kernel

On Sat, Apr 04, 2020 at 06:06:04PM +0100, Al Viro wrote:
> On Sat, Apr 04, 2020 at 06:01:00PM +0200, Oleg Nesterov wrote:
> > On 04/03, Nick Desaulniers wrote:
> > >
> > > --- a/arch/x86/kernel/signal.c
> > > +++ b/arch/x86/kernel/signal.c
> > > @@ -416,6 +416,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> > >  	return 0;
> > >  Efault:
> > >  	user_access_end();
> > > +	reset_altstack();
> > >  	return -EFAULT;
> > >  }
> > >  #else /* !CONFIG_X86_32 */
> > > @@ -507,6 +508,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> > >  
> > >  Efault:
> > >  	user_access_end();
> > > +	reset_altstack();
> > >  	return -EFAULT;
> > >  }
> > 
> > I must have missed something, but this looks just wrong.
> > 
> > reset_altstack() should be called when __setup_rt_frame() (and
> > unsafe_save_altstack() in particular) succeeds, not when it fails.
> > 
> > Nevermind, Al has already suggested to use signal_delivered()...
> 
> FWIW, I propose to do is the patch below (against the current mainline);
> objections?
> 
> Don't do sas_ss_reset() until we are certain that sigframe won't be abandoned
> 
> Currently we handle SS_AUTODISARM as soon as we have stored the
> altstack settings into sigframe - that's the point when we have
> set the things up for eventual sigreturn to restore the old settings.
> And if we manage to set the sigframe up (we are not done with that
> yet), everything's fine.  However, in case of failure we end up
> with sigframe-to-be abandoned and SIGSEGV force-delivered.  And
> in that case we end up with inconsistent rules - late failures
> have altstack reset, early ones do not.
> 
> It's trivial to get consistent behaviour - just handle SS_AUTODISARM
> once we have set the sigframe up and are committed to entering
> the handler, i.e. in signal_delivered().
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index 0480ba4db592..f614967374f5 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -461,8 +461,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
>  			&__uss->ss_sp, label); \
>  	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
>  	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
> -	if (t->sas_ss_flags & SS_AUTODISARM) \
> -		sas_ss_reset(t); \
>  } while (0);
>  
>  /*
> diff --git a/include/linux/signal.h b/include/linux/signal.h
> index 05bacd2ab135..28fe9cc134f7 100644
> --- a/include/linux/signal.h
> +++ b/include/linux/signal.h
> @@ -450,8 +450,6 @@ int __save_altstack(stack_t __user *, unsigned long);
>  	unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
>  	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
>  	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
> -	if (t->sas_ss_flags & SS_AUTODISARM) \
> -		sas_ss_reset(t); \
>  } while (0);
>  
>  #ifdef CONFIG_PROC_FS
> diff --git a/kernel/signal.c b/kernel/signal.c
> index e58a6c619824..4cfe0b9af588 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2769,6 +2769,8 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
>  	if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
>  		sigaddset(&blocked, ksig->sig);
>  	set_current_blocked(&blocked);
> +	if (current->sas_ss_flags & SS_AUTODISARM)
> +		sas_ss_reset(current);
>  	tracehook_signal_handler(stepping);
>  }
>  
> @@ -4070,11 +4072,7 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
>  	int err = __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
>  		__put_user(t->sas_ss_flags, &uss->ss_flags) |
>  		__put_user(t->sas_ss_size, &uss->ss_size);
> -	if (err)
> -		return err;
> -	if (t->sas_ss_flags & SS_AUTODISARM)
> -		sas_ss_reset(t);
> -	return 0;
> +	return err;
>  }
>  
>  #ifdef CONFIG_COMPAT
> @@ -4129,11 +4127,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
>  			 &uss->ss_sp) |
>  		__put_user(t->sas_ss_flags, &uss->ss_flags) |
>  		__put_user(t->sas_ss_size, &uss->ss_size);
> -	if (err)
> -		return err;
> -	if (t->sas_ss_flags & SS_AUTODISARM)
> -		sas_ss_reset(t);
> -	return 0;
> +	return err;
>  }
>  #endif
>  
> 

On next-20200404, this makes the three objtool warnings about the call
to memset() with UACCESS disabled disappear and does not add any new
ones.

Tested-by: Nathan Chancellor <natechancellor@gmail.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-04 17:06     ` Al Viro
                         ` (2 preceding siblings ...)
  2020-04-04 22:50       ` Nathan Chancellor
@ 2020-04-13 19:12       ` Nick Desaulniers
  2020-06-26 18:18       ` Nick Desaulniers
  4 siblings, 0 replies; 10+ messages in thread
From: Nick Desaulniers @ 2020-04-13 19:12 UTC (permalink / raw)
  To: Al Viro
  Cc: Oleg Nesterov, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Peter Zijlstra, clang-built-linux, Linus Torvalds,
	H. Peter Anvin, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, LKML

On Sat, Apr 4, 2020 at 10:06 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> On Sat, Apr 04, 2020 at 06:01:00PM +0200, Oleg Nesterov wrote:
> > On 04/03, Nick Desaulniers wrote:
> > >
> > > --- a/arch/x86/kernel/signal.c
> > > +++ b/arch/x86/kernel/signal.c
> > > @@ -416,6 +416,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> > >     return 0;
> > >  Efault:
> > >     user_access_end();
> > > +   reset_altstack();
> > >     return -EFAULT;
> > >  }
> > >  #else /* !CONFIG_X86_32 */
> > > @@ -507,6 +508,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> > >
> > >  Efault:
> > >     user_access_end();
> > > +   reset_altstack();
> > >     return -EFAULT;
> > >  }
> >
> > I must have missed something, but this looks just wrong.
> >
> > reset_altstack() should be called when __setup_rt_frame() (and
> > unsafe_save_altstack() in particular) succeeds, not when it fails.
> >
> > Nevermind, Al has already suggested to use signal_delivered()...
>
> FWIW, I propose to do is the patch below (against the current mainline);
> objections?
>
> Don't do sas_ss_reset() until we are certain that sigframe won't be abandoned
>
> Currently we handle SS_AUTODISARM as soon as we have stored the
> altstack settings into sigframe - that's the point when we have
> set the things up for eventual sigreturn to restore the old settings.
> And if we manage to set the sigframe up (we are not done with that
> yet), everything's fine.  However, in case of failure we end up
> with sigframe-to-be abandoned and SIGSEGV force-delivered.  And
> in that case we end up with inconsistent rules - late failures
> have altstack reset, early ones do not.
>
> It's trivial to get consistent behaviour - just handle SS_AUTODISARM
> once we have set the sigframe up and are committed to entering
> the handler, i.e. in signal_delivered().
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Tested-by: Nick Desaulniers <ndesaulniers@google.com>
I'll follow up on our KASAN implementation turning two consecutive
longs into memset, which is odd.  Some of the recent changes to
unsafe_put_user to pass a label are triggering new
error: inline assembly requires more registers than available
in arch/x86/ia32/ia32_signal.c for me, but they're unrelated to this patch.

> ---
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index 0480ba4db592..f614967374f5 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -461,8 +461,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
>                         &__uss->ss_sp, label); \
>         unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
>         unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
> -       if (t->sas_ss_flags & SS_AUTODISARM) \
> -               sas_ss_reset(t); \
>  } while (0);
>
>  /*
> diff --git a/include/linux/signal.h b/include/linux/signal.h
> index 05bacd2ab135..28fe9cc134f7 100644
> --- a/include/linux/signal.h
> +++ b/include/linux/signal.h
> @@ -450,8 +450,6 @@ int __save_altstack(stack_t __user *, unsigned long);
>         unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
>         unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
>         unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
> -       if (t->sas_ss_flags & SS_AUTODISARM) \
> -               sas_ss_reset(t); \
>  } while (0);
>
>  #ifdef CONFIG_PROC_FS
> diff --git a/kernel/signal.c b/kernel/signal.c
> index e58a6c619824..4cfe0b9af588 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2769,6 +2769,8 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
>         if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
>                 sigaddset(&blocked, ksig->sig);
>         set_current_blocked(&blocked);
> +       if (current->sas_ss_flags & SS_AUTODISARM)
> +               sas_ss_reset(current);
>         tracehook_signal_handler(stepping);
>  }
>
> @@ -4070,11 +4072,7 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
>         int err = __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
>                 __put_user(t->sas_ss_flags, &uss->ss_flags) |
>                 __put_user(t->sas_ss_size, &uss->ss_size);
> -       if (err)
> -               return err;
> -       if (t->sas_ss_flags & SS_AUTODISARM)
> -               sas_ss_reset(t);
> -       return 0;
> +       return err;
>  }
>
>  #ifdef CONFIG_COMPAT
> @@ -4129,11 +4127,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
>                          &uss->ss_sp) |
>                 __put_user(t->sas_ss_flags, &uss->ss_flags) |
>                 __put_user(t->sas_ss_size, &uss->ss_size);
> -       if (err)
> -               return err;
> -       if (t->sas_ss_flags & SS_AUTODISARM)
> -               sas_ss_reset(t);
> -       return 0;
> +       return err;
>  }
>  #endif
>


-- 
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] x86: signal: move save_altstack_ex out of generic headers
  2020-04-04 17:06     ` Al Viro
                         ` (3 preceding siblings ...)
  2020-04-13 19:12       ` Nick Desaulniers
@ 2020-06-26 18:18       ` Nick Desaulniers
  4 siblings, 0 replies; 10+ messages in thread
From: Nick Desaulniers @ 2020-06-26 18:18 UTC (permalink / raw)
  To: Al Viro
  Cc: Oleg Nesterov, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Peter Zijlstra, clang-built-linux, Linus Torvalds,
	H. Peter Anvin, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Sebastian Andrzej Siewior, Andy Lutomirski, Sami Tolvanen,
	Marco Elver, Brian Gerst, Arnd Bergmann, Andrew Morton,
	Eric W. Biederman, LKML

On Sat, Apr 4, 2020 at 10:06 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> On Sat, Apr 04, 2020 at 06:01:00PM +0200, Oleg Nesterov wrote:
> > On 04/03, Nick Desaulniers wrote:
> > >
> > > --- a/arch/x86/kernel/signal.c
> > > +++ b/arch/x86/kernel/signal.c
> > > @@ -416,6 +416,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> > >     return 0;
> > >  Efault:
> > >     user_access_end();
> > > +   reset_altstack();
> > >     return -EFAULT;
> > >  }
> > >  #else /* !CONFIG_X86_32 */
> > > @@ -507,6 +508,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
> > >
> > >  Efault:
> > >     user_access_end();
> > > +   reset_altstack();
> > >     return -EFAULT;
> > >  }
> >
> > I must have missed something, but this looks just wrong.
> >
> > reset_altstack() should be called when __setup_rt_frame() (and
> > unsafe_save_altstack() in particular) succeeds, not when it fails.
> >
> > Nevermind, Al has already suggested to use signal_delivered()...
>
> FWIW, I propose to do is the patch below (against the current mainline);
> objections?
>
> Don't do sas_ss_reset() until we are certain that sigframe won't be abandoned
>
> Currently we handle SS_AUTODISARM as soon as we have stored the
> altstack settings into sigframe - that's the point when we have
> set the things up for eventual sigreturn to restore the old settings.
> And if we manage to set the sigframe up (we are not done with that
> yet), everything's fine.  However, in case of failure we end up
> with sigframe-to-be abandoned and SIGSEGV force-delivered.  And
> in that case we end up with inconsistent rules - late failures
> have altstack reset, early ones do not.
>
> It's trivial to get consistent behaviour - just handle SS_AUTODISARM
> once we have set the sigframe up and are committed to entering
> the handler, i.e. in signal_delivered().
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Hi Al,
Have you had time to wrap this up as its own commit and send?  I was
doing a bug scrub of our KernelCI warnings and noticed this is still
an issue.  Looks like everyone was happy with your approach.  Let me
know if you're too busy, and I'll collect all of the tags and send for
you.  I appreciate you taking the time to help us fix this.

> ---
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index 0480ba4db592..f614967374f5 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -461,8 +461,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
>                         &__uss->ss_sp, label); \
>         unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
>         unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
> -       if (t->sas_ss_flags & SS_AUTODISARM) \
> -               sas_ss_reset(t); \
>  } while (0);
>
>  /*
> diff --git a/include/linux/signal.h b/include/linux/signal.h
> index 05bacd2ab135..28fe9cc134f7 100644
> --- a/include/linux/signal.h
> +++ b/include/linux/signal.h
> @@ -450,8 +450,6 @@ int __save_altstack(stack_t __user *, unsigned long);
>         unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
>         unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
>         unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
> -       if (t->sas_ss_flags & SS_AUTODISARM) \
> -               sas_ss_reset(t); \
>  } while (0);
>
>  #ifdef CONFIG_PROC_FS
> diff --git a/kernel/signal.c b/kernel/signal.c
> index e58a6c619824..4cfe0b9af588 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2769,6 +2769,8 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
>         if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
>                 sigaddset(&blocked, ksig->sig);
>         set_current_blocked(&blocked);
> +       if (current->sas_ss_flags & SS_AUTODISARM)
> +               sas_ss_reset(current);
>         tracehook_signal_handler(stepping);
>  }
>
> @@ -4070,11 +4072,7 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
>         int err = __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
>                 __put_user(t->sas_ss_flags, &uss->ss_flags) |
>                 __put_user(t->sas_ss_size, &uss->ss_size);
> -       if (err)
> -               return err;
> -       if (t->sas_ss_flags & SS_AUTODISARM)
> -               sas_ss_reset(t);
> -       return 0;
> +       return err;
>  }
>
>  #ifdef CONFIG_COMPAT
> @@ -4129,11 +4127,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
>                          &uss->ss_sp) |
>                 __put_user(t->sas_ss_flags, &uss->ss_flags) |
>                 __put_user(t->sas_ss_size, &uss->ss_size);
> -       if (err)
> -               return err;
> -       if (t->sas_ss_flags & SS_AUTODISARM)
> -               sas_ss_reset(t);
> -       return 0;
> +       return err;
>  }
>  #endif
>


-- 
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-06-26 18:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-24 22:08 [PATCH] x86: signal: move save_altstack_ex out of generic headers Nick Desaulniers
2020-04-03 23:16 ` [PATCH v2] " Nick Desaulniers
2020-04-03 23:39   ` Al Viro
2020-04-04 16:01   ` Oleg Nesterov
2020-04-04 17:06     ` Al Viro
2020-04-04 17:31       ` Linus Torvalds
2020-04-04 17:50       ` Oleg Nesterov
2020-04-04 22:50       ` Nathan Chancellor
2020-04-13 19:12       ` Nick Desaulniers
2020-06-26 18:18       ` Nick Desaulniers

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.