Skip to content

Commit

Permalink
Mac ProjFS kext: Blocks renaming files in offline roots at the hydrat…
Browse files Browse the repository at this point in the history
…ion stage

This causes the offline root check to block the file renaming operation at the hydration stage for empty files. The unit test is updated to check both the empty and hydrated scenarios.
  • Loading branch information
pmj committed Aug 5, 2019
1 parent 98d117b commit bf90ffa
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 42 deletions.
2 changes: 1 addition & 1 deletion ProjFS.Mac/PrjFSKext/KauthHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ KEXT_STATIC int HandleVnodeOperation(
// Prevent system services from hydrating files as this tends to cause deadlocks with the kauth listeners for Antivirus software
CallbackPolicy_UserInitiatedOnly,
// Prevent write access to empty files in offline roots. For now allow reads, and always allow the user to delete files.
isWriteOperation,
isWriteOperation || (isRename && s_osSupportsRenameDetection),
&root,
&vnodeFsidInode,
&kauthResult,
Expand Down
102 changes: 61 additions & 41 deletions ProjFS.Mac/PrjFSKextTests/HandleOperationTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1335,50 +1335,70 @@ - (void) testOfflineRootDeniesRename
// to let them happen as we can't distinguish them from file deletions
// before it's already happened.

testFileVnode->attrValues.va_flags = FileFlags_IsInVirtualizationRoot;

ActiveProvider_Disconnect(self->dummyRepoHandle, &self->dummyClient);

TestForAllSupportedDarwinVersions(^{
InitPendingRenames();

if (version_major >= PrjFSDarwinMajorVersion::MacOS10_14_Mojave)
{
string renamedFilePath = self->filePath + "_renamed";
HandleFileOpOperation(
nullptr, // credential
nullptr, /* idata, unused */
KAUTH_FILEOP_WILL_RENAME,
reinterpret_cast<uintptr_t>(self->testFileVnode.get()),
reinterpret_cast<uintptr_t>(self->filePath.c_str()),
reinterpret_cast<uintptr_t>(renamedFilePath.c_str()),
0); // unused
}

int deleteAuthResult =
HandleVnodeOperation(
nullptr,
nullptr,
KAUTH_VNODE_DELETE,
reinterpret_cast<uintptr_t>(self->context),
reinterpret_cast<uintptr_t>(self->testFileVnode.get()),
0,
0);

if (version_major <= PrjFSDarwinMajorVersion::MacOS10_13_HighSierra)
{
XCTAssertEqual(deleteAuthResult, KAUTH_RESULT_DEFER);
}
else
// Check the behaviour works for both empty and full files, and empty files are not hydrated.
vector<uint32_t> vnode_flags { FileFlags_IsInVirtualizationRoot, FileFlags_IsInVirtualizationRoot | FileFlags_IsEmpty };

std::for_each(vnode_flags.begin(), vnode_flags.end(),
[self](uint32_t flags)
{
// On Mojave+, renames should be blocked:
XCTAssertEqual(deleteAuthResult, KAUTH_RESULT_DENY);
}

MockCalls::Clear();
CleanupPendingRenames();
});

testFileVnode->attrValues.va_flags = flags;

TestForAllSupportedDarwinVersions(^{
InitPendingRenames();

if (version_major >= PrjFSDarwinMajorVersion::MacOS10_14_Mojave)
{
string renamedFilePath = self->filePath + "_renamed";
HandleFileOpOperation(
nullptr, // credential
nullptr, /* idata, unused */
KAUTH_FILEOP_WILL_RENAME,
reinterpret_cast<uintptr_t>(self->testFileVnode.get()),
reinterpret_cast<uintptr_t>(self->filePath.c_str()),
reinterpret_cast<uintptr_t>(renamedFilePath.c_str()),
0); // unused
}

int deleteAuthResult =
HandleVnodeOperation(
nullptr,
nullptr,
KAUTH_VNODE_DELETE,
reinterpret_cast<uintptr_t>(self->context),
reinterpret_cast<uintptr_t>(self->testFileVnode.get()),
0,
0);

if (version_major <= PrjFSDarwinMajorVersion::MacOS10_13_HighSierra)
{
XCTAssertEqual(deleteAuthResult, KAUTH_RESULT_DEFER);
}
else
{
// On Mojave+, renames should be blocked:
XCTAssertEqual(deleteAuthResult, KAUTH_RESULT_DENY, "flags = 0x%x", flags);
}

XCTAssertFalse(
MockCalls::DidCallFunction(
ProviderMessaging_TrySendRequestAndWaitForResponse,
_,
MessageType_KtoU_HydrateFile,
self->testFileVnode.get(),
_,
_,
_,
_,
_,
_,
nullptr));

MockCalls::Clear();
CleanupPendingRenames();
});
});
}

- (void) testOfflineRootAllowsRegisteredProcessAccessToEmptyFile
Expand Down

0 comments on commit bf90ffa

Please sign in to comment.