Bug 1496094 - Fix determining the correct target path of a reparse point. r=rstrong, a=pascalc
authorMatt Howell <mhowell@mozilla.com>
Fri, 05 Oct 2018 00:18:01 +0000
changeset 492824 32eb76185a118a033a7525161f31290fe062f1e2
parent 492823 dd37ab60c111c34e9160509c75297cc39d6c9e0d
child 492825 a48d5341b695f325fda0319f54613e24d9972c8e
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrstrong, pascalc
bugs1496094
milestone63.0
Bug 1496094 - Fix determining the correct target path of a reparse point. r=rstrong, a=pascalc The two standard reparse data buffer structs (SymbolicLinkReparseBuffer and MountPointReparseBuffer) both contain one UTF-16 array called PathBuffer which contains two paths, the "print name" and the "substitute name", with no separator between them. There are also fields in the struct that provide the offset and the length of both those paths (in bytes). I had originally missed that these were separate paths and that the print name will typically not match the substitute name for file system links. This patch corrects that oversight and uses the offsets to correctly check only the substitute name. Differential Revision: https://phabricator.services.mozilla.com/D7645
toolkit/mozapps/update/common/updatecommon.cpp
--- a/toolkit/mozapps/update/common/updatecommon.cpp
+++ b/toolkit/mozapps/update/common/updatecommon.cpp
@@ -229,26 +229,39 @@ PathContainsInvalidLinks(wchar_t * const
       if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, nullptr, 0, buffer,
                            MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytes, nullptr)) {
         return true;
       }
 
       wchar_t* reparseTarget = nullptr;
       switch (buffer->ReparseTag) {
         case IO_REPARSE_TAG_MOUNT_POINT:
-          reparseTarget = buffer->MountPointReparseBuffer.PathBuffer;
+          reparseTarget = buffer->MountPointReparseBuffer.PathBuffer +
+            (buffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
+          if (buffer->MountPointReparseBuffer.SubstituteNameLength <
+              ARRAYSIZE(L"\\??\\")) {
+            return false;
+          }
           break;
         case IO_REPARSE_TAG_SYMLINK:
-          reparseTarget = buffer->SymbolicLinkReparseBuffer.PathBuffer;
+          reparseTarget = buffer->SymbolicLinkReparseBuffer.PathBuffer +
+            (buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
+          if (buffer->SymbolicLinkReparseBuffer.SubstituteNameLength <
+              ARRAYSIZE(L"\\??\\")) {
+            return false;
+          }
           break;
         default:
           return true;
           break;
       }
 
+      if (!reparseTarget) {
+        return false;
+      }
       if (wcsncmp(reparseTarget, L"\\??\\", ARRAYSIZE(L"\\??\\") - 1) != 0) {
         return true;
       }
     }
 
     nextToken = wcstok_s(nullptr, L"\\", &remainingPath);
     PathAppendW(partialPath, nextToken);
   }