All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch 0/3] x86/pti: Fix various fallout
@ 2017-12-30 21:13 Thomas Gleixner
  2017-12-30 21:13 ` [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path Thomas Gleixner
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Thomas Gleixner @ 2017-12-30 21:13 UTC (permalink / raw)
  To: LKML
  Cc: Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski

The small series fixes the recent fallout of the x86/pti merge:

 - Remove the stale local_flush_tlb() invocations from the CPU hotplug code
    
 - Remove the stale preempt_disable/enable() pair from __native_flush_tlb()

 - Fix a bogus free in the write_ldt() error path

Thanks,

	tglx

---
 include/asm/tlbflush.h |   14 ++++++++------
 kernel/ldt.c           |    2 +-
 kernel/smpboot.c       |    9 ---------
 3 files changed, 9 insertions(+), 16 deletions(-)

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

* [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path
  2017-12-30 21:13 [patch 0/3] x86/pti: Fix various fallout Thomas Gleixner
@ 2017-12-30 21:13 ` Thomas Gleixner
  2017-12-30 21:33   ` Ingo Molnar
  2017-12-31 10:24   ` [patch V2 1/3] x86/ldt: Plug memory leak in " Thomas Gleixner
  2017-12-30 21:13 ` [patch 2/3] x86/smpboot: Remove stale tlb flush invocations Thomas Gleixner
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 12+ messages in thread
From: Thomas Gleixner @ 2017-12-30 21:13 UTC (permalink / raw)
  To: LKML
  Cc: Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski,
	Mathieu Desnoyers

[-- Attachment #1: x86-ldt--Free-the-right-thing-in-error-path.patch --]
[-- Type: text/plain, Size: 693 bytes --]

The error path in write_ldt() frees the already installed LDT memory
instead of the newly allocated which cannot be installed.

Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/ldt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -421,7 +421,7 @@ static int write_ldt(void __user *ptr, u
 	 */
 	error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0);
 	if (error) {
-		free_ldt_struct(old_ldt);
+		free_ldt_struct(new_ldt);
 		goto out_unlock;
 	}
 

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

* [patch 2/3] x86/smpboot: Remove stale tlb flush invocations
  2017-12-30 21:13 [patch 0/3] x86/pti: Fix various fallout Thomas Gleixner
  2017-12-30 21:13 ` [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path Thomas Gleixner
@ 2017-12-30 21:13 ` Thomas Gleixner
  2017-12-30 21:32   ` Ingo Molnar
  2017-12-30 21:13 ` [patch 3/3] x86/mm: Remove preempt_disable/enable() from __native_flush_tlb() Thomas Gleixner
  2017-12-30 21:35 ` [patch 0/3] x86/pti: Fix various fallout Ingo Molnar
  3 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2017-12-30 21:13 UTC (permalink / raw)
  To: LKML
  Cc: Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski

[-- Attachment #1: x86-smpboot--Remove-stale-tlb-flush-invocations.patch --]
[-- Type: text/plain, Size: 1504 bytes --]

smpboot_setup_warm_reset_vector() and smpboot_restore_warm_reset_vector()
invoke local_flush_tlb() for no obvious reason.

Digging in history revealed that the original code in the 2.1 aera added
those because the code manipulated a swapper_pg_dir pagetable entry. The
pagetable manipulation was removed long ago in the 2.3 timeframe, but the
tlb flush invocations stayed around forever.

Remove them along with the pointless pr_debugs which come from the same 2.1
change.

Reported-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/smpboot.c |    9 ---------
 1 file changed, 9 deletions(-)

--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -128,14 +128,10 @@ static inline void smpboot_setup_warm_re
 	spin_lock_irqsave(&rtc_lock, flags);
 	CMOS_WRITE(0xa, 0xf);
 	spin_unlock_irqrestore(&rtc_lock, flags);
-	local_flush_tlb();
-	pr_debug("1.\n");
 	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
 							start_eip >> 4;
-	pr_debug("2.\n");
 	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
 							start_eip & 0xf;
-	pr_debug("3.\n");
 }
 
 static inline void smpboot_restore_warm_reset_vector(void)
@@ -143,11 +139,6 @@ static inline void smpboot_restore_warm_
 	unsigned long flags;
 
 	/*
-	 * Install writable page 0 entry to set BIOS data area.
-	 */
-	local_flush_tlb();
-
-	/*
 	 * Paranoid:  Set warm reset code and vector here back
 	 * to default values.
 	 */

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

* [patch 3/3] x86/mm: Remove preempt_disable/enable() from __native_flush_tlb()
  2017-12-30 21:13 [patch 0/3] x86/pti: Fix various fallout Thomas Gleixner
  2017-12-30 21:13 ` [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path Thomas Gleixner
  2017-12-30 21:13 ` [patch 2/3] x86/smpboot: Remove stale tlb flush invocations Thomas Gleixner
@ 2017-12-30 21:13 ` Thomas Gleixner
  2017-12-30 21:31   ` Ingo Molnar
  2017-12-30 21:35 ` [patch 0/3] x86/pti: Fix various fallout Ingo Molnar
  3 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2017-12-30 21:13 UTC (permalink / raw)
  To: LKML
  Cc: Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski

[-- Attachment #1: x86-mm--Remove-preempt_disable-enable---from-__native_tlb_flush--.patch --]
[-- Type: text/plain, Size: 1960 bytes --]

The preempt_disable/enable() pair in __native_flush_tlb() was added in
commit 5cf0791da5c1 ("x86/mm: Disable preemption during CR3 read+write") to
protect the UP variant of flush_tlb_mm_range().

That preempt_disable/enable() pair should have been added to the UP variant
of flush_tlb_mm_range() instead.

The UP variant was removed with commit ce4a4e565f52 ("x86/mm: Remove the UP
asm/tlbflush.h code, always use the (formerly) SMP code"), but the
preempt_disable/enable() pair stayed around.

The latest change to __native_flush_tlb() in commit 6fd166aae78c ("x86/mm:
Use/Fix PCID to optimize user/kernel switches") added an access to a per
cpu variable outside the preempt disabled regions which makes no sense at
all. __native_flush_tlb() must always be called with at least preemption
disabled.

Remove the preempt_disable/enable() pair and add a WARN_ON_ONCE() to catch
bad callers independent of the smp_processor_id() debugging.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/tlbflush.h |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -345,15 +345,17 @@ static inline void invalidate_user_asid(
  */
 static inline void __native_flush_tlb(void)
 {
-	invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
 	/*
-	 * If current->mm == NULL then we borrow a mm which may change
-	 * during a task switch and therefore we must not be preempted
-	 * while we write CR3 back:
+	 * Preemption or interrupts must be disabled to protect the access
+	 * to the per cpu variable and to prevent being preempted between
+	 * read_cr3() and write_cr3().
 	 */
-	preempt_disable();
+	WARN_ON_ONCE(preemptible());
+
+	invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
+
+	/* If current->mm == NULL then the read_cr3() "borrows" a mm */
 	native_write_cr3(__native_read_cr3());
-	preempt_enable();
 }
 
 /*

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

* Re: [patch 3/3] x86/mm: Remove preempt_disable/enable() from __native_flush_tlb()
  2017-12-30 21:13 ` [patch 3/3] x86/mm: Remove preempt_disable/enable() from __native_flush_tlb() Thomas Gleixner
@ 2017-12-30 21:31   ` Ingo Molnar
  0 siblings, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2017-12-30 21:31 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski


The cleanup looks good to me, just a few speling nits:

* Thomas Gleixner <tglx@linutronix.de> wrote:

> The preempt_disable/enable() pair in __native_flush_tlb() was added in
> commit 5cf0791da5c1 ("x86/mm: Disable preemption during CR3 read+write") to
> protect the UP variant of flush_tlb_mm_range().
> 
> That preempt_disable/enable() pair should have been added to the UP variant
> of flush_tlb_mm_range() instead.
> 
> The UP variant was removed with commit ce4a4e565f52 ("x86/mm: Remove the UP
> asm/tlbflush.h code, always use the (formerly) SMP code"), but the
> preempt_disable/enable() pair stayed around.
> 
> The latest change to __native_flush_tlb() in commit 6fd166aae78c ("x86/mm:
> Use/Fix PCID to optimize user/kernel switches") added an access to a per
> cpu variable outside the preempt disabled regions which makes no sense at
> all. __native_flush_tlb() must always be called with at least preemption
> disabled.

s/cpu/CPU

> 
> Remove the preempt_disable/enable() pair and add a WARN_ON_ONCE() to catch
> bad callers independent of the smp_processor_id() debugging.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/x86/include/asm/tlbflush.h |   14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> --- a/arch/x86/include/asm/tlbflush.h
> +++ b/arch/x86/include/asm/tlbflush.h
> @@ -345,15 +345,17 @@ static inline void invalidate_user_asid(
>   */
>  static inline void __native_flush_tlb(void)
>  {
> -	invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
>  	/*
> -	 * If current->mm == NULL then we borrow a mm which may change
> -	 * during a task switch and therefore we must not be preempted
> -	 * while we write CR3 back:
> +	 * Preemption or interrupts must be disabled to protect the access
> +	 * to the per cpu variable and to prevent being preempted between
> +	 * read_cr3() and write_cr3().
>  	 */
> -	preempt_disable();
> +	WARN_ON_ONCE(preemptible());
> +
> +	invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
> +
> +	/* If current->mm == NULL then the read_cr3() "borrows" a mm */
>  	native_write_cr3(__native_read_cr3());
> -	preempt_enable();

s/a mm/an mm

Reviewed-by: Ingo Molnar <mingo@kernel.org>

Thanks,

	Ingo

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

* Re: [patch 2/3] x86/smpboot: Remove stale tlb flush invocations
  2017-12-30 21:13 ` [patch 2/3] x86/smpboot: Remove stale tlb flush invocations Thomas Gleixner
@ 2017-12-30 21:32   ` Ingo Molnar
  0 siblings, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2017-12-30 21:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski


* Thomas Gleixner <tglx@linutronix.de> wrote:

> smpboot_setup_warm_reset_vector() and smpboot_restore_warm_reset_vector()
> invoke local_flush_tlb() for no obvious reason.
> 
> Digging in history revealed that the original code in the 2.1 aera added
> those because the code manipulated a swapper_pg_dir pagetable entry. The
> pagetable manipulation was removed long ago in the 2.3 timeframe, but the
> tlb flush invocations stayed around forever.

s/tlb/TLB

> 
> Remove them along with the pointless pr_debugs which come from the same 2.1
> change.
> 
> Reported-by: Dominik Brodowski <linux@dominikbrodowski.net>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/x86/kernel/smpboot.c |    9 ---------
>  1 file changed, 9 deletions(-)
> 
> --- a/arch/x86/kernel/smpboot.c
> +++ b/arch/x86/kernel/smpboot.c
> @@ -128,14 +128,10 @@ static inline void smpboot_setup_warm_re
>  	spin_lock_irqsave(&rtc_lock, flags);
>  	CMOS_WRITE(0xa, 0xf);
>  	spin_unlock_irqrestore(&rtc_lock, flags);
> -	local_flush_tlb();
> -	pr_debug("1.\n");
>  	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
>  							start_eip >> 4;
> -	pr_debug("2.\n");
>  	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
>  							start_eip & 0xf;
> -	pr_debug("3.\n");
>  }
>  
>  static inline void smpboot_restore_warm_reset_vector(void)
> @@ -143,11 +139,6 @@ static inline void smpboot_restore_warm_
>  	unsigned long flags;
>  
>  	/*
> -	 * Install writable page 0 entry to set BIOS data area.
> -	 */
> -	local_flush_tlb();
> -
> -	/*
>  	 * Paranoid:  Set warm reset code and vector here back
>  	 * to default values.
>  	 */

Really nice archeology! :-)

Reviewed-by: Ingo Molnar <mingo@kernel.org>

Thanks,

	Ingo

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

* Re: [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path
  2017-12-30 21:13 ` [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path Thomas Gleixner
@ 2017-12-30 21:33   ` Ingo Molnar
  2017-12-31 10:24   ` [patch V2 1/3] x86/ldt: Plug memory leak in " Thomas Gleixner
  1 sibling, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2017-12-30 21:33 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski,
	Mathieu Desnoyers


* Thomas Gleixner <tglx@linutronix.de> wrote:

> The error path in write_ldt() frees the already installed LDT memory
> instead of the newly allocated which cannot be installed.

s/newly allocated
 /newly allocated one

> 
> Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
> Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  arch/x86/kernel/ldt.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- a/arch/x86/kernel/ldt.c
> +++ b/arch/x86/kernel/ldt.c
> @@ -421,7 +421,7 @@ static int write_ldt(void __user *ptr, u
>  	 */
>  	error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0);
>  	if (error) {
> -		free_ldt_struct(old_ldt);
> +		free_ldt_struct(new_ldt);
>  		goto out_unlock;
>  	}
>  

This bug kind of scares me ...

Reviewed-by: Ingo Molnar <mingo@kernel.org>

Thanks,

	Ingo

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

* Re: [patch 0/3] x86/pti: Fix various fallout
  2017-12-30 21:13 [patch 0/3] x86/pti: Fix various fallout Thomas Gleixner
                   ` (2 preceding siblings ...)
  2017-12-30 21:13 ` [patch 3/3] x86/mm: Remove preempt_disable/enable() from __native_flush_tlb() Thomas Gleixner
@ 2017-12-30 21:35 ` Ingo Molnar
  2017-12-30 22:06   ` Linus Torvalds
  3 siblings, 1 reply; 12+ messages in thread
From: Ingo Molnar @ 2017-12-30 21:35 UTC (permalink / raw)
  To: Thomas Gleixner, Linus Torvalds
  Cc: LKML, Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski


* Thomas Gleixner <tglx@linutronix.de> wrote:

> The small series fixes the recent fallout of the x86/pti merge:
> 
>  - Remove the stale local_flush_tlb() invocations from the CPU hotplug code
>     
>  - Remove the stale preempt_disable/enable() pair from __native_flush_tlb()
> 
>  - Fix a bogus free in the write_ldt() error path

Linus, I suspect -rc6 is imminent, and it would be nice to at least have the LDT 
error path fix in. I'll send you these fixes tomorrow, but feel free to pick it up 
from email if you wanted to release -rc6 today.

Thanks,

	Ingo

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

* Re: [patch 0/3] x86/pti: Fix various fallout
  2017-12-30 21:35 ` [patch 0/3] x86/pti: Fix various fallout Ingo Molnar
@ 2017-12-30 22:06   ` Linus Torvalds
  2017-12-31  2:23     ` Andy Lutomirski
  0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2017-12-30 22:06 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Thomas Gleixner, LKML, the arch/x86 maintainers, Andy Lutomirski,
	Dave Hansen, Peter Zijlstra, Borislav Petkov, Dominik Brodowski

On Sat, Dec 30, 2017 at 1:35 PM, Ingo Molnar <mingo@kernel.org> wrote:
>
> Linus, I suspect -rc6 is imminent, and it would be nice to at least have the LDT
> error path fix in. I'll send you these fixes tomorrow, but feel free to pick it up
> from email if you wanted to release -rc6 today.

I'll do rc6 tomorrow probably around this time (early afternoon PST).
So I think I should be ok just waiting for your pull request.

Thanks,

                  Linus

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

* Re: [patch 0/3] x86/pti: Fix various fallout
  2017-12-30 22:06   ` Linus Torvalds
@ 2017-12-31  2:23     ` Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: Andy Lutomirski @ 2017-12-31  2:23 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Ingo Molnar, Thomas Gleixner, LKML, the arch/x86 maintainers,
	Andy Lutomirski, Dave Hansen, Peter Zijlstra, Borislav Petkov,
	Dominik Brodowski



> On Dec 30, 2017, at 2:06 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote:
> 
>> On Sat, Dec 30, 2017 at 1:35 PM, Ingo Molnar <mingo@kernel.org> wrote:
>> 
>> Linus, I suspect -rc6 is imminent, and it would be nice to at least have the LDT
>> error path fix in. I'll send you these fixes tomorrow, but feel free to pick it up
>> from email if you wanted to release -rc6 today.
> 
> I'll do rc6 tomorrow probably around this time (early afternoon PST).
> So I think I should be ok just waiting for your pull request.

FWIW, I think this big is at worst just a memory leak.  Once an mm has any LDT mapped, mapping a second one can't fail because the entire LDT area is under 512 pages, meaning that nothing needs to be allocated, so there's no opportunity for failure.

So it's an embarrassing bug, but not catastrophic.

> 
> Thanks,
> 
>                  Linus

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

* [patch V2 1/3] x86/ldt: Plug memory leak in error path
  2017-12-30 21:13 ` [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path Thomas Gleixner
  2017-12-30 21:33   ` Ingo Molnar
@ 2017-12-31 10:24   ` Thomas Gleixner
  2017-12-31 15:23     ` Andy Lutomirski
  1 sibling, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2017-12-31 10:24 UTC (permalink / raw)
  To: LKML
  Cc: Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski,
	Mathieu Desnoyers

The error path in write_ldt() tries to free old_ldt instead of the newly
allocated new_ldt resulting in a memory leak. It also misses to clean up a
half populated LDT pagetable, which is not a leak as it gets cleaned up
when the process exits.

Free both the potentially half populated LDT pagetable and the newly
allocated LDT struct. This can be done unconditionally because once a LDT
is mapped subsequent maps will succeed because the PTE page is already
populated and the two LDTs fit into that single page.

Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/ldt.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -421,7 +421,13 @@ static int write_ldt(void __user *ptr, u
 	 */
 	error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0);
 	if (error) {
-		free_ldt_struct(old_ldt);
+		/*
+		 * This only can fail for the first LDT setup. If a LDT is
+		 * already installed then the PTE page is already
+		 * populated. Mop up a half populated page table.
+		 */
+		free_ldt_pgtables(mm);
+		free_ldt_struct(new_ldt);
 		goto out_unlock;
 	}
 

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

* Re: [patch V2 1/3] x86/ldt: Plug memory leak in error path
  2017-12-31 10:24   ` [patch V2 1/3] x86/ldt: Plug memory leak in " Thomas Gleixner
@ 2017-12-31 15:23     ` Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: Andy Lutomirski @ 2017-12-31 15:23 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Linus Torvalds, x86, Andy Lutomirski, Dave Hansen,
	Peter Zijlstra, Borislav Petkov, Dominik Brodowski,
	Mathieu Desnoyers



> On Dec 31, 2017, at 2:24 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> 
> The error path in write_ldt() tries to free old_ldt instead of the newly
> allocated new_ldt resulting in a memory leak. It also misses to clean up a
> half populated LDT pagetable, which is not a leak as it gets cleaned up
> when the process exits.
> 
> Free both the potentially half populated LDT pagetable and the newly
> allocated LDT struct. This can be done unconditionally because once a LDT
> is mapped subsequent maps will succeed because the PTE page is already
> populated and the two LDTs fit into that single page.
> 
> Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
> Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> arch/x86/kernel/ldt.c |    8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
> 
> --- a/arch/x86/kernel/ldt.c
> +++ b/arch/x86/kernel/ldt.c
> @@ -421,7 +421,13 @@ static int write_ldt(void __user *ptr, u
>     */
>    error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0);
>    if (error) {
> -        free_ldt_struct(old_ldt);
> +        /*
> +         * This only can fail for the first LDT setup. If a LDT is
> +         * already installed then the PTE page is already
> +         * populated. Mop up a half populated page table.
> +         */

I liked it better with the conditional.  If this ever fails due to fault injection, some silly accounting issue, a paravirt glitch, or whatever, then we'll oops.

> +        free_ldt_pgtables(mm);
> +        free_ldt_struct(new_ldt);
>        goto out_unlock;
>    }
> 

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

end of thread, other threads:[~2017-12-31 15:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-30 21:13 [patch 0/3] x86/pti: Fix various fallout Thomas Gleixner
2017-12-30 21:13 ` [patch 1/3] x86/ldt: Free the right LDT memory in write_ldt() error path Thomas Gleixner
2017-12-30 21:33   ` Ingo Molnar
2017-12-31 10:24   ` [patch V2 1/3] x86/ldt: Plug memory leak in " Thomas Gleixner
2017-12-31 15:23     ` Andy Lutomirski
2017-12-30 21:13 ` [patch 2/3] x86/smpboot: Remove stale tlb flush invocations Thomas Gleixner
2017-12-30 21:32   ` Ingo Molnar
2017-12-30 21:13 ` [patch 3/3] x86/mm: Remove preempt_disable/enable() from __native_flush_tlb() Thomas Gleixner
2017-12-30 21:31   ` Ingo Molnar
2017-12-30 21:35 ` [patch 0/3] x86/pti: Fix various fallout Ingo Molnar
2017-12-30 22:06   ` Linus Torvalds
2017-12-31  2:23     ` Andy Lutomirski

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.