diff options
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/globals.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 30 |
3 files changed, 36 insertions, 2 deletions
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index f153c73..3bbee4d 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -730,6 +730,12 @@ init_windows_system_directory () system_wow64_directory[system_wow64_directory_length++] = L'\\'; system_wow64_directory[system_wow64_directory_length] = L'\0'; } + /* We need the Windows dir in path.cc. */ + wcscpy (windows_directory, windows_system_directory); + windows_directory_length = windows_system_directory_length - 1; + windows_directory[windows_directory_length] = L'\0'; + while (windows_directory[windows_directory_length - 1] != L'\\') + windows_directory[--windows_directory_length] = L'\0'; #endif /* __i386__ */ } } diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 942bd1c..0b9559e 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -26,6 +26,8 @@ UINT windows_system_directory_length; #ifdef __i386__ WCHAR system_wow64_directory[MAX_PATH]; UINT system_wow64_directory_length; +WCHAR windows_directory[MAX_PATH]; +UINT windows_directory_length; #endif /* __i386__ */ WCHAR global_progname[NT_MAX_PATH]; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 2248b56..93068a4 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -3187,9 +3187,31 @@ restart: forces path_conv::check to backtrack inner path components. */ if (!fs.is_remote_drive ()) { - PFILE_NAME_INFORMATION pfni = (PFILE_NAME_INFORMATION) - tp.c_get (); +#ifdef __i386__ + /* On WOW64, ignore any potential problems if the path is inside + the Windows dir to avoid false positives for stuff under + File System Redirector control. */ + if (wincap.is_wow64 ()) + { + static UNICODE_STRING wpath; + UNICODE_STRING udpath; + + /* Create UNICODE_STRING for Windows dir. */ + RtlInitCountedUnicodeString (&wpath, windows_directory, + windows_directory_length * sizeof (WCHAR)); + /* Create a UNICODE_STRING from incoming path, splitting + off the leading "\\??\\" */ + RtlInitCountedUnicodeString (&udpath, upath.Buffer + 4, + upath.Length - 4 * sizeof (WCHAR)); + /* Are we below Windows dir? Skip the check for inner + symlinks. */ + if (RtlEqualUnicodePathPrefix (&udpath, &wpath, TRUE)) + goto skip_inner_syml_check; + } +#endif /* __i386__ */ + PFILE_NAME_INFORMATION pfni; + pfni = (PFILE_NAME_INFORMATION) tp.c_get (); if (NT_SUCCESS (NtQueryInformationFile (h, &io, pfni, NT_MAX_PATH, FileNameInformation))) { @@ -3204,6 +3226,10 @@ restart: break; } } +#ifdef __i386__ + skip_inner_syml_check: + ; +#endif /* __i386__ */ } } if (!NT_SUCCESS (status)) |