From 542689ac8f56eb2ba4aab4bf90d9ca4524ef3cd2 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 26 Apr 2017 14:20:31 +0200
Subject: [PATCH 2/2] ShellPkg/Shell: eliminate double-free in
RunSplitCommand()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Message-id: <20170426122031.12047-3-lersek@redhat.com>
Patchwork-id: 74884
O-Subject: [RHEL-7.4 ovmf PATCH 2/2] ShellPkg/Shell: eliminate double-free in
RunSplitCommand()
Bugzilla: 1442908
Acked-by: Thomas Huth <thuth@redhat.com>
Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
Commit bd3fc8133b2b ("ShellPkg/App: Fix memory leak and save resources.",
2016-05-20) added a FreePool() call for Split->SplitStdIn, near end of the
RunSplitCommand(), right after the same shell file was closed with
CloseFile(). The argument was:
> 1) RunSplitCommand() allocates the initial SplitStdOut via
> CreateFileInterfaceMem(). Free SplitStdIn after the swap to fix
> the memory leak.
There is no memory leak actually, and the FreePool() call in question
constitutes a double-free:
(a) This is how the handle is established:
ConvertEfiFileProtocolToShellHandle (
CreateFileInterfaceMem (Unicode),
NULL
);
CreateFileInterfaceMem() allocates an EFI_FILE_PROTOCOL_MEM object and
populates it fully. ConvertEfiFileProtocolToShellHandle() allocates
some administrative structures and links the EFI_FILE_PROTOCOL_MEM
object into "mFileHandleList".
(b) EFI_SHELL_PROTOCOL.CloseFile() is required to close the
SHELL_FILE_HANDLE and to release all associated data. Accordingly,
near the end of RunSplitCommand(), we have:
EfiShellClose()
ShellFileHandleRemove()
//
// undoes the effects of ConvertEfiFileProtocolToShellHandle()
//
ConvertShellHandleToEfiFileProtocol()
//
// note that this does not adjust the pointer value; it's a pure
// type cast
//
FileHandleClose()
FileInterfaceMemClose()
//
// tears down EFI_FILE_PROTOCOL_MEM completely, undoing the
// effects of CreateFileInterfaceMem ()
//
The FreePool() call added by bd3fc8133b2b conflicts with
SHELL_FREE_NON_NULL(This);
in FileInterfaceMemClose(), so remove it.
This error can be reproduced for example with:
> Shell> map | more
> 'more' is not recognized as an internal or external command, operable
> program, or script file.
which triggers:
> ASSERT MdeModulePkg/Core/Dxe/Mem/Pool.c(624): CR has Bad Signature
with the following stack dump:
> #0 0x000000007f6dc094 in CpuDeadLoop () at
> MdePkg/Library/BaseLib/CpuDeadLoop.c:37
> #1 0x000000007f6dd1b4 in DebugAssert (FileName=0x7f6ed9f0
> "MdeModulePkg/Core/Dxe/Mem/Pool.c", LineNumber=624,
> Description=0x7f6ed9d8 "CR has Bad Signature") at
> OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c:153
> #2 0x000000007f6d075d in CoreFreePoolI (Buffer=0x7e232c98,
> PoolType=0x7f6bc1c4) at MdeModulePkg/Core/Dxe/Mem/Pool.c:624
> #3 0x000000007f6d060e in CoreInternalFreePool (Buffer=0x7e232c98,
> PoolType=0x7f6bc1c4) at MdeModulePkg/Core/Dxe/Mem/Pool.c:529
> #4 0x000000007f6d0648 in CoreFreePool (Buffer=0x7e232c98) at
> MdeModulePkg/Core/Dxe/Mem/Pool.c:552
> #5 0x000000007d49fbf8 in FreePool (Buffer=0x7e232c98) at
> MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c:818
> #6 0x000000007d4875c3 in RunSplitCommand (CmdLine=0x7d898398,
> StdIn=0x0, StdOut=0x0) at ShellPkg/Application/Shell/Shell.c:1813
> #7 0x000000007d487d59 in ProcessNewSplitCommandLine
> (CmdLine=0x7d898398) at ShellPkg/Application/Shell/Shell.c:2121
> #8 0x000000007d488937 in RunShellCommand (CmdLine=0x7e233018,
> CommandStatus=0x0) at ShellPkg/Application/Shell/Shell.c:2670
> #9 0x000000007d488b0b in RunCommand (CmdLine=0x7e233018) at
> ShellPkg/Application/Shell/Shell.c:2732
> #10 0x000000007d4867c8 in DoShellPrompt () at
> ShellPkg/Application/Shell/Shell.c:1349
> #11 0x000000007d48524d in UefiMain (ImageHandle=0x7e24c898,
> SystemTable=0x7f5b6018) at ShellPkg/Application/Shell/Shell.c:631
Cc: Jaben Carsey <jaben.carsey@intel.com>
Cc: Marvin Häuser <Marvin.Haeuser@outlook.com>
Cc: Qiu Shumin <shumin.qiu@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Fixes: bd3fc8133b2b17ad2e0427d1bf6b44b08cf2f3b2
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Marvin Häuser <Marvin.Haeuser@outlook.com>
(cherry picked from commit 227fe49d5d4fe6513fc09766f1c9f3ff330ea845)
---
ShellPkg/Application/Shell/Shell.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index 816dd1a..7684e22 100644
--- a/ShellPkg/Application/Shell/Shell.c
+++ b/ShellPkg/Application/Shell/Shell.c
@@ -1801,7 +1801,6 @@ RunSplitCommand(
}
if (Split->SplitStdIn != NULL) {
ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);
- FreePool (Split->SplitStdIn);
}
FreePool(Split);
--
1.8.3.1