Added patch to check architecture before trying to load libraries.

This commit is contained in:
Sebastian Lackner 2015-07-18 09:27:37 +02:00
parent a37730ab0e
commit 5f7b6bf45f
7 changed files with 259 additions and 23 deletions

View File

@ -39,8 +39,9 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
-----------------------------------
**Bug fixes and features included in the next upcoming release [1]:**
**Bug fixes and features included in the next upcoming release [2]:**
* Check architecture before trying to load libraries ([Wine Bug #38021](https://bugs.winehq.org/show_bug.cgi?id=38021))
* Forward exitcode from child process when in wineconsole

1
debian/changelog vendored
View File

@ -1,5 +1,6 @@
wine-staging (1.7.48) UNRELEASED; urgency=low
* Added patch to forward exitcode from child process when in wineconsole.
* Added patch to check architecture before trying to load libraries.
* Removed patch to allow to enable/disable InsertMode in wineconsole settings
(accepted upstream).
* Removed patch to improve IoGetDeviceObjectPointer stub to appease SecuROM

View File

@ -1,4 +1,4 @@
From ea4f613ec5b7e4cdc5cb9d850f66c194af9eb5e6 Mon Sep 17 00:00:00 2001
From a76e0d5f4e8211975ede9f1bf65522a31114112a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 13 Dec 2014 05:34:48 +0100
Subject: ntdll: Implement loader redirection scheme.
@ -8,10 +8,10 @@ Subject: ntdll: Implement loader redirection scheme.
1 file changed, 44 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index e1444d2..c392f72 100644
index 0486517..7877f04 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -87,6 +87,7 @@ struct builtin_load_info
@@ -85,6 +85,7 @@ struct builtin_load_info
{
const WCHAR *load_path;
const WCHAR *filename;
@ -19,7 +19,7 @@ index e1444d2..c392f72 100644
NTSTATUS status;
WINE_MODREF *wm;
};
@@ -112,7 +113,8 @@ static WINE_MODREF *cached_modref;
@@ -110,7 +111,8 @@ static WINE_MODREF *cached_modref;
static WINE_MODREF *current_modref;
static WINE_MODREF *last_failed_modref;
@ -29,7 +29,7 @@ index e1444d2..c392f72 100644
static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved );
static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
@@ -438,7 +440,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
@@ -436,7 +438,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
if (!(wm = find_basename_module( mod_name )))
{
TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
@ -38,7 +38,7 @@ index e1444d2..c392f72 100644
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
if (process_attach( wm, NULL ) != STATUS_SUCCESS)
@@ -587,7 +589,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
@@ -585,7 +587,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
{
ascii_to_unicode( buffer, name, len );
buffer[len] = 0;
@ -47,7 +47,7 @@ index e1444d2..c392f72 100644
}
else /* need to allocate a larger buffer */
{
@@ -595,7 +597,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
@@ -593,7 +595,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
if (!ptr) return NULL;
ascii_to_unicode( ptr, name, len );
ptr[len] = 0;
@ -56,7 +56,7 @@ index e1444d2..c392f72 100644
RtlFreeHeap( GetProcessHeap(), 0, ptr );
}
@@ -906,7 +908,7 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
@@ -909,7 +911,7 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
* Allocate a WINE_MODREF structure and add it to the process list
* The loader_section must be locked while calling this function.
*/
@ -65,7 +65,7 @@ index e1444d2..c392f72 100644
{
WINE_MODREF *wm;
const WCHAR *p;
@@ -929,7 +931,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
@@ -932,7 +934,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
wm->ldr.TimeDateStamp = 0;
wm->ldr.ActivationContext = 0;
@ -74,7 +74,7 @@ index e1444d2..c392f72 100644
if ((p = strrchrW( wm->ldr.FullDllName.Buffer, '\\' ))) p++;
else p = wm->ldr.FullDllName.Buffer;
RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
@@ -1546,7 +1548,7 @@ static void load_builtin_callback( void *module, const char *filename )
@@ -1549,7 +1551,7 @@ static void load_builtin_callback( void *module, const char *filename )
return;
}
@ -83,7 +83,7 @@ index e1444d2..c392f72 100644
RtlFreeHeap( GetProcessHeap(), 0, fullname );
if (!wm)
{
@@ -1602,8 +1604,8 @@ static void load_builtin_callback( void *module, const char *filename )
@@ -1605,8 +1607,8 @@ static void load_builtin_callback( void *module, const char *filename )
/******************************************************************************
* load_native_dll (internal)
*/
@ -94,7 +94,7 @@ index e1444d2..c392f72 100644
{
void *module;
HANDLE mapping;
@@ -1627,7 +1629,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
@@ -1630,7 +1632,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
/* create the MODREF */
@ -103,7 +103,7 @@ index e1444d2..c392f72 100644
{
status = STATUS_NO_MEMORY;
goto done;
@@ -1689,8 +1691,8 @@ done:
@@ -1692,8 +1694,8 @@ done:
/***********************************************************************
* load_builtin_dll
*/
@ -114,7 +114,7 @@ index e1444d2..c392f72 100644
{
char error[256], dllname[MAX_PATH];
const WCHAR *name, *p;
@@ -1710,6 +1712,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file,
@@ -1713,6 +1715,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file,
*/
info.load_path = load_path;
info.filename = NULL;
@ -122,7 +122,7 @@ index e1444d2..c392f72 100644
info.status = STATUS_SUCCESS;
info.wm = NULL;
@@ -2028,14 +2031,14 @@ overflow:
@@ -2153,14 +2156,14 @@ overflow:
return STATUS_BUFFER_TOO_SMALL;
}
@ -137,9 +137,9 @@ index e1444d2..c392f72 100644
+static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, LPCWSTR fakemodule,
+ DWORD flags, WINE_MODREF** pwm )
{
BOOL data = flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
enum loadorder loadorder;
WCHAR buffer[32];
@@ -2072,6 +2075,25 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
@@ -2198,6 +2201,25 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
}
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
@ -165,7 +165,7 @@ index e1444d2..c392f72 100644
loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename );
if (handle && is_fake_dll( handle ))
@@ -2094,22 +2116,22 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
@@ -2220,22 +2242,22 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
if (!handle) nts = STATUS_DLL_NOT_FOUND;
else
{
@ -193,7 +193,7 @@ index e1444d2..c392f72 100644
if (nts == STATUS_SUCCESS && loadorder == LO_DEFAULT &&
(MODULE_InitDLL( *pwm, DLL_WINE_PREATTACH, NULL ) != STATUS_SUCCESS))
{
@@ -2119,7 +2141,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
@@ -2245,7 +2267,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
nts = STATUS_DLL_NOT_FOUND;
}
if (nts == STATUS_DLL_NOT_FOUND && loadorder != LO_BUILTIN)
@ -202,7 +202,7 @@ index e1444d2..c392f72 100644
break;
}
@@ -2152,7 +2174,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
@@ -2278,7 +2300,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
RtlEnterCriticalSection( &loader_section );
if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
@ -211,7 +211,7 @@ index e1444d2..c392f72 100644
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
@@ -3115,7 +3137,7 @@ void __wine_process_init(void)
@@ -3241,7 +3263,7 @@ void __wine_process_init(void)
/* setup the load callback and create ntdll modref */
wine_dll_set_callback( load_builtin_callback );
@ -221,5 +221,5 @@ index e1444d2..c392f72 100644
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
exit(1);
--
1.9.1
2.4.5

View File

@ -1,2 +1,3 @@
Fixes: Support for loader dll redirections
Depends: ntdll-Loader_Machine_Type
Category: stable

View File

@ -0,0 +1,206 @@
From a9e0627c59b5ddf2f91d5ceea61a0401afc27ce4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 18 Jul 2015 04:52:55 +0200
Subject: ntdll: Check architecture before loading module.
---
dlls/ntdll/loader.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 131 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index bef0ab1..0486517 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1911,6 +1911,108 @@ done:
return status;
}
+#if defined(__i386__)
+#define CURRENT_ARCH IMAGE_FILE_MACHINE_I386
+#elif defined(__x86_64__)
+#define CURRENT_ARCH IMAGE_FILE_MACHINE_AMD64
+#elif defined(__arm__)
+#define CURRENT_ARCH IMAGE_FILE_MACHINE_ARM
+#elif defined(__aarch64__)
+#define CURRENT_ARCH IMAGE_FILE_MACHINE_ARM64
+#endif
+
+/***********************************************************************
+ * get_machine_type (internal)
+ *
+ * Determines the machine type of a module. Based on the code in
+ * dlls/kernel32/module.c.
+ */
+static WORD get_machine_type( HANDLE hfile )
+{
+ union
+ {
+ struct
+ {
+ unsigned char magic[4];
+ unsigned char class;
+ unsigned char data;
+ unsigned char version;
+ unsigned char ignored[9];
+ unsigned short type;
+ unsigned short machine;
+ } elf;
+ struct
+ {
+ unsigned int magic;
+ unsigned int cputype;
+ unsigned int cpusubtype;
+ unsigned int filetype;
+ } macho;
+ IMAGE_DOS_HEADER mz;
+ } header;
+
+ IO_STATUS_BLOCK io;
+ LARGE_INTEGER offset;
+
+ /* Seek to the start of the file and read the header information. */
+ offset.QuadPart = 0;
+ if (NtReadFile( hfile, 0, NULL, 0, &io, &header, sizeof(header), &offset, NULL )) return 0;
+ if (io.Information < sizeof(header)) return 0;
+
+ if (!memcmp( header.elf.magic, "\177ELF", 4 ))
+ {
+#ifdef WORDS_BIGENDIAN
+ if (header.elf.data == 1)
+#else
+ if (header.elf.data == 2)
+#endif
+ {
+ header.elf.machine = RtlUshortByteSwap( header.elf.machine );
+ }
+
+ switch(header.elf.machine)
+ {
+ case 3: return IMAGE_FILE_MACHINE_I386;
+ case 20: return IMAGE_FILE_MACHINE_POWERPC;
+ case 40: return IMAGE_FILE_MACHINE_ARMNT;
+ case 50: return IMAGE_FILE_MACHINE_IA64;
+ case 62: return IMAGE_FILE_MACHINE_AMD64;
+ case 183: return IMAGE_FILE_MACHINE_ARM64;
+ default: return 0;
+ }
+ }
+ /* Mach-o File with Endian set to Big Endian or Little Endian */
+ else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe ||
+ header.macho.magic == 0xfeedfacf || header.macho.magic == 0xcffaedfe)
+ {
+ if (header.macho.magic == 0xcefaedfe || header.macho.magic == 0xcffaedfe)
+ header.macho.cputype = RtlUlongByteSwap( header.macho.cputype );
+
+ switch(header.macho.cputype)
+ {
+ case 0x00000007: return IMAGE_FILE_MACHINE_I386;
+ case 0x01000007: return IMAGE_FILE_MACHINE_AMD64;
+ case 0x0000000c: return IMAGE_FILE_MACHINE_ARMNT;
+ case 0x0100000c: return IMAGE_FILE_MACHINE_ARM64;
+ case 0x00000012: return IMAGE_FILE_MACHINE_POWERPC;
+ default: return 0;
+ }
+ }
+ /* Not ELF, try DOS */
+ else if (header.mz.e_magic == IMAGE_DOS_SIGNATURE)
+ {
+ IMAGE_NT_HEADERS32 ext_header;
+
+ offset.QuadPart = header.mz.e_lfanew;
+ if (NtReadFile( hfile, 0, NULL, 0, &io, &ext_header, sizeof(ext_header), &offset, NULL )) return 0;
+ if (io.Information < sizeof(ext_header)) return 0;
+
+ if (!memcmp( &ext_header.Signature, "PE\0\0", 4 ))
+ return ext_header.FileHeader.Machine;
+ }
+
+ return 0;
+}
/***********************************************************************
* find_dll_file
@@ -1918,7 +2020,8 @@ done:
* Find the file (or already loaded module) for a given dll name.
*/
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
- WCHAR *filename, ULONG *size, WINE_MODREF **pwm, HANDLE *handle )
+ WCHAR *filename, ULONG *size, WINE_MODREF **pwm, HANDLE *handle,
+ BOOL check_arch)
{
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
@@ -1964,12 +2067,15 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
{
- /* we need to search for it */
- len = RtlDosSearchPath_U( load_path, libname, NULL, *size, filename, &file_part );
- if (len)
+ while (load_path)
{
+ /* we need to search for it */
+ len = RtlDosSearchPath_U( load_path, libname, NULL, *size, filename, &file_part );
+ if (!len) break;
+
if (len >= *size) goto overflow;
- if ((*pwm = find_fullname_module( filename )) || !handle) goto found;
+ if ((*pwm = find_fullname_module( filename ))) goto found;
+ if (!handle) goto next;
if (!RtlDosPathNameToNtPathName_U( filename, &nt_name, NULL, NULL ))
{
@@ -1983,7 +2089,23 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
if (NtOpenFile( handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE )) *handle = 0;
- goto found;
+ #ifdef CURRENT_ARCH
+ if (*handle && check_arch)
+ {
+ WORD machine_type = get_machine_type( *handle );
+ if (machine_type && machine_type != CURRENT_ARCH)
+ {
+ FIXME( "skipping %s because of wrong architecture\n", debugstr_w(filename) );
+ NtClose( *handle );
+ *handle = 0;
+ }
+ }
+ #endif
+ if (*handle) goto found;
+
+ next:
+ load_path = strchrW(load_path, ';');
+ if (load_path) load_path++;
}
/* not found */
@@ -2040,6 +2162,7 @@ overflow:
*/
static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
{
+ BOOL data = flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
enum loadorder loadorder;
WCHAR buffer[32];
WCHAR *filename;
@@ -2055,7 +2178,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
size = sizeof(buffer);
for (;;)
{
- nts = find_dll_file( load_path, libname, filename, &size, pwm, &handle );
+ nts = find_dll_file( load_path, libname, filename, &size, pwm, &handle, !data );
if (nts == STATUS_SUCCESS) break;
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
if (nts != STATUS_BUFFER_TOO_SMALL) return nts;
@@ -2192,7 +2315,7 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
size = sizeof(buffer);
for (;;)
{
- status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, NULL );
+ status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, NULL, TRUE );
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
if (status != STATUS_BUFFER_TOO_SMALL) break;
/* grow the buffer and retry */
--
2.4.5

View File

@ -0,0 +1 @@
Fixes: [38021] Check architecture before trying to load libraries

View File

@ -161,6 +161,7 @@ patch_enable_all ()
enable_ntdll_Heap_FreeLists="$1"
enable_ntdll_Hide_Wine_Exports="$1"
enable_ntdll_Junction_Points="$1"
enable_ntdll_Loader_Machine_Type="$1"
enable_ntdll_NtQueryEaFile="$1"
enable_ntdll_NtQuerySection="$1"
enable_ntdll_NtSetLdtEntries="$1"
@ -549,6 +550,9 @@ patch_enable ()
ntdll-Junction_Points)
enable_ntdll_Junction_Points="$2"
;;
ntdll-Loader_Machine_Type)
enable_ntdll_Loader_Machine_Type="$2"
;;
ntdll-NtQueryEaFile)
enable_ntdll_NtQueryEaFile="$2"
;;
@ -1707,6 +1711,13 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
enable_ntdll_NtQueryEaFile=1
fi
if test "$enable_ntdll_DllRedirects" -eq 1; then
if test "$enable_ntdll_Loader_Machine_Type" -gt 1; then
abort "Patchset ntdll-Loader_Machine_Type disabled, but ntdll-DllRedirects depends on that."
fi
enable_ntdll_Loader_Machine_Type=1
fi
if test "$enable_ntdll_CLI_Images" -eq 1; then
if test "$enable_mscoree_CorValidateImage" -gt 1; then
abort "Patchset mscoree-CorValidateImage disabled, but ntdll-CLI_Images depends on that."
@ -3270,6 +3281,21 @@ if test "$enable_ntdll_DeviceType_Systemroot" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-Loader_Machine_Type
# |
# | This patchset fixes the following Wine bugs:
# | * [#38021] Check architecture before trying to load libraries
# |
# | Modified files:
# | * dlls/ntdll/loader.c
# |
if test "$enable_ntdll_Loader_Machine_Type" -eq 1; then
patch_apply ntdll-Loader_Machine_Type/0001-ntdll-Check-architecture-before-loading-module.patch
(
echo '+ { "Michael Müller", "ntdll: Check architecture before loading module.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-DllRedirects
# |
# | Modified files: