diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2021-02-19 18:15:58 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2021-02-19 18:15:58 +0100 |
commit | 6d898f43fc87a7bf3ab100d75538e381bd86f657 (patch) | |
tree | d1f9191cfc4bd999c43261548cdfbb1b5f595459 | |
parent | 543e39bb129ac77e29e3800a468100a754ad3d2a (diff) | |
download | cygnal-6d898f43fc87a7bf3ab100d75538e381bd86f657.tar.gz cygnal-6d898f43fc87a7bf3ab100d75538e381bd86f657.tar.bz2 cygnal-6d898f43fc87a7bf3ab100d75538e381bd86f657.zip |
Cygwin: realpath: fix cygwin installation dir being access via junction
Consider this case:
- Cygwin installed in C:\cygwin64
- mklink /j D:\cygwin64 C:\cygwin64
- create testcase calling
realpath("/", result);
printf ("%s\n", result);
- start cmd
>C:\cygwin64\bin\bash -lc <path-to-testcase>
/
>D\cygwin64\bin\bash -lc <path-to-testcase>
/cygdrive/c/cygwin64
This scenario circumventing the mount point handling which is automated
in terms of /, depending on the path returned from GetModuleFileNameW
for the Cygwin DLL. When calling D:\cygwin64\bin\bash the dir returned
from GetModuleFileNameW is D:\cygwin64\bin, thus root is D:\cygwin64.
However, junctions are treated as symlinks in Cygwin which explains why
the path gets converted to a cygdrive path.
Fix this by calling GetFinalPathNameByHandleW on the result from
GetModuleFileNameW to get the correct root path, even if accessed via
a junction point.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/cygheap.cc | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 3a32c352d..01b49468e 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -144,6 +144,19 @@ init_cygheap::init_installation_root () api_fatal ("Can't initialize Cygwin installation root dir.\n" "GetModuleFileNameW(%p, %p, %u), %E", cygwin_hmodule, installation_root_buf, PATH_MAX); + + /* We don't care if fetching the final pathname fails, it's non-fatal and + the path returned by GetModuleFileNameW is still valid. */ + HANDLE h; + h = CreateFileW (installation_root_buf, GENERIC_READ, FILE_SHARE_VALID_FLAGS, + &sec_none, OPEN_EXISTING, 0, 0); + if (h != INVALID_HANDLE_VALUE) + { + GetFinalPathNameByHandleW (h, installation_root_buf, PATH_MAX, + FILE_NAME_NORMALIZED); + CloseHandle (h); + } + PWCHAR p = installation_root_buf; if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */ { |