Proposed patch for https://bugs.winehq.org/show_bug.cgi?id=56211
Not sure if that's the right approach, therefore a draft. Could you please give feedback?
From: Fabian Maurer dark.shadow4@web.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56211 --- dlls/ntdll/unix/loader.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 803d8079213..3342c093c36 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1150,6 +1150,15 @@ static NTSTATUS open_builtin_so_file( const char *name, OBJECT_ATTRIBUTES *attr, return status; }
+/* After adjusting unix search path, also keep nt_name in sync */ +static void update_search_nt_name(UNICODE_STRING *search_nt_name, const char *search_name) +{ + WCHAR *nt_name; + if (search_nt_name->Buffer) + free(search_nt_name->Buffer); + unix_to_nt_file_name(search_name, &nt_name); + init_unicode_string(search_nt_name, nt_name); +}
/*********************************************************************** * find_builtin_dll @@ -1164,6 +1173,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T char *ptr = NULL, *file, *ext = NULL; const char *pe_dir = get_pe_dir( search_machine ); OBJECT_ATTRIBUTES attr; + UNICODE_STRING search_nt_name = {0}; NTSTATUS status = STATUS_DLL_NOT_FOUND; BOOL found_image = FALSE; BOOL try_so = (search_machine == current_machine && (!load_machine || load_machine == search_machine)); @@ -1172,7 +1182,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T if (nt_name->Buffer[i] == '/' || nt_name->Buffer[i] == '\') namepos = i + 1; len -= namepos; if (!len) return STATUS_DLL_NOT_FOUND; - InitializeObjectAttributes( &attr, nt_name, 0, 0, NULL ); + InitializeObjectAttributes( &attr, &search_nt_name, 0, 0, NULL );
if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/") + len; maxlen = max( maxlen, dll_path_maxlen + 1 ) + len + sizeof("/aarch64-windows") + sizeof(".so"); @@ -1195,6 +1205,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T /* try as a dll */ file[pos + len + 1] = 0; ptr = prepend_build_dir_path( file + pos, ".dll", pe_dir, "/dlls" ); + update_search_nt_name(&search_nt_name, ptr); status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit_low, limit_high, load_machine, prefer_native ); ptr = prepend_build_dir_path( file + pos, ".dll", "", "/dlls" ); @@ -1209,6 +1220,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T /* now as a program */ file[pos + len + 1] = 0; ptr = prepend_build_dir_path( file + pos, ".exe", pe_dir, "/programs" ); + update_search_nt_name(&search_nt_name, ptr); status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit_low, limit_high, load_machine, prefer_native ); ptr = prepend_build_dir_path( file + pos, ".exe", "", "/programs" ); @@ -1227,6 +1239,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T file[pos + len + 1] = 0; ptr = prepend( ptr, pe_dir, strlen(pe_dir) ); ptr = prepend( ptr, dll_paths[i], strlen(dll_paths[i]) ); + update_search_nt_name(&search_nt_name, ptr); status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit_low, limit_high, load_machine, prefer_native ); /* use so dir for unix lib */ @@ -1242,6 +1255,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T } file[pos + len + 1] = 0; ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) ); + update_search_nt_name(&search_nt_name, ptr); status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit_low, limit_high, load_machine, prefer_native ); if (status == STATUS_NOT_SUPPORTED) @@ -1266,6 +1280,7 @@ done: load_builtin_unixlib( *module, ptr ); } free( file ); + free(search_nt_name.Buffer); return status; }
We don't want to expose the internal path, the app shouldn't be aware that the dll was replaced by a builtin.
On Fri Jan 19 21:42:38 2024 +0000, Alexandre Julliard wrote:
We don't want to expose the internal path, the app shouldn't be aware that the dll was replaced by a builtin.
Why exactly is that? It seems a bit weird that there is that discrepancy between unix and nt path. It also means that Wine itself can't rely on the nt path, which causes issues like the issue with MR 4518 I mentioned. Won't this also cause issues with anti cheat that validate the dll hasn't been tampered with, since the in memory dll is a different one from what the programsees on disk?
On Fri Jan 19 21:42:38 2024 +0000, Fabian Maurer wrote:
Why exactly is that? It seems a bit weird that there is that discrepancy between unix and nt path. It also means that Wine itself can't rely on the nt path, which causes issues like the issue with MR 4518 I mentioned. Won't this also cause issues with anti cheat that validate the dll hasn't been tampered with, since the in memory dll is a different one from what the programsees on disk?
If there's a real anti-cheat that does this, the dll would have to be configured native.
Still, we don't want to expose the internal path. Note that it may not even be a valid dll in case of a non-PE build.