VirtualBox

Changeset 60480 in vbox for trunk


Ignore:
Timestamp:
Apr 13, 2016 8:13:17 PM (9 years ago)
Author:
vboxsync
Message:

SUPNtHard,IPRT: Moved supHardNtVpFix8dot3Path & supHardNtVpIsPossible8dot3Path to IPRT so they more easily can be tested and perhaps used for other stuff.

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/nt/nt.h

    r59366 r60480  
    249249
    250250/**
     251 * Converts a windows-style path to NT format and encoding.
     252 *
     253 * @returns IPRT status code.
     254 * @param   pNtName             Where to return the NT name.  Free using
     255 *                              RTNtPathFree.
     256 * @param   phRootDir           Where to return the root handle, if applicable.
     257 * @param   pszPath             The UTF-8 path.
     258 */
     259RTDECL(int) RTNtPathFromWinUtf8(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir, const char *pszPath);
     260
     261/**
    251262 * Converts a UTF-16 windows-style path to NT format.
    252263 *
     
    263274
    264275/**
     276 * Ensures that the NT string has sufficient storage to hold @a cwcMin RTUTF16
     277 * chars plus a terminator.
     278 *
     279 * The NT string must have been returned by RTNtPathFromWinUtf8 or
     280 * RTNtPathFromWinUtf16Ex.
     281 *
     282 * @returns IPRT status code.
     283 * @param   pNtName             The NT path string.
     284 * @param   cwcMin              The minimum number of RTUTF16 chars. Max 32767.
     285 * @sa      RTNtPathFree
     286 */
     287RTDECL(int) RTNtPathEnsureSpace(struct _UNICODE_STRING *pNtName, size_t cwcMin);
     288
     289/**
    265290 * Frees the native path and root handle.
    266291 *
    267  * @param   pNtName             The NT path after a successful
    268  *                              RTNtPathFromWinUtf16Ex call.
    269  * @param   phRootDir           The root handle variable after a successfull
    270  *                              RTNtPathFromWinUtf16Ex call.
     292 * @param   pNtName             The NT path from a successful call to
     293 *                              RTNtPathFromWinUtf8 or RTNtPathFromWinUtf16Ex.
     294 * @param   phRootDir           The root handle variable from the same call.
    271295 */
    272296RTDECL(void) RTNtPathFree(struct _UNICODE_STRING *pNtName, HANDLE *phRootDir);
     297
     298
     299/**
     300 * Checks whether the path could be containing alternative 8.3 names generated
     301 * by NTFS, FAT, or other similar file systems.
     302 *
     303 * @returns Pointer to the first component that might be an 8.3 name, NULL if
     304 *          not 8.3 path.
     305 * @param   pwszPath        The path to check.
     306 *
     307 * @remarks This is making bad ASSUMPTION wrt to the naming scheme of 8.3 names,
     308 *          however, non-tilde 8.3 aliases are probably rare enough to not be
     309 *          worth all the extra code necessary to open each path component and
     310 *          check if we've got the short name or not.
     311 */
     312RTDECL(PRTUTF16) RTNtPathFindPossible8dot3Name(PCRTUTF16 pwszPath);
     313
     314/**
     315 * Fixes up a path possibly containing one or more alternative 8-dot-3 style
     316 * components.
     317 *
     318 * The path is fixed up in place.  Errors are ignored.
     319 *
     320 * @returns VINF_SUCCESS if it all went smoothly, informational status codes
     321 *          indicating the nature of last problem we ran into.
     322 *
     323 * @param   pUniStr     The path to fix up. MaximumLength is the max buffer
     324 *                      length.
     325 * @param   fPathOnly   Whether to only process the path and leave the filename
     326 *                      as passed in.
     327 */
     328RTDECL(int) RTNtPathExpand8dot3Path(struct _UNICODE_STRING *pUniStr, bool fPathOnly);
    273329
    274330
  • trunk/src/VBox/HostDrivers/Support/Makefile.kmk

    r60043 r60480  
    308308        $(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathChangeToUnixSlashes.cpp \
    309309        $(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathExt.cpp \
    310         $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrPrintHexBytes.cpp \
    311310        $(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16PrintHexBytes.cpp \
    312311        $(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16ICmpAscii.cpp \
     
    375374        win/SUPR3HardenedNoCrt-win.cpp \
    376375        $(VBOX_PATH_RUNTIME_SRC)/nt/RTErrConvertFromNtStatus.cpp \
     376        $(VBOX_PATH_RUNTIME_SRC)/nt/RTNtPathFindPossible8dot3Name.cpp \
     377        $(VBOX_PATH_RUNTIME_SRC)/nt/RTNtPathExpand8dot3Path.cpp \
    377378        $(VBOX_PATH_RUNTIME_SRC)/r3/nt/pathint-nt.cpp \
    378379        $(VBOX_PATH_RUNTIME_SRC)/win/RTErrConvertFromWin32.cpp \
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h

    r56733 r60480  
    7676DECLHIDDEN(int)     supHardNtVpThread(HANDLE hProcess, HANDLE hThread, PRTERRINFO pErrInfo);
    7777DECLHIDDEN(int)     supHardNtVpDebugger(HANDLE hProcess, PRTERRINFO pErrInfo);
    78 DECLHIDDEN(PRTUTF16) supHardNtVpIsPossible8dot3Path(PCRTUTF16 pwszPath);
    79 DECLHIDDEN(void)    supHardNtVpFix8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly);
    8078
    8179DECLHIDDEN(bool)    supHardViUtf16PathIsEqualEx(PCRTUTF16 pawcLeft, size_t cwcLeft, const char *pszRight);
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp

    r60193 r60480  
    10901090
    10911091/**
    1092  * Checks whether the path could be containing alternative 8.3 names generated
    1093  * by NTFS, FAT, or other similar file systems.
    1094  *
    1095  * @returns Pointer to the first component that might be an 8.3 name, NULL if
    1096  *          not 8.3 path.
    1097  * @param   pwszPath        The path to check.
    1098  *
    1099  * @remarks This is making bad ASSUMPTION wrt to the naming scheme of 8.3 names,
    1100  *          however, non-tilde 8.3 aliases are probably rare enough to not be
    1101  *          worth all the extra code necessary to open each path component and
    1102  *          check if we've got the short name or not.
    1103  */
    1104 DECLHIDDEN(PRTUTF16) supHardNtVpIsPossible8dot3Path(PCRTUTF16 pwszPath)
    1105 {
    1106     PCRTUTF16 pwszName = pwszPath;
    1107     for (;;)
    1108     {
    1109         RTUTF16 wc = *pwszPath++;
    1110         if (wc == '~')
    1111         {
    1112             /* Could check more here before jumping to conclusions... */
    1113             if (pwszPath - pwszName <= 8+1+3)
    1114                 return (PRTUTF16)pwszName;
    1115         }
    1116         else if (wc == '\\' || wc == '/' || wc == ':')
    1117             pwszName = pwszPath;
    1118         else if (wc == 0)
    1119             break;
    1120     }
    1121     return NULL;
    1122 }
    1123 
    1124 
    1125 /**
    1126  * Fixes up a path possibly containing one or more alternative 8-dot-3 style
    1127  * components.
    1128  *
    1129  * The path is fixed up in place.  Errors are ignored.
    1130  *
    1131  * @param   pUniStr     The path to fix up. MaximumLength is the max buffer
    1132  *                      length.
    1133  * @param   fPathOnly   Whether to only process the path and leave the filename
    1134  *                      as passed in.
    1135  */
    1136 DECLHIDDEN(void) supHardNtVpFix8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly)
    1137 {
    1138     /*
    1139      * We could use FileNormalizedNameInformation here and slap the volume device
    1140      * path in front of the result, but it's only supported since windows 8.0
    1141      * according to some docs... So we expand all supicious names.
    1142      */
    1143     union fix8dot3tmp
    1144     {
    1145         FILE_BOTH_DIR_INFORMATION Info;
    1146         uint8_t abBuffer[sizeof(FILE_BOTH_DIR_INFORMATION) + 2048 * sizeof(WCHAR)];
    1147     } *puBuf = NULL;
    1148 
    1149 
    1150     PRTUTF16 pwszFix = pUniStr->Buffer;
    1151     while (*pwszFix)
    1152     {
    1153         pwszFix = supHardNtVpIsPossible8dot3Path(pwszFix);
    1154         if (pwszFix == NULL)
    1155             break;
    1156 
    1157         RTUTF16 wc;
    1158         PRTUTF16 pwszFixEnd = pwszFix;
    1159         while ((wc = *pwszFixEnd) != '\0' && wc != '\\' && wc != '/')
    1160             pwszFixEnd++;
    1161         if (wc == '\0' && fPathOnly)
    1162             break;
    1163 
    1164         if (!puBuf)
    1165         {
    1166             puBuf = (union fix8dot3tmp *)RTMemAlloc(sizeof(*puBuf));
    1167             if (!puBuf)
    1168                 break;
    1169         }
    1170 
    1171         RTUTF16 const wcSaved = *pwszFix;
    1172         *pwszFix = '\0';                     /* paranoia. */
    1173 
    1174         UNICODE_STRING      NtDir;
    1175         NtDir.Buffer = pUniStr->Buffer;
    1176         NtDir.Length = NtDir.MaximumLength = (USHORT)((pwszFix - pUniStr->Buffer) * sizeof(WCHAR));
    1177 
    1178         HANDLE              hDir  = RTNT_INVALID_HANDLE_VALUE;
    1179         IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    1180 
    1181         OBJECT_ATTRIBUTES   ObjAttr;
    1182         InitializeObjectAttributes(&ObjAttr, &NtDir, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
    1183 #ifdef IN_RING0
    1184         ObjAttr.Attributes |= OBJ_KERNEL_HANDLE;
    1185 #endif
    1186 
    1187         NTSTATUS rcNt = NtCreateFile(&hDir,
    1188                                      FILE_READ_DATA | SYNCHRONIZE,
    1189                                      &ObjAttr,
    1190                                      &Ios,
    1191                                      NULL /* Allocation Size*/,
    1192                                      FILE_ATTRIBUTE_NORMAL,
    1193                                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    1194                                      FILE_OPEN,
    1195                                      FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
    1196                                      NULL /*EaBuffer*/,
    1197                                      0 /*EaLength*/);
    1198         *pwszFix = wcSaved;
    1199         if (NT_SUCCESS(rcNt))
    1200         {
    1201             RT_ZERO(*puBuf);
    1202 
    1203             IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    1204             UNICODE_STRING  NtFilterStr;
    1205             NtFilterStr.Buffer = pwszFix;
    1206             NtFilterStr.Length = (USHORT)((uintptr_t)pwszFixEnd - (uintptr_t)pwszFix);
    1207             NtFilterStr.MaximumLength = NtFilterStr.Length;
    1208             rcNt = NtQueryDirectoryFile(hDir,
    1209                                         NULL /* Event */,
    1210                                         NULL /* ApcRoutine */,
    1211                                         NULL /* ApcContext */,
    1212                                         &Ios,
    1213                                         puBuf,
    1214                                         sizeof(*puBuf) - sizeof(WCHAR),
    1215                                         FileBothDirectoryInformation,
    1216                                         FALSE /*ReturnSingleEntry*/,
    1217                                         &NtFilterStr,
    1218                                         FALSE /*RestartScan */);
    1219             if (NT_SUCCESS(rcNt) && puBuf->Info.NextEntryOffset == 0) /* There shall only be one entry matching... */
    1220             {
    1221                 uint32_t offName = puBuf->Info.FileNameLength / sizeof(WCHAR);
    1222                 while (offName > 0  && puBuf->Info.FileName[offName - 1] != '\\' && puBuf->Info.FileName[offName - 1] != '/')
    1223                     offName--;
    1224                 uint32_t cwcNameNew = (puBuf->Info.FileNameLength / sizeof(WCHAR)) - offName;
    1225                 uint32_t cwcNameOld = (uint32_t)(pwszFixEnd - pwszFix);
    1226 
    1227                 if (cwcNameOld == cwcNameNew)
    1228                     memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
    1229                 else if (   pUniStr->Length + cwcNameNew * sizeof(WCHAR) - cwcNameOld * sizeof(WCHAR) + sizeof(WCHAR)
    1230                          <= pUniStr->MaximumLength)
    1231                 {
    1232                     size_t cwcLeft = pUniStr->Length - (pwszFixEnd - pUniStr->Buffer) * sizeof(WCHAR) + sizeof(WCHAR);
    1233                     memmove(&pwszFix[cwcNameNew], pwszFixEnd, cwcLeft * sizeof(WCHAR));
    1234                     pUniStr->Length -= (USHORT)(cwcNameOld * sizeof(WCHAR));
    1235                     pUniStr->Length += (USHORT)(cwcNameNew * sizeof(WCHAR));
    1236                     pwszFixEnd      -= cwcNameOld;
    1237                     pwszFixEnd      -= cwcNameNew;
    1238                     memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
    1239                 }
    1240                 /* else: ignore overflow. */
    1241             }
    1242             /* else: ignore failure. */
    1243 
    1244             NtClose(hDir);
    1245         }
    1246 
    1247         /* Advance */
    1248         pwszFix = pwszFixEnd;
    1249     }
    1250 
    1251     if (puBuf)
    1252         RTMemFree(puBuf);
    1253 }
    1254 
    1255 
    1256 
    1257 /**
    12581092 * Matches two UNICODE_STRING structures in a case sensitive fashion.
    12591093 *
     
    13161150     */
    13171151    PUNICODE_STRING pLongName = &pImage->Name.UniStr;
    1318     if (supHardNtVpIsPossible8dot3Path(pLongName->Buffer))
     1152    if (RTNtPathFindPossible8dot3Name(pLongName->Buffer))
    13191153    {
    13201154        AssertCompile(sizeof(pThis->abMemory) > sizeof(pImage->Name));
     
    13251159        memcpy(pTmp->Buffer, pLongName->Buffer, pLongName->Length + sizeof(RTUTF16));
    13261160
    1327         supHardNtVpFix8dot3Path(pTmp, false /*fPathOnly*/);
     1161        RTNtPathExpand8dot3Path(pTmp, false /*fPathOnly*/);
    13281162        Assert(pTmp->Buffer[pTmp->Length / sizeof(RTUTF16)] == '\0');
    13291163
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r59811 r60480  
    12251225    }
    12261226
    1227     if (supHardNtVpIsPossible8dot3Path(uBuf.UniStr.Buffer))
     1227    if (!RTNtPathFindPossible8dot3Name(uBuf.UniStr.Buffer))
     1228        cbNameBuf += sizeof(WCHAR);
     1229    else
    12281230    {
    12291231        uBuf.UniStr.MaximumLength = sizeof(uBuf) - 128;
    1230         supHardNtVpFix8dot3Path(&uBuf.UniStr, true /*fPathOnly*/);
     1232        RTNtPathExpand8dot3Path(&uBuf.UniStr, true /*fPathOnly*/);
     1233        cbNameBuf = (uintptr_t)uBuf.UniStr.Buffer + uBuf.UniStr.Length + sizeof(WCHAR) - (uintptr_t)&uBuf.abBuffer[0];
    12311234    }
    12321235
  • trunk/src/VBox/Runtime/Makefile.kmk

    r59754 r60480  
    784784        generic/RTThreadGetNativeState-generic.cpp \
    785785        nt/RTErrConvertFromNtStatus.cpp \
     786        nt/RTNtPathExpand8dot3Path.cpp \
     787        nt/RTNtPathFindPossible8dot3Name.cpp \
    786788        r3/nt/fs-nt.cpp \
    787789        r3/nt/pathint-nt.cpp \
     
    21712173        generic/RTMpGetCoreCount-generic.cpp \
    21722174        nt/RTErrConvertFromNtStatus.cpp \
     2175        nt/RTNtPathExpand8dot3Path.cpp \
     2176        nt/RTNtPathFindPossible8dot3Name.cpp \
    21732177        r0drv/generic/threadctxhooks-r0drv-generic.cpp \
    21742178        r0drv/alloc-ef-r0drv.cpp \
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette