linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andy Lutomirski <luto@kernel.org>
To: Borislav Petkov <bp@alien8.de>, Peter Zijlstra <peterz@infradead.org>
Cc: Sean Christopherson <seanjc@google.com>,
	kernel test robot <oliver.sang@intel.com>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>,
	x86@kernel.org, lkp@lists.01.org, lkp@intel.com
Subject: Re: [PATCH] x86/entry_32: Fix segment exceptions
Date: Thu, 13 Jan 2022 10:54:39 -0800	[thread overview]
Message-ID: <73020277-d49f-7aae-22db-945e040a31a2@kernel.org> (raw)
In-Reply-To: <Yd724f1Uv1GTZ+46@zn.tnic>

On 1/12/22 07:42, Borislav Petkov wrote:
> On Wed, Jan 12, 2022 at 11:55:41AM +0100, Peter Zijlstra wrote:
>> Full and proper patch below. Boris, if you could merge in x86/core that
>> branch should then be ready for a pull req.
> 
> I've got this as the final version. Scream if something's wrong.

AAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHH!!!!!!!!!!!


> 
> ---
> From: Peter Zijlstra <peterz@infradead.org>
> Date: Tue, 11 Jan 2022 12:11:14 +0100
> Subject: [PATCH] x86/entry_32: Fix segment exceptions
> 
> The LKP robot reported that commit in Fixes: caused a failure. Turns out
> the ldt_gdt_32 selftest turns into an infinite loop trying to clear the
> segment.
> 
> As discovered by Sean, what happens is that PARANOID_EXIT_TO_KERNEL_MODE
> in the handle_exception_return path overwrites the entry stack data with
> the task stack data, restoring the "bad" segment value.
> 
> Instead of having the exception retry the instruction, have it emulate
> the full instruction. Replace EX_TYPE_POP_ZERO with EX_TYPE_POP_REG
> which will do the equivalent of: POP %reg; MOV $imm, %reg.
> 
> In order to encode the segment registers, add them as registers 8-11 for
> 32-bit.
> 
> By setting regs->[defg]s the (nested) RESTORE_REGS will pop this value
> at the end of the exception handler and by increasing regs->sp, it will
> have skipped the stack slot.
> 
> This was debugged by Sean Christopherson <seanjc@google.com>.
> 
>   [ bp: Add EX_REG_GS too. ]
> 
> Fixes: aa93e2ad7464 ("x86/entry_32: Remove .fixup usage")
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Signed-off-by: Borislav Petkov <bp@suse.de>
> Link: https://lore.kernel.org/r/Yd1l0gInc4zRcnt/@hirez.programming.kicks-ass.net
> ---
>   arch/x86/entry/entry_32.S                  | 13 +++++++++----
>   arch/x86/include/asm/extable_fixup_types.h | 11 ++++++++++-
>   arch/x86/lib/insn-eval.c                   |  5 +++++
>   arch/x86/mm/extable.c                      | 17 +++--------------
>   4 files changed, 27 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
> index e0a95d8a6553..a7ec22b1d06c 100644
> --- a/arch/x86/entry/entry_32.S
> +++ b/arch/x86/entry/entry_32.S
> @@ -268,11 +268,16 @@
>   1:	popl	%ds
>   2:	popl	%es
>   3:	popl	%fs
> -	addl	$(4 + \pop), %esp	/* pop the unused "gs" slot */
> +4:	addl	$(4 + \pop), %esp	/* pop the unused "gs" slot */
>   	IRET_FRAME
> -	_ASM_EXTABLE_TYPE(1b, 1b, EX_TYPE_POP_ZERO)
> -	_ASM_EXTABLE_TYPE(2b, 2b, EX_TYPE_POP_ZERO)
> -	_ASM_EXTABLE_TYPE(3b, 3b, EX_TYPE_POP_ZERO)
> +
> +	/*
> +	 * There is no _ASM_EXTABLE_TYPE_REG() for ASM, however since this is
> +	 * ASM the registers are known and we can trivially hard-code them.
> +	 */
> +	_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_POP_ZERO|EX_REG_DS)
> +	_ASM_EXTABLE_TYPE(2b, 3b, EX_TYPE_POP_ZERO|EX_REG_ES)
> +	_ASM_EXTABLE_TYPE(3b, 4b, EX_TYPE_POP_ZERO|EX_REG_FS)

