diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 7c252f1b..77d7bf9b 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -78,6 +78,9 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR), #define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024) #define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX +#define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((T) & 0xffffffff)) +#define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff)) + /* marshalling */ #pragma warning(push) #pragma warning(disable:4200) /* zero-sized array in struct/union */ @@ -222,7 +225,7 @@ typedef struct UINT32 FileAttributes; /* file attributes for new files */ FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */ UINT64 AllocationSize; /* initial allocation size */ - UINT64 AccessToken; /* request access token (HANDLE) */ + UINT64 AccessToken; /* request access token (PID,HANDLE) */ UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ @@ -315,7 +318,7 @@ typedef struct struct { FSP_FSCTL_TRANSACT_BUF NewFileName; - UINT64 AccessToken; /* request access token (HANDLE) */ + UINT64 AccessToken; /* request access token (PID,HANDLE) */ } Rename; } Info; } SetInformation; diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index dc98bd3b..b2c97a57 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1065,6 +1065,23 @@ BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID) FspFsctlTransactCreateKind == Request->Kind && Request->Req.Create.CaseSensitive || FspFsctlTransactQueryDirectoryKind == Request->Kind && Request->Req.QueryDirectory.CaseSensitive; } +FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID); +static inline +UINT32 FspFileSystemOperationProcessId(VOID) +{ + FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request; + switch (Request->Kind) + { + case FspFsctlTransactCreateKind: + return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken); + case FspFsctlTransactSetInformationKind: + if (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) + return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken); + /* fall through! */ + default: + return 0; + } +} /* * Operations diff --git a/src/dll/debug.c b/src/dll/debug.c index 21a02914..ff8c98f5 100644 --- a/src/dll/debug.c +++ b/src/dll/debug.c @@ -302,7 +302,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request) FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c%c%c] \"%S\", " "%s, CreateOptions=%lx, FileAttributes=%lx, Security=%s%s%s, " "AllocationSize=%lx:%lx, " - "AccessToken=%p, DesiredAccess=%lx, GrantedAccess=%lx, " + "AccessToken=%p[PID=%lx], DesiredAccess=%lx, GrantedAccess=%lx, " "ShareAccess=%lx\n", FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint, Request->Req.Create.UserMode ? 'U' : 'K', @@ -319,7 +319,8 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request) Sddl ? Sddl : "NULL", Sddl ? "\"" : "", MAKE_UINT32_PAIR(Request->Req.Create.AllocationSize), - (PVOID)Request->Req.Create.AccessToken, + FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken), + FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken), Request->Req.Create.DesiredAccess, Request->Req.Create.GrantedAccess, Request->Req.Create.ShareAccess); @@ -459,7 +460,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request) break; case 10/*FileRenameInformation*/: FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [Rename] %s%S%s%s, " - "NewFileName=\"%S\", AccessToken=%p\n", + "NewFileName=\"%S\", AccessToken=%p[PID=%lx]\n", FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint, Request->FileName.Size ? "\"" : "", Request->FileName.Size ? (PWSTR)Request->Buffer : L"", @@ -468,7 +469,8 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request) Request->Req.SetInformation.UserContext, Request->Req.SetInformation.UserContext2, UserContextBuf), (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset), - (PVOID)Request->Req.SetInformation.Info.Rename.AccessToken); + FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.SetInformation.Info.Rename.AccessToken), + FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken)); break; default: FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [INVALID] %s%S%s%s\n", diff --git a/src/dll/fs.c b/src/dll/fs.c index 5aca3047..66d7e634 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -683,3 +683,8 @@ FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID) { return FspFileSystemIsOperationCaseSensitive(); } + +FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID) +{ + return FspFileSystemOperationProcessId(); +} diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index 50039b0d..6b3e90b0 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -283,6 +283,7 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) context->private_data = f->data; context->uid = -1; context->gid = -1; + context->pid = -1; memset(&conn, 0, sizeof conn); conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */ @@ -737,7 +738,6 @@ FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *env) return 0; context = FSP_FUSE_CONTEXT_FROM_HDR(contexthdr); - context->pid = -1; TlsSetValue(fsp_fuse_tlskey, context); } diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 88679dff..77b83ee9 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -112,7 +112,7 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem, struct fuse_context *context; struct fsp_fuse_context_header *contexthdr; char *PosixPath = 0; - UINT32 Uid = -1, Gid = -1; + UINT32 Uid = -1, Gid = -1, Pid = -1; PWSTR FileName = 0, Suffix; WCHAR Root[2] = L"\\"; HANDLE Token = 0; @@ -124,13 +124,15 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem, FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root); else FileName = (PWSTR)Request->Buffer; - Token = (HANDLE)Request->Req.Create.AccessToken; + Token = FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken); + Pid = FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken); } else if (FspFsctlTransactSetInformationKind == Request->Kind && 10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) { FileName = (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset); - Token = (HANDLE)Request->Req.SetInformation.Info.Rename.AccessToken; + Token = FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.SetInformation.Info.Rename.AccessToken); + Pid = FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken); } if (0 != FileName) @@ -162,6 +164,7 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem, context->private_data = f->data; context->uid = Uid; context->gid = Gid; + context->pid = Pid; contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context); contexthdr->PosixPath = PosixPath; @@ -189,6 +192,7 @@ NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem, context->private_data = 0; context->uid = -1; context->gid = -1; + context->pid = -1; contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context); if (0 != contexthdr->PosixPath) diff --git a/src/dll/security.c b/src/dll/security.c index 515098ca..2caf3cbc 100644 --- a/src/dll/security.c +++ b/src/dll/security.c @@ -172,8 +172,12 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, if (0 < SecurityDescriptorSize) { - if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE, - &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, &TraverseAccess, &AccessStatus)) + if (AccessCheck(SecurityDescriptor, + FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken), + FILE_TRAVERSE, + &FspFileGenericMapping, + PrivilegeSet, &PrivilegeSetLength, + &TraverseAccess, &AccessStatus)) Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; else Result = FspNtStatusFromWin32(GetLastError()); @@ -202,8 +206,12 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, { if (0 == DesiredAccess) Result = STATUS_SUCCESS; - else if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess, - &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus)) + else if (AccessCheck(SecurityDescriptor, + FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken), + DesiredAccess, + &FspFileGenericMapping, + PrivilegeSet, &PrivilegeSetLength, + PGrantedAccess, &AccessStatus)) Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; else Result = FspNtStatusFromWin32(GetLastError()); @@ -244,8 +252,12 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, ((FILE_LIST_DIRECTORY & ParentAccess) ? FILE_READ_ATTRIBUTES : 0)); if (0 != DesiredAccess2) { - if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess2, - &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus)) + if (AccessCheck(SecurityDescriptor, + FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken), + DesiredAccess2, + &FspFileGenericMapping, + PrivilegeSet, &PrivilegeSetLength, + PGrantedAccess, &AccessStatus)) Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; else /* any failure just becomes ACCESS DENIED at this point */ @@ -396,7 +408,7 @@ FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem, (PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0, PSecurityDescriptor, 0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE), - (HANDLE)Request->Req.Create.AccessToken, + FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken), &FspFileGenericMapping)) return FspNtStatusFromWin32(GetLastError());