]> granicus.if.org Git - php/commitdiff
Fix #80258: Windows Deduplication Enabled, randon permission errors
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 19 Oct 2020 15:41:58 +0000 (17:41 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Mon, 26 Oct 2020 10:21:14 +0000 (11:21 +0100)
A recent bug fix regarding symlinks claimed:

> After resolving reparse points, the path still may be a reparse
> point; in that case we have to resolve that reparse point as well.

While that is basically correct, some reparse points may point to
inaccessible system folders (e.g. `IO_REPARSE_TAG_DEDUP` points to
"\System Volume Information").  Since we don't know details about
arbitrary reparse points, and are mainly interested in nested symlinks,
we take a step back, and only resolve `IO_REPARSE_TAG_SYMLINK` for now.

Close GH-6354.

NEWS
Zend/zend_virtual_cwd.c

diff --git a/NEWS b/NEWS
index a818b50641e1f8a28f8f83c85c35fe9fd9c6335a..1b5f8ee8dd8e0f455526185660cef68b67cb77af 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP                                                                        NEWS
 - Core:
   . Fixed bug #80280 (ADD_EXTENSION_DEP() fails for ext/standard and ext/date).
     (cmb)
+  . Fixed bug #80258 (Windows Deduplication Enabled, randon permission errors).
+    (cmb)
 
 - IMAP:
   . Fixed bug #64076 (imap_sort() does not return FALSE on failure). (cmb)
index 7c5ac825c55c8420071f9729b1316e201d61a72c..b74313d3a576cb8747b248d97ecc213cb9713af5 100644 (file)
@@ -741,7 +741,7 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void)
 static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, time_t *t, int use_realpath, int is_dir, int *link_is_dir) /* {{{ */
 {
        size_t i, j;
-       int directory = 0, save;
+       int directory = 0, save, may_retry_reparse_point;
 #ifdef ZEND_WIN32
        WIN32_FIND_DATAW dataw;
        HANDLE hFind = INVALID_HANDLE_VALUE;
@@ -846,6 +846,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
 
 #ifdef ZEND_WIN32
 retry_reparse_point:
+               may_retry_reparse_point = 0;
                if (save) {
                        pathw = php_win32_ioutil_any_to_w(path);
                        if (!pathw) {
@@ -940,6 +941,7 @@ retry_reparse_tag_cloud:
                        CloseHandle(hLink);
 
                        if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
+                               may_retry_reparse_point = 1;
                                reparsetarget = pbuffer->SymbolicLinkReparseBuffer.ReparseTarget;
                                isabsolute = (pbuffer->SymbolicLinkReparseBuffer.Flags == 0) ? 1 : 0;
 #if VIRTUAL_CWD_DEBUG
@@ -1076,7 +1078,7 @@ retry_reparse_tag_cloud:
                        free_alloca(pbuffer, use_heap_large);
                        free(substitutename);
 
-                       {
+                       if (may_retry_reparse_point) {
                                DWORD attrs;
 
                                FREE_PATHW()