From: Zebediah Figura z.figura12@gmail.com
Normally, when an application with a manifest is run, ntdll will notice and create the new process with an administrator token. However, if the process is launched directly from the loader, this code is never run. By launching all processes via start.exe, we make sure that the process is created through RtlCreateUserProcess() and thus elevated if necessary.
The alternative to this patch would be to elevate the child from within ntdll.so or the server. However, either one would require parsing the manifest there, which would require copying a lot of code. This seems like a simpler approach, with no actual disadvantage. --- dlls/ntdll/unix/env.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index ad9ab0dc220..427c577f2c9 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -1924,6 +1924,7 @@ static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module ) */ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) { + static const char *args[] = { "start.exe", "/exec" }; static const WCHAR valueW[] = {'1',0}; static const WCHAR pathW[] = {'P','A','T','H'}; RTL_USER_PROCESS_PARAMETERS *params = NULL; @@ -1952,29 +1953,8 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) add_registry_environment( &env, &env_pos, &env_size ); env[env_pos++] = 0;
- status = load_main_exe( NULL, main_argv[1], curdir, 0, &image, module ); - if (!status) - { - char *loader; - - if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; - /* if we have to use a different loader, fall back to start.exe */ - if ((loader = get_alternate_wineloader( main_image_info.Machine ))) - { - free( loader ); - status = STATUS_INVALID_IMAGE_FORMAT; - } - } - - if (status) /* try launching it through start.exe */ - { - static const char *args[] = { "start.exe", "/exec" }; - free( image ); - if (*module) NtUnmapViewOfSection( GetCurrentProcess(), *module ); - load_start_exe( &image, module ); - prepend_argv( args, 2 ); - } - else rebuild_argv(); + load_start_exe( &image, module ); + prepend_argv( args, 2 );
main_wargv = build_wargv( get_dos_path( image )); cmdline = build_command_line( main_wargv );