|
|
eb7fe6 |
From 06ffc9beb27a82dea25bb4cd3825ea3b57df5df5 Mon Sep 17 00:00:00 2001
|
|
|
eb7fe6 |
From: Laszlo Ersek <lersek@redhat.com>
|
|
|
eb7fe6 |
Date: Wed, 26 Apr 2017 14:20:30 +0200
|
|
|
eb7fe6 |
Subject: [PATCH 1/2] ShellPkg/Shell: clean up bogus member types in SPLIT_LIST
|
|
|
eb7fe6 |
MIME-Version: 1.0
|
|
|
eb7fe6 |
Content-Type: text/plain; charset=UTF-8
|
|
|
eb7fe6 |
Content-Transfer-Encoding: 8bit
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
Message-id: <20170426122031.12047-2-lersek@redhat.com>
|
|
|
eb7fe6 |
Patchwork-id: 74883
|
|
|
eb7fe6 |
O-Subject: [RHEL-7.4 ovmf PATCH 1/2] ShellPkg/Shell: clean up bogus member types
|
|
|
eb7fe6 |
in SPLIT_LIST
|
|
|
eb7fe6 |
Bugzilla: 1442908
|
|
|
eb7fe6 |
Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
eb7fe6 |
Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
|
|
eb7fe6 |
Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
The "SPLIT_LIST.SplitStdOut" and "SPLIT_LIST.SplitStdIn" members currently
|
|
|
eb7fe6 |
have type (SHELL_FILE_HANDLE *). This is wrong; SHELL_FILE_HANDLE is
|
|
|
eb7fe6 |
already a pointer, there's no need to store a pointer to a pointer.
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
The error is obvious if we check where and how these members are used:
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
- In the RunSplitCommand() function, these members are used (populated)
|
|
|
eb7fe6 |
extensively; this function has to be updated in sync.
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
ConvertEfiFileProtocolToShellHandle() already returns the temporary
|
|
|
eb7fe6 |
memory file created with CreateFileInterfaceMem() as SHELL_FILE_HANDLE,
|
|
|
eb7fe6 |
not as (SHELL_FILE_HANDLE *).
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
- In particular, the ConvertShellHandleToEfiFileProtocol() calls need to
|
|
|
eb7fe6 |
be dropped as well in RunSplitCommand(), since
|
|
|
eb7fe6 |
EFI_SHELL_PROTOCOL.SetFilePosition() and EFI_SHELL_PROTOCOL.CloseFile()
|
|
|
eb7fe6 |
take SHELL_FILE_HANDLE parameters, not (EFI_FILE_PROTOCOL *).
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
Given that ConvertShellHandleToEfiFileProtocol() only performs a
|
|
|
eb7fe6 |
type-cast (it does not adjust any pointer values), *and*
|
|
|
eb7fe6 |
SHELL_FILE_HANDLE -- taken by EFI_SHELL_PROTOCOL member functions -- is
|
|
|
eb7fe6 |
actually a typedef to (VOID *) -- see more on this later --, this
|
|
|
eb7fe6 |
conversion error hasn't been caught by compilers.
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
- In the ProcessNewSplitCommandLine() function, RunSplitCommand() is
|
|
|
eb7fe6 |
called either initially (passing in NULL / NULL; no update needed), or
|
|
|
eb7fe6 |
recursively (passing in Split->SplitStdIn / Split->SplitStdOut; again no
|
|
|
eb7fe6 |
update is necessary beyond the RunSplitCommand() modification above).
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
- In the UpdateStdInStdOutStdErr() and RestoreStdInStdOutStdErr()
|
|
|
eb7fe6 |
functions, said structure members are compared and assigned to
|
|
|
eb7fe6 |
"EFI_SHELL_PARAMETERS_PROTOCOL.StdIn" and
|
|
|
eb7fe6 |
"EFI_SHELL_PARAMETERS_PROTOCOL.StdOut", both of which have type
|
|
|
eb7fe6 |
SHELL_FILE_HANDLE, *not* (SHELL_FILE_HANDLE *).
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
The compiler hasn't caught this error because of the fatally flawed type
|
|
|
eb7fe6 |
definition of SHELL_FILE_HANDLE, namely
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
typedef VOID *SHELL_FILE_HANDLE;
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
Pointer-to-void silently converts to and from most other pointer types;
|
|
|
eb7fe6 |
among them, pointer-to-pointer-to-void. That is also why no update is
|
|
|
eb7fe6 |
necessary for UpdateStdInStdOutStdErr() and RestoreStdInStdOutStdErr()
|
|
|
eb7fe6 |
in this fix.
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
(
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
Generally speaking, using (VOID *) typedefs for opaque handles is a tragic
|
|
|
eb7fe6 |
mistake in all of the UEFI-related specifications; this practice defeats
|
|
|
eb7fe6 |
any type checking that compilers might help programmers with. The right
|
|
|
eb7fe6 |
way to define an opaque handle is as follows:
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
// Introduce the incomplete structure type, and the derived pointer
|
|
|
eb7fe6 |
// type, in both the specification and the public edk2 headers. Note
|
|
|
eb7fe6 |
// that the derived pointer type itself is a complete type, and it can
|
|
|
eb7fe6 |
// be used freely by client code.
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
typedef struct SHELL_FILE *SHELL_FILE_HANDLE;
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
// Complete the structure type in the edk2 internal C source files.
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
struct SHELL_FILE {
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
// list fields
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
};
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
This way the structure size and members remain hidden from client code,
|
|
|
eb7fe6 |
but the C compiler can nonetheless catch any invalid conversions between
|
|
|
eb7fe6 |
incompatible XXX_HANDLE types.
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
)
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
Cc: Jaben Carsey <jaben.carsey@intel.com>
|
|
|
eb7fe6 |
Cc: Marvin Häuser <Marvin.Haeuser@outlook.com>
|
|
|
eb7fe6 |
Cc: Qiu Shumin <shumin.qiu@intel.com>
|
|
|
eb7fe6 |
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
|
|
|
eb7fe6 |
Contributed-under: TianoCore Contribution Agreement 1.0
|
|
|
eb7fe6 |
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
eb7fe6 |
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
|
|
|
eb7fe6 |
(cherry picked from commit 1bd0bf153ebf4993421afd5084c52a6e57e17fdc)
|
|
|
eb7fe6 |
---
|
|
|
eb7fe6 |
ShellPkg/Application/Shell/Shell.c | 12 ++++++------
|
|
|
eb7fe6 |
ShellPkg/Application/Shell/Shell.h | 4 ++--
|
|
|
eb7fe6 |
2 files changed, 8 insertions(+), 8 deletions(-)
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
|
|
|
eb7fe6 |
index 731ba18..816dd1a 100644
|
|
|
eb7fe6 |
--- a/ShellPkg/Application/Shell/Shell.c
|
|
|
eb7fe6 |
+++ b/ShellPkg/Application/Shell/Shell.c
|
|
|
eb7fe6 |
@@ -1705,8 +1705,8 @@ ShellConvertVariables (
|
|
|
eb7fe6 |
EFI_STATUS
|
|
|
eb7fe6 |
RunSplitCommand(
|
|
|
eb7fe6 |
IN CONST CHAR16 *CmdLine,
|
|
|
eb7fe6 |
- IN SHELL_FILE_HANDLE *StdIn,
|
|
|
eb7fe6 |
- IN SHELL_FILE_HANDLE *StdOut
|
|
|
eb7fe6 |
+ IN SHELL_FILE_HANDLE StdIn,
|
|
|
eb7fe6 |
+ IN SHELL_FILE_HANDLE StdOut
|
|
|
eb7fe6 |
)
|
|
|
eb7fe6 |
{
|
|
|
eb7fe6 |
EFI_STATUS Status;
|
|
|
eb7fe6 |
@@ -1715,7 +1715,7 @@ RunSplitCommand(
|
|
|
eb7fe6 |
UINTN Size1;
|
|
|
eb7fe6 |
UINTN Size2;
|
|
|
eb7fe6 |
SPLIT_LIST *Split;
|
|
|
eb7fe6 |
- SHELL_FILE_HANDLE *TempFileHandle;
|
|
|
eb7fe6 |
+ SHELL_FILE_HANDLE TempFileHandle;
|
|
|
eb7fe6 |
BOOLEAN Unicode;
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
ASSERT(StdOut == NULL);
|
|
|
eb7fe6 |
@@ -1781,7 +1781,7 @@ RunSplitCommand(
|
|
|
eb7fe6 |
Split->SplitStdOut = Split->SplitStdIn;
|
|
|
eb7fe6 |
}
|
|
|
eb7fe6 |
Split->SplitStdIn = TempFileHandle;
|
|
|
eb7fe6 |
- ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
|
|
|
eb7fe6 |
+ ShellInfoObject.NewEfiShellProtocol->SetFilePosition (Split->SplitStdIn, 0);
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
if (!EFI_ERROR(Status)) {
|
|
|
eb7fe6 |
Status = RunCommand(NextCommandLine);
|
|
|
eb7fe6 |
@@ -1797,10 +1797,10 @@ RunSplitCommand(
|
|
|
eb7fe6 |
// Note that the original StdIn is now the StdOut...
|
|
|
eb7fe6 |
//
|
|
|
eb7fe6 |
if (Split->SplitStdOut != NULL) {
|
|
|
eb7fe6 |
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));
|
|
|
eb7fe6 |
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);
|
|
|
eb7fe6 |
}
|
|
|
eb7fe6 |
if (Split->SplitStdIn != NULL) {
|
|
|
eb7fe6 |
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));
|
|
|
eb7fe6 |
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);
|
|
|
eb7fe6 |
FreePool (Split->SplitStdIn);
|
|
|
eb7fe6 |
}
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
diff --git a/ShellPkg/Application/Shell/Shell.h b/ShellPkg/Application/Shell/Shell.h
|
|
|
eb7fe6 |
index 25ac114..ff08494 100644
|
|
|
eb7fe6 |
--- a/ShellPkg/Application/Shell/Shell.h
|
|
|
eb7fe6 |
+++ b/ShellPkg/Application/Shell/Shell.h
|
|
|
eb7fe6 |
@@ -63,8 +63,8 @@ extern CONST CHAR16 mNoNestingFalse[];
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
typedef struct {
|
|
|
eb7fe6 |
LIST_ENTRY Link; ///< Standard linked list handler.
|
|
|
eb7fe6 |
- SHELL_FILE_HANDLE *SplitStdOut; ///< ConsoleOut for use in the split.
|
|
|
eb7fe6 |
- SHELL_FILE_HANDLE *SplitStdIn; ///< ConsoleIn for use in the split.
|
|
|
eb7fe6 |
+ SHELL_FILE_HANDLE SplitStdOut; ///< ConsoleOut for use in the split.
|
|
|
eb7fe6 |
+ SHELL_FILE_HANDLE SplitStdIn; ///< ConsoleIn for use in the split.
|
|
|
eb7fe6 |
} SPLIT_LIST;
|
|
|
eb7fe6 |
|
|
|
eb7fe6 |
typedef struct {
|
|
|
eb7fe6 |
--
|
|
|
eb7fe6 |
1.8.3.1
|
|
|
eb7fe6 |
|