From 0cc546876474464d9ca45b7244d9b961dac5c06a Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 10 Feb 2016 16:57:12 -0800 Subject: [PATCH] dll: FspPathPrefix(), FspPathSuffix(): better root handling --- inc/winfsp/winfsp.h | 4 ++-- src/dll/create.c | 23 +++++++++++++---------- src/dll/path.c | 8 ++++++-- tst/winfsp-tests/memfs.cpp | 23 ++++++++--------------- tst/winfsp-tests/path-test.c | 32 ++++++++++++++++++-------------- 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 8c8fc04c..0304bcf8 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -223,8 +223,8 @@ NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem, /* * Path Handling */ -FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain); -FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix); +FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain, PWSTR Root); +FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix, PWSTR Root); FSP_API VOID FspPathCombine(PWSTR Prefix, PWSTR Suffix); /* diff --git a/src/dll/create.c b/src/dll/create.c index e575d7b4..b368d3b4 100644 --- a/src/dll/create.c +++ b/src/dll/create.c @@ -56,7 +56,8 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, } NTSTATUS Result; - PWSTR Parent, Suffix, Prefix, Remain; + WCHAR Root[2] = L"\\", TraverseCheckRoot[2] = L"\\"; + PWSTR FileName, Suffix, Prefix, Remain; UINT32 FileAttributes; PSECURITY_DESCRIPTOR SecurityDescriptor = 0; SIZE_T SecurityDescriptorSize; @@ -67,7 +68,9 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, BOOL AccessStatus; if (CheckParentDirectory) - FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix); + FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root); + else + FileName = (PWSTR)Request->Buffer; SecurityDescriptorSize = 1024; SecurityDescriptor = MemAlloc(SecurityDescriptorSize); @@ -80,21 +83,20 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, if (Request->Req.Create.UserMode && AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege) { - Remain = (PWSTR)Request->Buffer; + Remain = (PWSTR)FileName; for (;;) { - FspPathPrefix(Remain, &Prefix, &Remain); + FspPathPrefix(Remain, &Prefix, &Remain, TraverseCheckRoot); if (L'\0' == Remain[0]) { - FspPathCombine((PWSTR)Request->Buffer, Remain); + FspPathCombine(FileName, Remain); break; } - Prefix = L'\0' == Prefix[0] ? L"\\" : (PWSTR)Request->Buffer; Result = FspGetSecurity(FileSystem, Prefix, 0, &SecurityDescriptor, &SecurityDescriptorSize); - FspPathCombine((PWSTR)Request->Buffer, Remain); + FspPathCombine(FileName, Remain); if (!NT_SUCCESS(Result)) { @@ -116,7 +118,7 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, } } - Result = FspGetSecurity(FileSystem, (PWSTR)Request->Buffer, &FileAttributes, + Result = FspGetSecurity(FileSystem, FileName, &FileAttributes, &SecurityDescriptor, &SecurityDescriptorSize); if (!NT_SUCCESS(Result)) goto exit; @@ -498,6 +500,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F FSP_FSCTL_TRANSACT_REQ *Request) { NTSTATUS Result; + WCHAR Root[2] = L"\\"; PWSTR Parent, Suffix; UINT32 GrantedAccess; PVOID FileNode; @@ -509,11 +512,11 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F if (!NT_SUCCESS(Result)) return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); - FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix); FileNode = 0; memset(&FileInfo, 0, sizeof FileInfo); + FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix, Root); Result = FileSystem->Interface->Open(FileSystem, Request, - (PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions, + Parent, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions, &FileNode, &FileInfo); FspPathCombine((PWSTR)Request->Buffer, Suffix); if (!NT_SUCCESS(Result)) diff --git a/src/dll/path.c b/src/dll/path.c index 1e100506..3b4f765c 100644 --- a/src/dll/path.c +++ b/src/dll/path.c @@ -6,13 +6,15 @@ #include -FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain) +FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain, PWSTR Root) { PWSTR Pointer; for (Pointer = Path; *Pointer; Pointer++) if (L'\\' == *Pointer) { + if (0 != Root && Path == Pointer) + Path = Root; *Pointer++ = L'\0'; for (; L'\\' == *Pointer; Pointer++) ; @@ -23,7 +25,7 @@ FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain) *PRemain = Pointer; } -FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix) +FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix, PWSTR Root) { PWSTR Pointer, RemainEnd, Suffix = 0; @@ -41,6 +43,8 @@ FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix) *PRemain = Path; if (Path < Suffix) { + if (0 != Root && Path == RemainEnd && L'\\' == *Path) + *PRemain = Root; *RemainEnd = L'\0'; *PSuffix = Suffix; } diff --git a/tst/winfsp-tests/memfs.cpp b/tst/winfsp-tests/memfs.cpp index c317b5d9..13033b5b 100644 --- a/tst/winfsp-tests/memfs.cpp +++ b/tst/winfsp-tests/memfs.cpp @@ -133,10 +133,11 @@ static inline MEMFS_FILE_NODE *MemfsFileNodeMapGetParent(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR FileName, PNTSTATUS PResult) { + WCHAR Root[2] = L"\\"; PWSTR Remain, Suffix; - FspPathSuffix(FileName, &Remain, &Suffix); + FspPathSuffix(FileName, &Remain, &Suffix, Root); MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->find(Remain); - FspPathCombine(Remain, Suffix); + FspPathCombine(FileName, Suffix); if (iter == FileNodeMap->end()) { *PResult = STATUS_OBJECT_PATH_NOT_FOUND; @@ -179,13 +180,14 @@ static inline BOOLEAN MemfsFileNodeMapHasChild(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMFS_FILE_NODE *FileNode) { BOOLEAN Result; + WCHAR Root[2] = L"\\"; PWSTR Remain, Suffix; MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->upper_bound(FileNode->FileName); if (iter == FileNodeMap->end()) return FALSE; - FspPathSuffix(iter->second->FileName, &Remain, &Suffix); + FspPathSuffix(iter->second->FileName, &Remain, &Suffix, Root); Result = 0 == MemfsFileNameCompare(Remain, FileNode->FileName); - FspPathCombine(Remain, Suffix); + FspPathCombine(iter->second->FileName, Suffix); return Result; } @@ -196,7 +198,7 @@ static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem, MEMFS *Memfs = (MEMFS *)FileSystem->UserContext; MEMFS_FILE_NODE *RootNode; - RootNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, L""); + RootNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, L"\\"); if (0 == RootNode) return STATUS_DISK_CORRUPT_ERROR; @@ -218,9 +220,6 @@ static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem, MEMFS_FILE_NODE *FileNode; NTSTATUS Result; - if (L'\\' == FileName[0] && L'\0' == FileName[1]) - FileName = L""; - FileNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, FileName); if (0 == FileNode) { @@ -259,9 +258,6 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem, NTSTATUS Result; BOOLEAN Inserted; - if (L'\\' == FileName[0] && L'\0' == FileName[1]) - FileName = L""; - if (CreateOptions & FILE_DIRECTORY_FILE) AllocationSize = 0; @@ -332,9 +328,6 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem, MEMFS_FILE_NODE *FileNode; NTSTATUS Result; - if (L'\\' == FileName[0] && L'\0' == FileName[1]) - FileName = L""; - FileNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, FileName); if (0 == FileNode) { @@ -635,7 +628,7 @@ NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout, * Create root directory. */ - Result = MemfsFileNodeCreate(L"", &RootNode); + Result = MemfsFileNodeCreate(L"\\", &RootNode); if (!NT_SUCCESS(Result)) { MemfsDelete(Memfs); diff --git a/tst/winfsp-tests/path-test.c b/tst/winfsp-tests/path-test.c index a65df42d..a0d648aa 100644 --- a/tst/winfsp-tests/path-test.c +++ b/tst/winfsp-tests/path-test.c @@ -19,16 +19,17 @@ void path_prefix_test(void) L"foo\\\\\\bar\\\\baz", L"foo\\\\\\bar\\\\baz\\", L"foo\\\\\\bar\\\\baz\\\\", + L"foo", }; PWSTR opaths[] = { L"", L"", - L"", L"", - L"", L"", - L"", L"a", - L"", L"a", - L"", L"a\\", - L"", L"a\\\\", + L"ROOT", L"", + L"ROOT", L"", + L"ROOT", L"a", + L"ROOT", L"a", + L"ROOT", L"a\\", + L"ROOT", L"a\\\\", L"a", L"", L"a", L"", L"a", L"b", @@ -36,6 +37,7 @@ void path_prefix_test(void) L"foo", L"bar\\\\baz", L"foo", L"bar\\\\baz\\", L"foo", L"bar\\\\baz\\\\", + L"foo", L"", }; for (size_t i = 0; sizeof ipaths / sizeof ipaths[0] > i; i++) @@ -43,10 +45,10 @@ void path_prefix_test(void) PWSTR Prefix, Remain; WCHAR buf[32]; wcscpy_s(buf, 32, ipaths[i]); - FspPathPrefix(buf, &Prefix, &Remain); + FspPathPrefix(buf, &Prefix, &Remain, L"ROOT"); ASSERT(0 == wcscmp(opaths[2 * i + 0], Prefix)); ASSERT(0 == wcscmp(opaths[2 * i + 1], Remain)); - FspPathCombine(Prefix, Remain); + FspPathCombine(buf, Remain); ASSERT(0 == wcscmp(ipaths[i], buf)); } } @@ -69,14 +71,15 @@ void path_suffix_test(void) L"foo\\\\\\bar\\\\baz", L"foo\\\\\\bar\\\\baz\\", L"foo\\\\\\bar\\\\baz\\\\", + L"foo", }; PWSTR opaths[] = { L"", L"", - L"", L"", - L"", L"", - L"", L"a", - L"", L"a", + L"ROOT", L"", + L"ROOT", L"", + L"ROOT", L"a", + L"ROOT", L"a", L"\\\\a", L"", L"\\\\a", L"", L"a", L"", @@ -86,6 +89,7 @@ void path_suffix_test(void) L"foo\\\\\\bar", L"baz", L"foo\\\\\\bar\\\\baz", L"", L"foo\\\\\\bar\\\\baz", L"", + L"foo", L"", }; for (size_t i = 0; sizeof ipaths / sizeof ipaths[0] > i; i++) @@ -93,10 +97,10 @@ void path_suffix_test(void) PWSTR Remain, Suffix; WCHAR buf[32]; wcscpy_s(buf, 32, ipaths[i]); - FspPathSuffix(buf, &Remain, &Suffix); + FspPathSuffix(buf, &Remain, &Suffix, L"ROOT"); ASSERT(0 == wcscmp(opaths[2 * i + 0], Remain)); ASSERT(0 == wcscmp(opaths[2 * i + 1], Suffix)); - FspPathCombine(Remain, Suffix); + FspPathCombine(buf, Suffix); ASSERT(0 == wcscmp(ipaths[i], buf)); } }