Aside from POP_ZERO being a bit mystifying to a naive reader...

>   .endm
>   
>   .macro RESTORE_ALL_NMI cr3_reg:req pop=0
> diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h
> index b5ab333e064a..503622627400 100644
> --- a/arch/x86/include/asm/extable_fixup_types.h
> +++ b/arch/x86/include/asm/extable_fixup_types.h
> @@ -16,9 +16,16 @@
>   #define EX_DATA_FLAG_SHIFT		12
>   #define EX_DATA_IMM_SHIFT		16
>   
> +#define EX_DATA_REG(reg)		((reg) << EX_DATA_REG_SHIFT)
>   #define EX_DATA_FLAG(flag)		((flag) << EX_DATA_FLAG_SHIFT)
>   #define EX_DATA_IMM(imm)		((imm) << EX_DATA_IMM_SHIFT)
>   
> +/* segment regs */
> +#define EX_REG_DS			EX_DATA_REG(8)
> +#define EX_REG_ES			EX_DATA_REG(9)
> +#define EX_REG_FS			EX_DATA_REG(10)

These three seem likely to work

> +#define EX_REG_GS			EX_DATA_REG(11)

But not this one.

> +
>   /* flags */
>   #define EX_FLAG_CLEAR_AX		EX_DATA_FLAG(1)
>   #define EX_FLAG_CLEAR_DX		EX_DATA_FLAG(2)
> @@ -41,7 +48,9 @@
>   #define	EX_TYPE_RDMSR_IN_MCE		13
>   #define	EX_TYPE_DEFAULT_MCE_SAFE	14
>   #define	EX_TYPE_FAULT_MCE_SAFE		15
> -#define	EX_TYPE_POP_ZERO		16
> +
> +#define	EX_TYPE_POP_REG			16 /* sp += sizeof(long) */
> +#define EX_TYPE_POP_ZERO		(EX_TYPE_POP_REG | EX_DATA_IMM(0))
>   
>   #define	EX_TYPE_IMM_REG			17 /* reg := (long)imm */
>   #define	EX_TYPE_EFAULT_REG		(EX_TYPE_IMM_REG | EX_DATA_IMM(-EFAULT))
> diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
> index 7760d228041b..c8a962c2e653 100644
> --- a/arch/x86/lib/insn-eval.c
> +++ b/arch/x86/lib/insn-eval.c
> @@ -430,6 +430,11 @@ static const int pt_regoff[] = {
>   	offsetof(struct pt_regs, r13),
>   	offsetof(struct pt_regs, r14),
>   	offsetof(struct pt_regs, r15),
> +#else
> +	offsetof(struct pt_regs, ds),
> +	offsetof(struct pt_regs, es),
> +	offsetof(struct pt_regs, fs),
> +	offsetof(struct pt_regs, gs),

See the comment in asm/ptrace.h over gs :)

Fortunately nothing uses EX_REG_GS.  Maybe just remove all the gs bits 
and leave the rest alone?

  reply	other threads:[~2022-01-13 18:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-06  8:35 [x86/entry_32] aa93e2ad74: BUG:soft_lockup-CPU##stuck_for#s![systemd-logind:#] kernel test robot
2022-01-11 11:11 ` Peter Zijlstra
2022-01-12  1:28   ` Sean Christopherson
2022-01-12 10:25     ` Peter Zijlstra
2022-01-12 16:14       ` Sean Christopherson
2022-01-12 10:55     ` [PATCH] x86/entry_32: Fix segment exceptions Peter Zijlstra
2022-01-12 15:42       ` Borislav Petkov
2022-01-13 18:54         ` Andy Lutomirski [this message]
2022-01-13 19:55           ` Peter Zijlstra
2022-01-14 11:24             ` Borislav Petkov
2022-01-14 23:48               ` Andy Lutomirski
2022-01-15  8:13                 ` Borislav Petkov

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=73020277-d49f-7aae-22db-945e040a31a2@kernel.org \
    --to=luto@kernel.org \
    --cc=bp@alien8.de \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=lkp@lists.01.org \
    --cc=oliver.sang@intel.com \
    --cc=peterz@infradead.org \
    --cc=seanjc@google.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).