From b0066b81acef1ebd4713764fd860807805c92c0e Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 3 Dec 2015 20:18:21 -0800 Subject: [PATCH] sys: IRP_MJ_CREATE --- inc/winfsp/fsctl.h | 17 ++++++++--------- src/sys/create.c | 32 ++++++++++++++++++++++++++++---- src/sys/iop.c | 8 +++++--- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 355577d6..ffdcf5ea 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -21,8 +21,9 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = /* alignment macros */ #define FSP_FSCTL_ALIGN_UP(x, s) (((x) + ((s) - 1L)) & ~((s) - 1L)) -#define FSP_FSCTL_DEFAULT_ALIGNMENT (8) -#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(8)) +#define FSP_FSCTL_DEFAULT_ALIGNMENT 8 +#define FSP_FSCTL_DEFAULT_ALIGN_UP(x) FSP_FSCTL_ALIGN_UP(x, FSP_FSCTL_DEFAULT_ALIGNMENT) +#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(FSP_FSCTL_DEFAULT_ALIGNMENT)) /* fsctl device codes */ #define FSP_FSCTL_CREATE \ @@ -37,9 +38,7 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = #define FSP_FSCTL_CREATE_BUFFER_SIZE 128 #define FSP_FSCTL_TRANSACT_BUFFER_SIZE (16 * 1024) -#define FSP_FSCTL_VOLUME_PARAMS_SIZE \ - FSP_FSCTL_ALIGN_UP(sizeof(FSP_FSCTL_VOLUME_PARAMS),\ - FSP_FSCTL_DEFAULT_ALIGNMENT) +#define FSP_FSCTL_VOLUME_PARAMS_SIZE FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_VOLUME_PARAMS)) #define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (4 * 1024) #define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (4 * 1024) @@ -142,7 +141,7 @@ typedef struct static inline FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactProduceRequest( FSP_FSCTL_TRANSACT_REQ *Request, SIZE_T RequestSize, PVOID RequestBufEnd) { - PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_ALIGN_UP(RequestSize, FSP_FSCTL_DEFAULT_ALIGNMENT); + PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(RequestSize); return NextRequest <= RequestBufEnd ? NextRequest : 0; } static inline const FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactConsumeRequest( @@ -151,13 +150,13 @@ static inline const FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactConsumeRequest( if ((PUINT8)Request + sizeof(Request->Size) > (PUINT8)RequestBufEnd || sizeof(FSP_FSCTL_TRANSACT_REQ) > Request->Size) return 0; - PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_ALIGN_UP(Request->Size, FSP_FSCTL_DEFAULT_ALIGNMENT); + PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(Request->Size); return NextRequest <= RequestBufEnd ? NextRequest : 0; } static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactProduceResponse( FSP_FSCTL_TRANSACT_RSP *Response, SIZE_T ResponseSize, PVOID ResponseBufEnd) { - PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_ALIGN_UP(ResponseSize, FSP_FSCTL_DEFAULT_ALIGNMENT); + PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(ResponseSize); return NextResponse <= ResponseBufEnd ? NextResponse : 0; } static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( @@ -166,7 +165,7 @@ static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( if ((PUINT8)Response + sizeof(Response->Size) > (PUINT8)ResponseBufEnd || sizeof(FSP_FSCTL_TRANSACT_RSP) > Response->Size) return 0; - PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_ALIGN_UP(Response->Size, FSP_FSCTL_DEFAULT_ALIGNMENT); + PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(Response->Size); return NextResponse <= ResponseBufEnd ? NextResponse : 0; } diff --git a/src/sys/create.c b/src/sys/create.c index 3f93a71a..238af010 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -60,7 +60,8 @@ static NTSTATUS FspFsvolCreate( KPROCESSOR_MODE RequestorMode = FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; - //PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; + PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; + ULONG SecurityDescriptorSize = 0; USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; ULONG CreateOptions = IrpSp->Parameters.Create.Options & 0xffffff; @@ -68,6 +69,8 @@ static NTSTATUS FspFsvolCreate( LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; //ULONG EaLength = IrpSp->Parameters.Create.EaLength; + BOOLEAN IsAbsoluteSecurityDescriptor = FALSE; + BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE; BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); BOOLEAN HasTrailingBackslash = FALSE; FSP_FILE_CONTEXT *FsContext = 0; @@ -89,6 +92,26 @@ static NTSTATUS FspFsvolCreate( if (0 != EaBuffer && !FsvrtDeviceExtension->VolumeParams.EaSupported) return STATUS_EAS_NOT_SUPPORTED; + /* check security descriptor validity */ + if (0 != SecurityDescriptor) + { + IsAbsoluteSecurityDescriptor = RtlValidSecurityDescriptor(SecurityDescriptor); + if (IsAbsoluteSecurityDescriptor) + { + Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize); + if (STATUS_BUFFER_TOO_SMALL != Result) + return STATUS_INVALID_PARAMETER; + } + else + { + SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); + IsSelfRelativeSecurityDescriptor = RtlValidRelativeSecurityDescriptor( + SecurityDescriptor, SecurityDescriptorSize, 0); + if (!IsSelfRelativeSecurityDescriptor) + return STATUS_INVALID_PARAMETER; + } + } + /* according to fastfat, filenames that begin with two backslashes are ok */ if (sizeof(WCHAR) * 2 <= FileName.Length && L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) @@ -167,7 +190,7 @@ static NTSTATUS FspFsvolCreate( */ /* create the user-mode file system request */ - Result = FspIopCreateRequest(Irp, &FsContext->FileName, 0, &Request); + Result = FspIopCreateRequest(Irp, &FsContext->FileName, SecurityDescriptorSize, &Request); if (!NT_SUCCESS(Result)) { FspFileContextDelete(FsContext); @@ -179,8 +202,9 @@ static NTSTATUS FspFsvolCreate( Request->Req.Create.CreateDisposition = CreateDisposition; Request->Req.Create.CreateOptions = CreateOptions; Request->Req.Create.FileAttributes = FileAttributes; - Request->Req.Create.SecurityDescriptor = 0; - Request->Req.Create.SecurityDescriptorSize = 0; + Request->Req.Create.SecurityDescriptor = 0 == SecurityDescriptor ? 0 : + FSP_FSCTL_DEFAULT_ALIGN_UP(FsContext->FileName.Length + sizeof(WCHAR)); + Request->Req.Create.SecurityDescriptorSize = (UINT16)SecurityDescriptorSize; Request->Req.Create.AllocationSize = AllocationSize.QuadPart; Request->Req.Create.AccessToken = 0; Request->Req.Create.DesiredAccess = DesiredAccess; diff --git a/src/sys/iop.c b/src/sys/iop.c index 011e26c2..68a2220a 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -20,20 +20,22 @@ NTSTATUS FspIopCreateRequest( { PAGED_CODE(); + FSP_FSCTL_TRANSACT_REQ *Request; + *PRequest = 0; if (0 != FileName) - ExtraSize += FileName->Length + sizeof(WCHAR); + ExtraSize += FSP_FSCTL_DEFAULT_ALIGN_UP(FileName->Length + sizeof(WCHAR)); if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) return STATUS_INVALID_PARAMETER; - FSP_FSCTL_TRANSACT_REQ *Request = ExAllocatePoolWithTag(PagedPool, + Request = ExAllocatePoolWithTag(PagedPool, sizeof *Request + ExtraSize, FSP_TAG); if (0 == Request) return STATUS_INSUFFICIENT_RESOURCES; - RtlZeroMemory(Request, sizeof *Request); + RtlZeroMemory(Request, sizeof *Request + ExtraSize); Request->Size = (UINT16)(sizeof *Request + ExtraSize); Request->Hint = (UINT_PTR)Irp; if (0 != FileName)