From 482a26e13503a9779107d6e7f1bf9229b6cecea4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 26 Mar 2021 11:34:36 +0100 Subject: [PATCH] ntdll: Use the same builtin check for process creation and initial image loading. Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/loader.c | 47 +++++++++++++++++++++++++++++----- dlls/ntdll/unix/process.c | 39 ++-------------------------- dlls/ntdll/unix/unix_private.h | 1 + 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 2467b640a79..f89ec12dc7e 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1452,6 +1452,42 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename, } +/*************************************************************************** + * is_builtin_path + */ +BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) +{ + static const WCHAR wow64W[] = {'\\','?','?','\\','c',':','\\','w','i','n','d','o','w','s','\\', + 's','y','s','w','o','w','6','4'}; + unsigned int len; + + *machine = current_machine; + if (path->Length > wcslen(system_dir) * sizeof(WCHAR) && + !wcsnicmp( path->Buffer, system_dir, wcslen(system_dir) )) + { +#ifndef _WIN64 + if (NtCurrentTeb64() && NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR]) + *machine = IMAGE_FILE_MACHINE_AMD64; +#endif + goto found; + } + if ((is_win64 || is_wow64) && path->Length > sizeof(wow64W) && + !wcsnicmp( path->Buffer, wow64W, ARRAY_SIZE(wow64W) )) + { + *machine = IMAGE_FILE_MACHINE_I386; + goto found; + } + return FALSE; + +found: + /* check that there are no other path components */ + len = wcslen(system_dir); + while (len < path->Length / sizeof(WCHAR) && path->Buffer[len] == '\\') len++; + while (len < path->Length / sizeof(WCHAR) && path->Buffer[len] != '\\') len++; + return len == path->Length / sizeof(WCHAR); +} + + /*********************************************************************** * open_main_image */ @@ -1507,7 +1543,7 @@ NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *c NTSTATUS status; SIZE_T size; struct stat st; - const WCHAR *p; + WORD machine; /* special case for Unix file name */ if (unix_name && unix_name[0] == '/' && !stat( unix_name, &st )) @@ -1523,13 +1559,10 @@ NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *c if (status != STATUS_DLL_NOT_FOUND) return status; /* if path is in system dir, we can load the builtin even if the file itself doesn't exist */ - if (!wcsnicmp( *image, system_dir, wcslen(system_dir) )) + init_unicode_string( &nt_name, *image ); + if (is_builtin_path( &nt_name, &machine )) { - p = *image + wcslen( system_dir ); - while (*p == '\\') p++; - if (wcschr( p, '\\' )) goto failed; - init_unicode_string( &nt_name, *image ); - status = find_builtin_dll( &nt_name, module, &size, image_info, current_machine, FALSE ); + status = find_builtin_dll( &nt_name, module, &size, image_info, machine, FALSE ); if (status != STATUS_DLL_NOT_FOUND) return status; } /* if name contains a path, bail out */ diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index d2fd08e155f..1a92235de20 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -226,33 +226,6 @@ static startup_info_t *create_startup_info( const RTL_USER_PROCESS_PARAMETERS *p } -/*************************************************************************** - * is_builtin_path - */ -static BOOL is_builtin_path( UNICODE_STRING *path, BOOL *is_64bit ) -{ - static const WCHAR wow64W[] = {'\\','?','?','\\','c',':','\\','w','i','n','d','o','w','s','\\', - 's','y','s','w','o','w','6','4'}; - - *is_64bit = is_win64; - if (path->Length > wcslen(system_dir) * sizeof(WCHAR) && - !wcsnicmp( path->Buffer, system_dir, wcslen(system_dir) )) - { -#ifndef _WIN64 - if (NtCurrentTeb64() && NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR]) *is_64bit = TRUE; -#endif - return TRUE; - } - if ((is_win64 || is_wow64) && path->Length > sizeof(wow64W) && - !wcsnicmp( path->Buffer, wow64W, ARRAY_SIZE(wow64W) )) - { - *is_64bit = FALSE; - return TRUE; - } - return FALSE; -} - - /*********************************************************************** * get_so_file_info */ @@ -373,17 +346,9 @@ static NTSTATUS get_pe_file_info( UNICODE_STRING *path, HANDLE *handle, pe_image if ((status = NtOpenFile( handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT ))) { - BOOL is_64bit; - - if (is_builtin_path( path, &is_64bit )) + if (is_builtin_path( path, &info->machine )) { - TRACE( "assuming %u-bit builtin for %s\n", is_64bit ? 64 : 32, debugstr_us(path)); - /* assume current arch */ -#if defined(__i386__) || defined(__x86_64__) - info->machine = is_64bit ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386; -#else - info->machine = current_machine; -#endif + TRACE( "assuming %04x builtin for %s\n", info->machine, debugstr_us(path)); return STATUS_SUCCESS; } return status; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 3f84fa9c065..904667399f2 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -143,6 +143,7 @@ extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN; extern NTSTATUS exec_wineloader( char **argv, int socketfd, const pe_image_info_t *pe_info ) DECLSPEC_HIDDEN; extern NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename, void **addr_ptr, SIZE_T *size_ptr ) DECLSPEC_HIDDEN; +extern BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) DECLSPEC_HIDDEN; extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *curdir, WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) DECLSPEC_HIDDEN; extern NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) DECLSPEC_HIDDEN;