diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index 4056a286..1a050b7c 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -17,21 +17,23 @@ static inline VOID GlobalDevicePath(PWCHAR DevicePathBuf, SIZE_T DevicePathSize, L'\\' == DevicePath[0] ? GLOBALROOT "%s" : GLOBALROOT "\\Device\\%s", DevicePath); } -FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, - const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor, - PWCHAR VolumePathBuf, SIZE_T VolumePathSize) +static NTSTATUS CreateSelfRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, + PSECURITY_DESCRIPTOR *PSelfRelativeSecurityDescriptor, PDWORD PSelfRelativeSecurityDescriptorSize) { - NTSTATUS Result = STATUS_SUCCESS; - FSP_FSCTL_VOLUME_PARAMS *ParamsBuf = 0; - HANDLE Token = 0; - PTOKEN_DEFAULT_DACL DefaultDacl = 0; + NTSTATUS Result; + PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor = 0; + DWORD SelfRelativeSecurityDescriptorSize; SECURITY_DESCRIPTOR SecurityDescriptorStruct; - PSECURITY_DESCRIPTOR SecurityDescriptorBuf; - DWORD SecurityDescriptorSize, Bytes; - WCHAR DevicePathBuf[MAX_PATH]; - HANDLE DeviceHandle = INVALID_HANDLE_VALUE; + PTOKEN_OWNER Owner = 0; + PTOKEN_PRIMARY_GROUP PrimaryGroup = 0; + PTOKEN_DEFAULT_DACL DefaultDacl = 0; + DWORD OwnerSize = 0; + DWORD PrimaryGroupSize = 0; + DWORD DefaultDaclSize = 0; + HANDLE Token = 0; - VolumePathBuf[0] = L'\0'; + *PSelfRelativeSecurityDescriptor = 0; + *PSelfRelativeSecurityDescriptorSize = 0; if (0 == SecurityDescriptor) { @@ -40,63 +42,123 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, Result = FspNtStatusFromWin32(GetLastError()); goto exit; } - Bytes = 0; - if (!GetTokenInformation(Token, TokenDefaultDacl, 0, 0, &Bytes) && - ERROR_INSUFFICIENT_BUFFER != GetLastError()) + if ((!GetTokenInformation(Token, TokenOwner, 0, 0, &OwnerSize) && + ERROR_INSUFFICIENT_BUFFER != GetLastError()) || + (!GetTokenInformation(Token, TokenPrimaryGroup, 0, 0, &PrimaryGroupSize) && + ERROR_INSUFFICIENT_BUFFER != GetLastError()) || + (!GetTokenInformation(Token, TokenDefaultDacl, 0, 0, &DefaultDaclSize) && + ERROR_INSUFFICIENT_BUFFER != GetLastError())) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } - DefaultDacl = malloc(Bytes); - if (0 == DefaultDacl) + Owner = malloc(OwnerSize); + PrimaryGroup = malloc(PrimaryGroupSize); + DefaultDacl = malloc(DefaultDaclSize); + if (0 == Owner || 0 == PrimaryGroup || 0 == DefaultDacl) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } - if (!GetTokenInformation(Token, TokenDefaultDacl, DefaultDacl, Bytes, &Bytes) || - !InitializeSecurityDescriptor(&SecurityDescriptorStruct, SECURITY_DESCRIPTOR_REVISION) || - !SetSecurityDescriptorDacl(&SecurityDescriptorStruct, TRUE, DefaultDacl->DefaultDacl, FALSE)) + if (!GetTokenInformation(Token, TokenOwner, Owner, OwnerSize, &OwnerSize) || + !GetTokenInformation(Token, TokenPrimaryGroup, PrimaryGroup, PrimaryGroupSize, &PrimaryGroupSize) || + !GetTokenInformation(Token, TokenDefaultDacl, DefaultDacl, DefaultDaclSize, &DefaultDaclSize)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + if (!InitializeSecurityDescriptor(&SecurityDescriptorStruct, SECURITY_DESCRIPTOR_REVISION) || + !SetSecurityDescriptorOwner(&SecurityDescriptorStruct, Owner->Owner, FALSE) || + !SetSecurityDescriptorGroup(&SecurityDescriptorStruct, PrimaryGroup->PrimaryGroup, FALSE) || + !SetSecurityDescriptorDacl(&SecurityDescriptorStruct, TRUE, DefaultDacl->DefaultDacl, FALSE) || + !SetSecurityDescriptorControl(&SecurityDescriptorStruct, SE_DACL_PROTECTED, SE_DACL_PROTECTED)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } SecurityDescriptor = &SecurityDescriptorStruct; - CloseHandle(Token); - Token = 0; } - SecurityDescriptorSize = 0; - if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize) && + SelfRelativeSecurityDescriptorSize = 0; + if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SelfRelativeSecurityDescriptorSize) && ERROR_INSUFFICIENT_BUFFER != GetLastError()) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } - ParamsBuf = malloc(FSP_FSCTL_VOLUME_PARAMS_SIZE + SecurityDescriptorSize); + SelfRelativeSecurityDescriptor = malloc(SelfRelativeSecurityDescriptorSize); + if (0 == SelfRelativeSecurityDescriptor) + { + Result = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + if (!MakeSelfRelativeSD(SecurityDescriptor, SelfRelativeSecurityDescriptor, &SelfRelativeSecurityDescriptorSize)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + *PSelfRelativeSecurityDescriptor = SelfRelativeSecurityDescriptor; + *PSelfRelativeSecurityDescriptorSize = SelfRelativeSecurityDescriptorSize; + Result = STATUS_SUCCESS; + +exit: + if (0 != Token) + CloseHandle(Token); + + free(DefaultDacl); + free(PrimaryGroup); + free(Owner); + + if (STATUS_SUCCESS != Result) + free(SelfRelativeSecurityDescriptor); + + return Result; +} + +FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor, + PWCHAR VolumePathBuf, SIZE_T VolumePathSize) +{ + NTSTATUS Result = STATUS_SUCCESS; + PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor = 0; + DWORD SelfRelativeSecurityDescriptorSize; + FSP_FSCTL_VOLUME_PARAMS *ParamsBuf = 0; + WCHAR DevicePathBuf[MAX_PATH]; + HANDLE DeviceHandle = INVALID_HANDLE_VALUE; + DWORD Bytes; + + if (sizeof(WCHAR) <= VolumePathSize) + VolumePathBuf[0] = L'\0'; + + Result = CreateSelfRelativeSecurityDescriptor(SecurityDescriptor, + &SelfRelativeSecurityDescriptor, &SelfRelativeSecurityDescriptorSize); + if (!NT_SUCCESS(Result)) + goto exit; + + ParamsBuf = malloc(FSP_FSCTL_VOLUME_PARAMS_SIZE + SelfRelativeSecurityDescriptorSize); if (0 == ParamsBuf) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } memset(ParamsBuf, 0, FSP_FSCTL_VOLUME_PARAMS_SIZE); - SecurityDescriptorBuf = (PVOID)((PUINT8)ParamsBuf + FSP_FSCTL_VOLUME_PARAMS_SIZE); - if (!MakeSelfRelativeSD(SecurityDescriptor, SecurityDescriptorBuf, &SecurityDescriptorSize)) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } *ParamsBuf = *Params; + memcpy((PUINT8)ParamsBuf + FSP_FSCTL_VOLUME_PARAMS_SIZE, + SelfRelativeSecurityDescriptor, SelfRelativeSecurityDescriptorSize); GlobalDevicePath(DevicePathBuf, sizeof DevicePathBuf, DevicePath); #if !defined(NDEBUG) { PSTR Sddl; - if (ConvertSecurityDescriptorToStringSecurityDescriptorA(SecurityDescriptorBuf, - SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &Sddl, 0)) + if (ConvertSecurityDescriptorToStringSecurityDescriptorA(SelfRelativeSecurityDescriptor, + SDDL_REVISION_1, + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + &Sddl, 0)) { DEBUGLOG("Device=\"%S\", Sddl=\"%s\", SdSize=%lu", - DevicePathBuf, Sddl, SecurityDescriptorSize); + DevicePathBuf, Sddl, SelfRelativeSecurityDescriptorSize); LocalFree(Sddl); } } @@ -113,7 +175,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, } if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE, - ParamsBuf, FSP_FSCTL_VOLUME_PARAMS_SIZE + SecurityDescriptorSize, + ParamsBuf, FSP_FSCTL_VOLUME_PARAMS_SIZE + SelfRelativeSecurityDescriptorSize, VolumePathBuf, (DWORD)VolumePathSize, &Bytes, 0)) { @@ -125,11 +187,9 @@ exit: if (INVALID_HANDLE_VALUE != DeviceHandle) CloseHandle(DeviceHandle); - if (0 != Token) - CloseHandle(Token); - free(DefaultDacl); free(ParamsBuf); + free(SelfRelativeSecurityDescriptor); return Result; }