All of lore.kernel.org
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@alien8.de>
To: Andy Lutomirski <luto@amacapital.net>
Cc: Ingo Molnar <mingo@kernel.org>, Andi Kleen <andi@firstfloor.org>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	x86@kernel.org, linux-kernel@vger.kernel.org,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: [PATCH v2 1/2] x86_64,signal: Fix SS handling for signals delivered to 64-bit programs
Date: Wed, 11 Mar 2015 09:31:31 +0100	[thread overview]
Message-ID: <20150311083131.GA16419@pd.tnic> (raw)
In-Reply-To: <ee0df6e0b7a4bd5283fa29f0d4fd11a4d39f45d1.1425995824.git.luto@amacapital.net>

On Tue, Mar 10, 2015 at 07:03:24AM -0700, Andy Lutomirski wrote:
> The comment in the signal code says that apps can save/restore other
> segments on their own.  It's true that apps can *save* SS on their
> own, but there's no way for apps to restore it: SYSCALL effectively
> resets SS to __USER_DS, so any value that user code tries to load
> into SS gets lost on entry to sigreturn.
> 
> This recycles two padding bytes in the segment selector area for SS.
> 
> While we're at it, we need a second change to make this useful.  If
> the signal we're delivering is caused by a bad SS value, saving that
> value isn't enough.  We need to remove that bad value from the regs
> before we try to deliver the signal.  Oddly, x32 already got this
> right.

Are we at least reporting the bad SS value when delivering the signal so
that userpsace knows why it got the signal?

> I suspect that 64-bit programs that try to run 16-bit code and uses
> signals will have a lot of trouble without this.

Do we even have software doing that? Maybe we should search for similar
bug reports...

> Signed-off-by: Andy Lutomirski <luto@amacapital.net>
> ---
>  arch/x86/include/asm/sigcontext.h      |  2 +-
>  arch/x86/include/uapi/asm/sigcontext.h |  2 +-
>  arch/x86/kernel/signal.c               | 20 +++++++++++---------
>  3 files changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
> index 9dfce4e0417d..f910cdcb71fd 100644
> --- a/arch/x86/include/asm/sigcontext.h
> +++ b/arch/x86/include/asm/sigcontext.h
> @@ -59,7 +59,7 @@ struct sigcontext {
>  	unsigned short cs;
>  	unsigned short gs;
>  	unsigned short fs;
> -	unsigned short __pad0;

This __pad0 thing has been there since the beginning, according to my
git history dive.

> +	unsigned short ss;
>  	unsigned long err;
>  	unsigned long trapno;
>  	unsigned long oldmask;
> diff --git a/arch/x86/include/uapi/asm/sigcontext.h b/arch/x86/include/uapi/asm/sigcontext.h
> index d8b9f9081e86..076b11fd6fa1 100644
> --- a/arch/x86/include/uapi/asm/sigcontext.h
> +++ b/arch/x86/include/uapi/asm/sigcontext.h
> @@ -179,7 +179,7 @@ struct sigcontext {
>  	__u16 cs;
>  	__u16 gs;
>  	__u16 fs;
> -	__u16 __pad0;
> +	__u16 ss;
>  	__u64 err;
>  	__u64 trapno;
>  	__u64 oldmask;
> diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
> index ed37a768d0fc..40f34574fb36 100644
> --- a/arch/x86/kernel/signal.c
> +++ b/arch/x86/kernel/signal.c
> @@ -94,15 +94,8 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
>  		COPY(r15);
>  #endif /* CONFIG_X86_64 */
>  
> -#ifdef CONFIG_X86_32
>  		COPY_SEG_CPL3(cs);
>  		COPY_SEG_CPL3(ss);
> -#else /* !CONFIG_X86_32 */
> -		/* Kernel saves and restores only the CS segment register on signals,
> -		 * which is the bare minimum needed to allow mixed 32/64-bit code.
> -		 * App's signal handler can save/restore other segments if needed. */
> -		COPY_SEG_CPL3(cs);
> -#endif /* CONFIG_X86_32 */
>  
>  		get_user_ex(tmpflags, &sc->flags);
>  		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
> @@ -164,6 +157,7 @@ int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
>  		put_user_ex(regs->cs, &sc->cs);
>  		put_user_ex(0, &sc->gs);
>  		put_user_ex(0, &sc->fs);
> +		put_user_ex(regs->ss, &sc->ss);
>  #endif /* CONFIG_X86_32 */
>  
>  		put_user_ex(fpstate, &sc->fpstate);
> @@ -457,9 +451,17 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
>  
>  	regs->sp = (unsigned long)frame;
>  
> -	/* Set up the CS register to run signal handlers in 64-bit mode,
> -	   even if the handler happens to be interrupting 32-bit code. */
> +	/* Set up the CS and SS registers to run signal handlers in
> +	   64-bit mode, even if the handler happens to be interrupting
> +	   32-bit or 16-bit code.
> +
> +	   SS is subtle.  In 64-bit mode, we don't need any particular
> +	   SS descriptor, but we do need SS to be valid.  It's possible
> +	   that the old SS is entirely bogus -- this can happen if the
> +	   signal we're trying to deliver is #GP or #SS caused by a bad
> +	   SS value. */

Kernel comment style please:

	/*
	 * Andy likes to go and play 16-bit games on 64-bit linux. We all are
	 * having lotsa fun.
	 */

:-D

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--

  parent reply	other threads:[~2015-03-11  8:33 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-10 14:03 [PATCH v2 0/2] x86_64: Sigcontext improvements Andy Lutomirski
2015-03-10 14:03 ` [PATCH v2 1/2] x86_64,signal: Fix SS handling for signals delivered to 64-bit programs Andy Lutomirski
2015-03-10 14:22   ` Andy Lutomirski
2015-03-10 16:42     ` Oleg Nesterov
2015-03-10 17:35       ` Andy Lutomirski
2015-03-11  8:31   ` Borislav Petkov [this message]
2015-03-12 20:38     ` Andy Lutomirski
2015-03-10 14:03 ` [PATCH v2 2/2] x86_64,signal: Remove 'fs' and 'gs' from sigcontext Andy Lutomirski
2015-03-10 14:22   ` Andy Lutomirski
2015-03-10 16:16   ` John Stoffel
2015-03-10 18:12     ` Andy Lutomirski
2015-03-11  9:28   ` Borislav Petkov
2015-03-11 12:22     ` Andy Lutomirski
2015-03-11 12:32       ` Borislav Petkov
2015-03-10 14:05 ` [PATCH v2 0/2] x86_64: Sigcontext improvements Andy Lutomirski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150311083131.GA16419@pd.tnic \
    --to=bp@alien8.de \
    --cc=andi@firstfloor.org \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mingo@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.