| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- From f7b3a0038fd5bdc21d05f09002e16db3ea8e6e3b Mon Sep 17 00:00:00 2001
- From: Thomas Gleixner <[email protected]>
- Date: Sun, 31 Dec 2017 11:24:34 +0100
- Subject: [PATCH 221/242] x86/ldt: Plug memory leak in error path
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- CVE-2017-5754
- 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 an LDT
- is mapped subsequent maps will succeed, because the PTE page is already
- populated and the two LDTs fit into that single page.
- Reported-by: Mathieu Desnoyers <[email protected]>
- Signed-off-by: Thomas Gleixner <[email protected]>
- Cc: Andy Lutomirski <[email protected]>
- Cc: Borislav Petkov <[email protected]>
- Cc: Dave Hansen <[email protected]>
- Cc: Dominik Brodowski <[email protected]>
- Cc: Linus Torvalds <[email protected]>
- Cc: Linus Torvalds <[email protected]>
- Cc: Peter Zijlstra <[email protected]>
- Fixes: f55f0501cbf6 ("x86/pti: Put the LDT in its own PGD if PTI is on")
- Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1712311121340.1899@nanos
- Signed-off-by: Ingo Molnar <[email protected]>
- (cherry picked from commit a62d69857aab4caa43049e72fe0ed5c4a60518dd)
- Signed-off-by: Andy Whitcroft <[email protected]>
- Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
- (cherry picked from commit 03d02494f6253d0bdca7254d85e50786448c14f9)
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- arch/x86/kernel/ldt.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
- diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
- index 2260eb6e2de7..9a35b7e541bc 100644
- --- a/arch/x86/kernel/ldt.c
- +++ b/arch/x86/kernel/ldt.c
- @@ -420,7 +420,13 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
- */
- 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 an 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;
- }
-
- --
- 2.14.2
|