sys: fix filename length check during query directory operations

This commit is contained in:
Bill Zissimopoulos 2017-12-01 17:01:59 -08:00
parent 2ca33665ef
commit c87ff75b8f
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
4 changed files with 100 additions and 6 deletions

View File

@ -611,7 +611,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
if (0 != FileDesc->DirectoryMarker.Buffer)
{
ASSERT(
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) >=
FileDesc->DirectoryMarker.Length);
Request->Req.QueryDirectory.Marker.Offset =
@ -921,7 +921,7 @@ NTSTATUS FspFsvolDirectoryControlComplete(
if (0 != FileDesc->DirectoryMarker.Buffer)
{
ASSERT(
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) >=
FileDesc->DirectoryMarker.Length);
Request->Req.QueryDirectory.Marker.Offset =

View File

@ -2166,7 +2166,7 @@ NTSTATUS FspFileDescSetDirectoryMarker(FSP_FILE_DESC *FileDesc,
FspFsvolDeviceExtension(FileDesc->FileNode->FsvolDeviceObject);
UNICODE_STRING DirectoryMarker;
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength < FileName->Length)
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) < FileName->Length)
return STATUS_OBJECT_NAME_INVALID;
DirectoryMarker.Length = DirectoryMarker.MaximumLength = FileName->Length;

View File

@ -657,7 +657,7 @@ exit /b 0
:sample-passthrough-dotnet
call :__run_sample_test passthrough-dotnet anycpu passthrough-dotnet winfsp-tests-x64 ^
"-create_backup_test -create_restore_test -create_namelen_test -delete_access_test"
"-create_backup_test -create_restore_test -create_namelen_test -delete_access_test -querydir_namelen_test"
if !ERRORLEVEL! neq 0 goto fail
exit /b 0
@ -725,7 +725,7 @@ L:
"%ProjRoot%\build\VStudio\build\%Configuration%\%4.exe" ^
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
-create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
-getfileinfo_name_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -exec_rename_dir_test ^
-getfileinfo_name_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -querydir_namelen_test -exec_rename_dir_test ^
-reparse* -stream*
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
popd
@ -785,7 +785,7 @@ L:
"%ProjRoot%\build\VStudio\build\%Configuration%\%3.exe" ^
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
-create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
-getfileinfo_name_test -setfileinfo_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -exec_rename_dir_test ^
-getfileinfo_name_test -setfileinfo_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -querydir_namelen_test -exec_rename_dir_test ^
-reparse* -stream*
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
popd

View File

@ -416,6 +416,98 @@ void querydir_buffer_overflow_test(void)
}
}
static VOID querydir_namelen_exists(PWSTR FilePath)
{
HANDLE Handle;
WIN32_FIND_DATAW FindData;
Handle = FindFirstFileW(FilePath, &FindData);
ASSERT(INVALID_HANDLE_VALUE != Handle);
FindClose(Handle);
}
static void querydir_namelen_dotest(ULONG Flags, PWSTR Prefix, PWSTR Drive)
{
/* based on create_namelen_dotest */
void *memfs = memfs_start(Flags);
WCHAR FilePath[1024];
PWSTR FilePathBgn, P, EndP;
DWORD MaxComponentLength;
HANDLE Handle;
BOOL Success;
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Drive ? Drive : memfs_volumename(memfs));
Success = GetVolumeInformationW(FilePath,
0, 0,
0, &MaxComponentLength, 0,
0, 0);
ASSERT(Success);
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
FilePathBgn = FilePath + wcslen(FilePath);
for (P = FilePathBgn, EndP = P + MaxComponentLength - 1; EndP > P; P++)
*P = (P - FilePathBgn) % 10 + '0';
*P = L'\0';
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
querydir_namelen_exists(FilePath);
Success = CloseHandle(Handle);
ASSERT(Success);
for (P = FilePathBgn, EndP = P + MaxComponentLength; EndP > P; P++)
*P = (P - FilePathBgn) % 10 + '0';
*P = L'\0';
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
querydir_namelen_exists(FilePath);
Success = CloseHandle(Handle);
ASSERT(Success);
for (P = FilePathBgn, EndP = P + MaxComponentLength + 1; EndP > P; P++)
*P = (P - FilePathBgn) % 10 + '0';
*P = L'\0';
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE == Handle);
ASSERT(ERROR_INVALID_NAME == GetLastError());
memfs_stop(memfs);
}
static void querydir_namelen_test(void)
{
if (OptShareName || OptMountPoint)
return;
if (NtfsTests)
{
WCHAR DirBuf[MAX_PATH], DriveBuf[3];
GetTestDirectoryAndDrive(DirBuf, DriveBuf);
querydir_namelen_dotest(-1, DirBuf, DriveBuf);
}
if (WinFspDiskTests)
querydir_namelen_dotest(MemfsDisk, 0, 0);
#if 0
/* This test does not work when going through the MUP! */
if (WinFspNetTests)
querydir_namelen_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share");
#endif
}
static unsigned __stdcall dirnotify_dotest_thread(void *FilePath)
{
FspDebugLog(__FUNCTION__ ": \"%S\"\n", FilePath);
@ -552,5 +644,7 @@ void dirctl_tests(void)
TEST(querydir_expire_cache_test);
if (!OptShareName)
TEST(querydir_buffer_overflow_test);
if (!OptShareName && !OptMountPoint)
TEST(querydir_namelen_test);
TEST(dirnotify_test);
}