From f4496786e5b6be3e3e0b42f1dcc5754110b3d717 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 18 Jun 2019 16:49:20 -0700 Subject: [PATCH] src: ku: posix.c - src/ku directory contains shared kernel/user mode code --- build/VStudio/winfsp_dll.vcxproj | 3 +- build/VStudio/winfsp_dll.vcxproj.filters | 12 +- build/VStudio/winfsp_sys.vcxproj | 2 + build/VStudio/winfsp_sys.vcxproj.filters | 9 + opt/fsext/inc/winfsp/fsext.h | 39 +++- opt/fsext/lib/winfsp-x64.lib | Bin 2270 -> 4336 bytes opt/fsext/lib/winfsp-x86.lib | Bin 2312 -> 4512 bytes src/ku/library.h | 222 +++++++++++++++++++++++ src/{dll => ku}/posix.c | 202 +++++++++++++++++---- src/sys/driver.h | 2 + src/sys/util.c | 34 ++++ 11 files changed, 479 insertions(+), 46 deletions(-) create mode 100644 src/ku/library.h rename src/{dll => ku}/posix.c (85%) diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index ed328627..01207f5b 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -35,6 +35,7 @@ + @@ -51,7 +52,6 @@ - @@ -63,6 +63,7 @@ + diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters index 3340618e..cac6502a 100644 --- a/build/VStudio/winfsp_dll.vcxproj.filters +++ b/build/VStudio/winfsp_dll.vcxproj.filters @@ -27,6 +27,9 @@ {96091a7b-3923-4a74-9491-3ee230c688f9} + + {613cce77-2428-4f9a-9187-f37e009253c1} + @@ -77,6 +80,9 @@ Source\fuse3 + + Source\ku + @@ -124,9 +130,6 @@ Source\fuse - - Source - Source\fuse @@ -154,6 +157,9 @@ Source\fuse3 + + Source\ku + diff --git a/build/VStudio/winfsp_sys.vcxproj b/build/VStudio/winfsp_sys.vcxproj index 2f04da2c..e341f18d 100644 --- a/build/VStudio/winfsp_sys.vcxproj +++ b/build/VStudio/winfsp_sys.vcxproj @@ -155,6 +155,7 @@ + @@ -190,6 +191,7 @@ + diff --git a/build/VStudio/winfsp_sys.vcxproj.filters b/build/VStudio/winfsp_sys.vcxproj.filters index 866dfa01..a6d6528e 100644 --- a/build/VStudio/winfsp_sys.vcxproj.filters +++ b/build/VStudio/winfsp_sys.vcxproj.filters @@ -12,6 +12,9 @@ {904f0df1-2fb8-4f84-aa46-fa929488c39a} + + {235076b8-290c-4dec-b005-71d9b8e8cba7} + @@ -107,6 +110,9 @@ Source + + Source\ku + @@ -118,6 +124,9 @@ Include\winfsp + + Source\ku + diff --git a/opt/fsext/inc/winfsp/fsext.h b/opt/fsext/inc/winfsp/fsext.h index e16b18b8..5344795d 100644 --- a/opt/fsext/inc/winfsp/fsext.h +++ b/opt/fsext/inc/winfsp/fsext.h @@ -51,10 +51,43 @@ typedef struct UINT32 DeviceExtensionOffset; } FSP_FSEXT_PROVIDER; -FSP_DDI_DEF(NTSTATUS, FspFsextProviderRegister, FSP_FSEXT_PROVIDER *Provider) +FSP_DDI_DEF(NTSTATUS, FspFsextProviderRegister, + FSP_FSEXT_PROVIDER *Provider) -FSP_DDI_DEF(NTSTATUS, FspPosixMapSidToUid, PSID Sid, PUINT32 PUid) -FSP_DDI_DEF(NTSTATUS, FspPosixMapWindowsToPosixPathEx, PWSTR WindowsPath, char **PPosixPath, +FSP_DDI_DEF(NTSTATUS, FspPosixMapUidToSid, + UINT32 Uid, + PSID *PSid) +FSP_DDI_DEF(NTSTATUS, FspPosixMapSidToUid, + PSID Sid, + PUINT32 PUid) +FSP_DDI_DEF(VOID, FspDeleteSid, + PSID Sid, + NTSTATUS (*CreateFunc)()) +FSP_DDI_DEF(NTSTATUS, FspPosixMapPermissionsToSecurityDescriptor, + UINT32 Uid, + UINT32 Gid, + UINT32 Mode, + PSECURITY_DESCRIPTOR *PSecurityDescriptor) +FSP_DDI_DEF(NTSTATUS, FspPosixMapSecurityDescriptorToPermissions, + PSECURITY_DESCRIPTOR SecurityDescriptor, + PUINT32 PUid, + PUINT32 PGid, + PUINT32 PMode) +FSP_DDI_DEF(NTSTATUS, FspPosixMapWindowsToPosixPathEx, + PWSTR WindowsPath, + char **PPosixPath, BOOLEAN Translate) +FSP_DDI_DEF(NTSTATUS, FspPosixMapPosixToWindowsPathEx, + const char *PosixPath, + PWSTR *PWindowsPath, + BOOLEAN Translate) +FSP_DDI_DEF(VOID, FspPosixDeletePath, + void *Path) +FSP_DDI_DEF(VOID, FspPosixEncodeWindowsPath, + PWSTR WindowsPath, + ULONG Size) +FSP_DDI_DEF(VOID, FspPosixDecodeWindowsPath, + PWSTR WindowsPath, + ULONG Size) #endif diff --git a/opt/fsext/lib/winfsp-x64.lib b/opt/fsext/lib/winfsp-x64.lib index a471199d23338a318208572c7668bc324921c365..a1192e27671e614332e8b3dfe0e1a5e8d15ea173 100644 GIT binary patch literal 4336 zcmcInNl)8A6ngeq5+ZsQiVbr5Qr@bK}eNKNMi$*N*u+efeXEH z>IotE1N{Y@dgKT6&_l(k2YyNE8{6Xg1kgFSN4N9fOmHBzM9KIR~ zhPXJhvN%`DO%^9%TCGj1(yo@TD_>+$su!e9S=FREjwEl_N=?Nm$SbP6yHKvJ$YN1h zmPKabl5pCnSX9u&t!+tAJ12dXG|4t7V{xP9rTVt4s{YocDh>2m_bXr4wx)L71A1z4qv*y(#Z+rHil-JG z#fT~~b-;51sykJ!D5AunIZWJgYMGN-Te{^}uER8|Lo6hC-UTod0occ?oWLpz#{rJ| z0M2``f>0rbeGPes*dOQxI7T`}JuG18f-uA&3cb(`JrIFT=l}r%5Nsj|kt(vKr*}y; zj|P*FwAWXIvYH1KOOH!O&-AB*5LHsG&RpT-?XsO$r6tVqtWAL9d8Y4mHZN;0VnMc8 z-l4X{`n28Y<&;}tw+r0Cx66Gjf!n}qAzWJRmcwm87sVy9mc}LVT%cwrMMFPf2Gu>) zsLggKV``k9k?VqZ5P}bl$VVXnSX0I`C`zApHv5;&Psn2D8~rfbEX3ap%3@h7_YYIi zeeC>1x-c0bY_pI&Gxahi8|xR~FVY2NV4H=+SrFShSk>ea*rZ;Twd}P zs0zflAkZ0S0d#M-C`X^0fn(~Vhz=TorIThH!hcF$=0ipY7&E^}6NEgzuTzq@l_kTe zaqIph9t8C)`JsD8`~&dH644M@Z!SwlD3fH#clu$rBuoCs>ib#K$LK@T%Ndu3{%UJ@ zjGcD0w*DZ3vBKU_Yf)Qi8Yohmq_+4c3t3uQDat2$zv+kB6204wuAj(0Lj2pxM(Z-4 zAh&r^pW*@8w;t$o4BO9nuB=(t-}}|KjH*%|G-1k`&?r{+^*sibCmwU*fC!q zX3)TFa#(VpSI*QlJp>#PeS)YV8>)2#b8xJC^Erk&H21mAkoZHvAL=MAM#mh-!qL=yZ7Dbp>H~w;KU+o8~Ts?JhQ)8?5Uu0_h>|2#_3S1i};7^iS4d<(zzqO%O_E$E zUVuF>z=9PE7HC$82N)q1ELrd*1LxSj^|fQWjwn~UzJKT3@7(iuudl9mt=_@y{LMnJ zl&ZDjTCr4FDF^3^-f*q7>h<>W0Dc4}-vGH!z|tJR0j_he z-MUZ!xXzW`I`bCbI$Lz>OoPS^P21dR-D`KW`o_*5?afx_URyghjvm?rXxjE}vpKqs ze_R50x%21l_Fb)hr*j8d!yYtj{bbm(%qK=)x7zw6!yf9ETA|I1!-1AaLEJ6VHcqy> zgI%NFF?Woiee;;k;Apbd9Ug3)sHJj*@UfKA zZq6nh(<4pVEtXR3<|>}I2zZLa7hDq@8%I5}uS?jYR*xhR{B`|I{wR{MBf9KI^elz+ zn@QkP4p^K5-cJLs=7Dvp`_z9)1h40S!U9mH_U#N%q`3yQlnOA33Cv;|Gq{8)N9@JqoCKmAOQIRm^F!h9AcWG4 zw0W%ekLJQNbETj60+u*C8=g{lQINu4W!nVVBP|ppNol81rZ{VjP^PijC{t2aPrN4L ztQdED9Xq$)vi;O{qx`Jfy0Rwj?Y(?c$zty~_g7v4MW<7g<-WfE_|f$pcL=D|c_s#4 zt7885WuxC6cCXVd?Uu{b{73b(J4BXR6~%WRUCo=OOaS~(^|P3uRz=}mhS~+n4_xy8 zp>E)ZdCES{cD%&t==p=iEu&|dw)t>aSZe=TXl`!b<;8GeES7^e0OcX>QQD#m#62H` zB<5O0BKbB(1rz^^p)<3rA}$A-1YQQS65tTXKV3?Rjc9 zjYh8!?z!cv6;GW7{G4fLIy1t@mhj=F8zh}1wHSZCNs?R)OA_-yk>JP9Pf42KcRKsHcx0w{_DG`m-E^9$ rR-(P{8foHESQ7s&<-?4v`y|9%2vK^VeFI{Wweumw`!WBx5`6wE-cXgx delta 413 zcmYjN%}#?r7#yImKp_QfDWMW+;b}et_-aB zA!mT20x1X2f)->b5Fl1NiG0(iE9O?FH#AYklnEWWWp-gsIh)k)JC%kHt(PD6CDfcl zhHjO7ptC05J6kUP{~{42@Vj^KG}Hs~)B$bUpUok^Mpr8YW1bQ;FfW_U536ew%@OYj bJUUO@r=A_`HEXj^_npIXz?5r5dbHy|obgiW diff --git a/src/ku/library.h b/src/ku/library.h new file mode 100644 index 00000000..1a95a94d --- /dev/null +++ b/src/ku/library.h @@ -0,0 +1,222 @@ +/** + * @file ku/library.h + * + * @copyright 2015-2019 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef WINFSP_KU_LIBRARY_H_INCLUDED +#define WINFSP_KU_LIBRARY_H_INCLUDED + +#if !defined(_KERNEL_MODE) + +#include +#include +#define _NTDEF_ +#include + +#define FSP_KU_CODE ((void)0) + +#else + +#include + +#define FSP_KU_CODE PAGED_CODE(); NTSTATUS fsp_ku_status = STATUS_SUCCESS; (VOID)fsp_ku_status + +#define FSP_API FSP_DDI + +#define BYTE UINT8 +#define BOOL BOOLEAN +#define LPBOOL PBOOLEAN +#define UINT ULONG + +#define GetLastError() ((DWORD)fsp_ku_status) +#define FspNtStatusFromWin32(Err) ((NTSTATUS)(Err)) +#define ERROR_INSUFFICIENT_BUFFER STATUS_BUFFER_TOO_SMALL + +#define InitOnceExecuteOnce(I, F, P, C) RtlRunOnceExecuteOnce(I, F, P, C) +#define INIT_ONCE RTL_RUN_ONCE +#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT + +#define AddAccessAllowedAce(Acl, Rev, Acc, Sid)\ + (fsp_ku_status = RtlAddAccessAllowedAce(Acl, Rev, Acc, Sid),\ + NT_SUCCESS(fsp_ku_status)) +#define AddAccessDeniedAce(Acl, Rev, Acc, Sid)\ + (fsp_ku_status = FspKuAddAccessDeniedAce(Acl, Rev, Acc, Sid),\ + NT_SUCCESS(fsp_ku_status)) +#define EqualSid(Sid1, Sid2) (fsp_ku_status = 0, RtlEqualSid(Sid1, Sid2)) +#define GetAce(Acl, Idx, Ace) (fsp_ku_status = RtlGetAce(Acl, Idx, Ace), NT_SUCCESS(fsp_ku_status)) +#define GetAclInformation(Acl, Inf, Len, Cls)\ + (fsp_ku_status = FspKuQueryInformationAcl(Acl, Inf, Len, Cls),\ + NT_SUCCESS(fsp_ku_status)) +#define GetLengthSid(Sid) (fsp_ku_status = 0, RtlLengthSid(Sid)) +#define GetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\ + (fsp_ku_status = RtlGetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\ + NT_SUCCESS(fsp_ku_status)) +#define GetSecurityDescriptorGroup(Sec, Grp, Def)\ + (fsp_ku_status = RtlGetGroupSecurityDescriptor(Sec, Grp, Def),\ + NT_SUCCESS(fsp_ku_status)) +#define GetSecurityDescriptorOwner(Sec, Own, Def)\ + (fsp_ku_status = RtlGetOwnerSecurityDescriptor(Sec, Own, Def),\ + NT_SUCCESS(fsp_ku_status)) +#define GetSidIdentifierAuthority(Sid) (fsp_ku_status = 0, &((PISID)(Sid))->IdentifierAuthority) +#define GetSidSubAuthority(Sid, Sub) (fsp_ku_status = 0, RtlSubAuthoritySid(Sid, Sub)) +#define GetSidSubAuthorityCount(Sid) (fsp_ku_status = 0, RtlSubAuthorityCountSid(Sid)) +#define InitializeAcl(Acl, Len, Rev) (fsp_ku_status = RtlCreateAcl(Acl, Len, Rev), NT_SUCCESS(fsp_ku_status)) +#define InitializeSecurityDescriptor(Sec, Rev)\ + (fsp_ku_status = RtlCreateSecurityDescriptor(Sec, Rev),\ + NT_SUCCESS(fsp_ku_status)) +#define InitializeSid(Sid, Aut, Cnt) (fsp_ku_status = RtlInitializeSid(Sid, Aut, Cnt), NT_SUCCESS(fsp_ku_status)) +#define IsValidSid(Sid) (RtlValidSid(Sid) || (fsp_ku_status = STATUS_INVALID_SID, FALSE)) +#define MakeSelfRelativeSD(Abs, Rel, Len)\ + (fsp_ku_status = RtlAbsoluteToSelfRelativeSD(Abs, Rel, Len),\ + NT_SUCCESS(fsp_ku_status)) +#define SetSecurityDescriptorControl(Sec, Msk, Bit)\ + (fsp_ku_status = FspKuSetControlSecurityDescriptor(Sec, Msk, Bit),\ + NT_SUCCESS(fsp_ku_status)) +#define SetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\ + (fsp_ku_status = RtlSetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\ + NT_SUCCESS(fsp_ku_status)) +#define SetSecurityDescriptorGroup(Sec, Grp, Def)\ + (fsp_ku_status = RtlSetGroupSecurityDescriptor(Sec, Grp, Def),\ + NT_SUCCESS(fsp_ku_status)) +#define SetSecurityDescriptorOwner(Sec, Own, Def)\ + (fsp_ku_status = RtlSetOwnerSecurityDescriptor(Sec, Own, Def),\ + NT_SUCCESS(fsp_ku_status)) +static inline NTSTATUS FspKuAddAccessDeniedAce( + PACL Acl, + ULONG AceRevision, + ACCESS_MASK AccessMask, + PSID Sid) +{ + /* We are missing RtlAddAccessDeniedAce. So we need this malarkey! */ + NTSTATUS Result; + PACE_HEADER Ace; + Result = RtlAddAccessAllowedAce(Acl, AceRevision, AccessMask, Sid); + if (!NT_SUCCESS(Result)) + return Result; + Result = RtlGetAce(Acl, Acl->AceCount - 1, &Ace); + if (!NT_SUCCESS(Result)) + return Result; + Ace->AceType = ACCESS_DENIED_ACE_TYPE; + return STATUS_SUCCESS; +} +typedef enum +{ + AclRevisionInformation__DO_NOT_USE = 1, + AclSizeInformation, +} ACL_INFORMATION_CLASS; +typedef struct +{ + DWORD AceCount; + DWORD AclBytesInUse__DO_NOT_USE; + DWORD AclBytesFree__DO_NOT_USE; +} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION; +static inline NTSTATUS FspKuQueryInformationAcl( + PACL Acl, + PVOID AclInformation, + ULONG AclInformationLength, + ACL_INFORMATION_CLASS AclInformationClass) +{ + ASSERT(AclSizeInformation == AclInformationClass); + ASSERT(sizeof(ACL_SIZE_INFORMATION) <= AclInformationLength); + ((PACL_SIZE_INFORMATION)AclInformation)->AceCount = Acl->AceCount; + return STATUS_SUCCESS; +} +static inline NTSTATUS FspKuSetControlSecurityDescriptor( + PSECURITY_DESCRIPTOR SecurityDescriptor, + SECURITY_DESCRIPTOR_CONTROL ControlMask, + SECURITY_DESCRIPTOR_CONTROL ControlBits) +{ + ((PUSHORT)(SecurityDescriptor))[1] &= ~ControlMask; + ((PUSHORT)(SecurityDescriptor))[1] |= ControlBits; + return STATUS_SUCCESS; +} + +#define WideCharToMultiByte(C, F, W, w, B, b, D, d)\ + (FspKuWideCharToMultiByte(C, F, W, w, B, b, D, d, &fsp_ku_status)) +#define MultiByteToWideChar(C, F, B, b, W, w)\ + (FspKuMultiByteToWideChar(C, F, B, b, W, w, &fsp_ku_status)) +#define CP_UTF8 65001 +static inline int FspKuWideCharToMultiByte( + UINT CodePage, + DWORD dwFlags, + LPCWCH lpWideCharStr, + int cchWideChar, + LPSTR lpMultiByteStr, + int cbMultiByte, + LPCCH lpDefaultChar, + LPBOOL lpUsedDefaultChar, + PNTSTATUS PResult) +{ + ASSERT(CP_UTF8 == CodePage); + ASSERT(0 == dwFlags); + ASSERT(0 == lpDefaultChar); + ASSERT(0 == lpUsedDefaultChar); + NTSTATUS Result; + ULONG ByteCount; + if (-1 == cchWideChar) + cchWideChar = (int)wcslen(lpWideCharStr); + Result = RtlUnicodeToUTF8N( + lpMultiByteStr, cbMultiByte, &ByteCount, + lpWideCharStr, cchWideChar * sizeof(WCHAR)); + if (STATUS_SOME_NOT_MAPPED == Result) + Result = STATUS_SUCCESS; + else if (!NT_SUCCESS(Result)) + return 0; + *PResult = Result; + return ByteCount; +} +static inline int FspKuMultiByteToWideChar( + UINT CodePage, + DWORD dwFlags, + LPCCH lpMultiByteStr, + int cbMultiByte, + LPWSTR lpWideCharStr, + int cchWideChar, + PNTSTATUS PResult) +{ + ASSERT(CP_UTF8 == CodePage); + ASSERT(0 == dwFlags); + NTSTATUS Result; + ULONG ByteCount; + if (-1 == cbMultiByte) + cbMultiByte = (int)strlen(lpMultiByteStr); + Result = RtlUTF8ToUnicodeN( + lpWideCharStr, cchWideChar * sizeof(WCHAR), &ByteCount, + lpMultiByteStr, cbMultiByte); + if (STATUS_SOME_NOT_MAPPED == Result) + Result = STATUS_SUCCESS; + else if (!NT_SUCCESS(Result)) + return 0; + *PResult = Result; + return ByteCount / sizeof(WCHAR); +} + +static inline void *MemAlloc(size_t Size) +{ + return FspAlloc(Size); +} +static inline void MemFree(void *Pointer) +{ + if (0 != Pointer) + FspFree(Pointer); +} + +#endif + +#endif diff --git a/src/dll/posix.c b/src/ku/posix.c similarity index 85% rename from src/dll/posix.c rename to src/ku/posix.c index f7a58f85..6322ff42 100644 --- a/src/dll/posix.c +++ b/src/ku/posix.c @@ -1,5 +1,5 @@ /** - * @file dll/posix.c + * @file ku/posix.c * POSIX Interop. * * This file provides routines for Windows/POSIX interoperability. It is based @@ -32,15 +32,67 @@ * associated repository. */ -#include -#include -#define _NTDEF_ -#include +#include +FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid); +FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid); static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...); +FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()); +FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( + UINT32 Uid, UINT32 Gid, UINT32 Mode, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( + PSECURITY_DESCRIPTOR SecurityDescriptor, + PUINT32 PUid, PUINT32 PGid, PUINT32 PMode); +FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, + BOOLEAN Translate); +FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, + BOOLEAN Translate); +FSP_API VOID FspPosixDeletePath(void *Path); +FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size); +FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size); -static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT; -union +#if defined(_KERNEL_MODE) +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, FspPosixMapUidToSid) +#pragma alloc_text(PAGE, FspPosixMapSidToUid) +#pragma alloc_text(PAGE, FspPosixCreateSid) +#pragma alloc_text(PAGE, FspDeleteSid) +#pragma alloc_text(PAGE, FspPosixMapPermissionsToSecurityDescriptor) +#pragma alloc_text(PAGE, FspPosixMapSecurityDescriptorToPermissions) +#pragma alloc_text(PAGE, FspPosixMapWindowsToPosixPathEx) +#pragma alloc_text(PAGE, FspPosixMapPosixToWindowsPathEx) +#pragma alloc_text(PAGE, FspPosixDeletePath) +#pragma alloc_text(PAGE, FspPosixEncodeWindowsPath) +#pragma alloc_text(PAGE, FspPosixDecodeWindowsPath) +#endif +#endif + +static union +{ + SID V; + UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))]; +} FspWorldSidBuf = +{ + /* S-1-1-0 */ + .V.Revision = SID_REVISION, + .V.SubAuthorityCount = 1, + .V.IdentifierAuthority.Value[5] = 1, + .V.SubAuthority[0] = 0, +}; +static union +{ + SID V; + UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))]; +} FspAuthUsersSidBuf = +{ + /* S-1-5-11 */ + .V.Revision = SID_REVISION, + .V.SubAuthorityCount = 1, + .V.IdentifierAuthority.Value[5] = 5, + .V.SubAuthority[0] = 11, +}; +static union { SID V; UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))]; @@ -52,11 +104,15 @@ union .V.IdentifierAuthority.Value[5] = 0, .V.SubAuthority[0] = 65534, }; -static PISID FspAccountDomainSid, FspPrimaryDomainSid; +#define FspWorldSid (&FspWorldSidBuf.V) +#define FspAuthUsersSid (&FspAuthUsersSidBuf.V) #define FspUnmappedSid (&FspUnmappedSidBuf.V) #define FspUnmappedUid (65534) +static PISID FspAccountDomainSid, FspPrimaryDomainSid; +static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT; +#if !defined(_KERNEL_MODE) static BOOL WINAPI FspPosixInitialize( PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) { @@ -120,9 +176,79 @@ VOID FspPosixFinalize(BOOLEAN Dynamic) MemFree(FspPrimaryDomainSid); } } +#else +ULONG NTAPI FspPosixInitialize( + PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID *Context) +{ + static union + { + SID V; + UINT8 B[SECURITY_MAX_SID_SIZE]; + } FspAccountDomainSidBuf; + static union + { + SID V; + UINT8 B[SECURITY_MAX_SID_SIZE]; + } FspPrimaryDomainSidBuf; + UNICODE_STRING Path; + UNICODE_STRING Name; + union + { + KEY_VALUE_PARTIAL_INFORMATION V; + UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + SECURITY_MAX_SID_SIZE]; + } Value; + ULONG Length; + NTSTATUS Result; + + RtlInitUnicodeString(&Path, L"\\Machine\\SECURITY\\Policy\\PolAcDmS"); + RtlZeroMemory(&Name, sizeof Name); + Length = sizeof Value; + Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length); + if (STATUS_SUCCESS == Result /*!NT_SUCCESS*/ && REG_NONE == Value.V.Type && + sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data)) + { + RtlCopyMemory(&FspAccountDomainSidBuf.V, &Value.V.Data, Value.V.DataLength); + FspAccountDomainSid = &FspAccountDomainSidBuf.V; + } + + RtlInitUnicodeString(&Path, L"\\Machine\\SECURITY\\Policy\\PolPrDmS"); + RtlZeroMemory(&Name, sizeof Name); + Length = sizeof Value; + Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length); + if (STATUS_SUCCESS == Result /*!NT_SUCCESS*/ && REG_NONE == Value.V.Type && + sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data)) + { + RtlCopyMemory(&FspPrimaryDomainSidBuf.V, &Value.V.Data, Value.V.DataLength); + FspPrimaryDomainSid = &FspPrimaryDomainSidBuf.V; + } + + return TRUE; +} +#endif + +static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2) +{ + if (Sid1->Revision != Sid2->Revision) + return FALSE; + if (Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0] || + Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1] || + Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2] || + Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3] || + Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4] || + Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5]) + return FALSE; + if (Sid1->SubAuthorityCount + 1 != Sid2->SubAuthorityCount) + return FALSE; + for (ULONG I = 0; Sid1->SubAuthorityCount > I; I++) + if (Sid1->SubAuthority[I] != Sid2->SubAuthority[I]) + return FALSE; + return TRUE; +} FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) { + FSP_KU_CODE; + InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0); *PSid = 0; @@ -221,7 +347,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) * S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y */ else if (0x10000 <= Uid && Uid < 0x11000) - *PSid = FspPosixCreateSid((Uid - 0x10000) >> 8, 1, (Uid - 0x10000) & 0xff); + *PSid = FspPosixCreateSid((BYTE)((Uid - 0x10000) >> 8), 1, (Uid - 0x10000) & 0xff); /* [IDMAP] * Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID): @@ -238,13 +364,15 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid) { + FSP_KU_CODE; + InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0); BYTE Authority; BYTE Count; UINT32 SubAuthority0, Rid; - *PUid = -1; + *PUid = (UINT32)-1; if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid))) return STATUS_INVALID_SID; @@ -298,12 +426,11 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid) * has PrimaryDomainSid == AccountDomainSid. */ - BOOL EqualDomains = FALSE; if (0 != FspPrimaryDomainSid && - EqualDomainSid(FspPrimaryDomainSid, Sid, &EqualDomains) && EqualDomains) + FspPosixIsRelativeSid(FspPrimaryDomainSid, Sid)) *PUid = 0x100000 + Rid; else if (0 != FspAccountDomainSid && - EqualDomainSid(FspAccountDomainSid, Sid, &EqualDomains) && EqualDomains) + FspPosixIsRelativeSid(FspAccountDomainSid, Sid)) *PUid = 0x30000 + Rid; /* @@ -348,6 +475,8 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid) static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...) { + FSP_KU_CODE; + PISID Sid; SID_IDENTIFIER_AUTHORITY IdentifierAuthority; va_list ap; @@ -370,6 +499,8 @@ static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...) FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()) { + FSP_KU_CODE; + if (FspUnmappedSid == Sid) ; else if ((NTSTATUS (*)())FspPosixMapUidToSid == CreateFunc) @@ -439,7 +570,9 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( UINT32 Uid, UINT32 Gid, UINT32 Mode, PSECURITY_DESCRIPTOR *PSecurityDescriptor) { - PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0; + FSP_KU_CODE; + + PSID OwnerSid = 0, GroupSid = 0; UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm; PACL Acl = 0; SECURITY_DESCRIPTOR SecurityDescriptor; @@ -457,13 +590,6 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( if (!NT_SUCCESS(Result)) goto exit; - WorldSid = FspWksidGet(WinWorldSid); - if (0 == WorldSid) - { - Result = STATUS_INSUFFICIENT_RESOURCES; - goto exit; - } - OwnerPerm = (Mode & 0700) >> 6; GroupPerm = (Mode & 0070) >> 3; WorldPerm = (Mode & 0007); @@ -502,7 +628,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny); Size += GetLengthSid(OwnerSid) - sizeof(DWORD); Size += GetLengthSid(GroupSid) - sizeof(DWORD); - Size += GetLengthSid(WorldSid) - sizeof(DWORD); + Size += GetLengthSid(FspWorldSid) - sizeof(DWORD); if (OwnerDeny) Size += GetLengthSid(OwnerSid) - sizeof(DWORD); if (GroupDeny) @@ -546,7 +672,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( if (!AddAccessAllowedAce(Acl, ACL_REVISION, FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm), - WorldSid)) + FspWorldSid)) goto lasterror; if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) @@ -621,7 +747,9 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( PSECURITY_DESCRIPTOR SecurityDescriptor, PUINT32 PUid, PUINT32 PGid, PUINT32 PMode) { - PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0, AuthUsersSid = 0; + FSP_KU_CODE; + + PSID OwnerSid = 0, GroupSid = 0; BOOL Defaulted, DaclPresent; PACL Acl = 0; ACL_SIZE_INFORMATION AclSizeInfo; @@ -653,20 +781,6 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( if (0 != Acl) { - WorldSid = FspWksidGet(WinWorldSid); - if (0 == WorldSid) - { - Result = STATUS_INSUFFICIENT_RESOURCES; - goto exit; - } - - AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid); - if (0 == AuthUsersSid) - { - Result = STATUS_INSUFFICIENT_RESOURCES; - goto exit; - } - OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0; if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation)) @@ -701,7 +815,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( * add the allowed or denied access right bits into the "owner", "group" * and "other" collections. */ - if (EqualSid(WorldSid, AceSid) || EqualSid(AuthUsersSid, AceSid)) + if (EqualSid(FspWorldSid, AceSid) || EqualSid(FspAuthUsersSid, AceSid)) { /* [PERMS] * If this is an access-denied ACE, then add each access right to the set @@ -812,6 +926,8 @@ static UINT32 FspPosixInvalidPathChars[4] = FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, BOOLEAN Translate) { + FSP_KU_CODE; + NTSTATUS Result; ULONG Size; char *PosixPath = 0, *p, *q; @@ -874,6 +990,8 @@ lasterror: FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, BOOLEAN Translate) { + FSP_KU_CODE; + NTSTATUS Result; ULONG Size; PWSTR WindowsPath = 0, p; @@ -925,11 +1043,15 @@ lasterror: FSP_API VOID FspPosixDeletePath(void *Path) { + FSP_KU_CODE; + MemFree(Path); } FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size) { + FSP_KU_CODE; + for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++) { WCHAR c = *p; @@ -944,6 +1066,8 @@ FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size) FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size) { + FSP_KU_CODE; + for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++) { WCHAR c = *p; diff --git a/src/sys/driver.h b/src/sys/driver.h index 1e7c4897..b242d417 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -493,6 +493,8 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); +NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName, + PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength); NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, diff --git a/src/sys/util.c b/src/sys/util.c index a99c42c8..92ddcc04 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -24,6 +24,8 @@ NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); +NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName, + PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength); NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, @@ -130,6 +132,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, FspCreateGuid) #pragma alloc_text(PAGE, FspGetDeviceObjectPointer) +#pragma alloc_text(PAGE, FspRegistryGetValue) #pragma alloc_text(PAGE, FspSendSetInformationIrp) #pragma alloc_text(PAGE, FspSendQuerySecurityIrp) #pragma alloc_text(PAGE, FspSendQueryEaIrp) @@ -280,6 +283,37 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir return Result; } +NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName, + PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength) +{ + PAGED_CODE(); + + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle = 0; + NTSTATUS Result; + + InitializeObjectAttributes(&ObjectAttributes, + Path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); + + Result = ZwOpenKey(&Handle, KEY_QUERY_VALUE, &ObjectAttributes); + if (!NT_SUCCESS(Result)) + goto exit; + + Result = ZwQueryValueKey(Handle, ValueName, + KeyValuePartialInformation, ValueInformation, + *PValueInformationLength, PValueInformationLength); + if (!NT_SUCCESS(Result)) + goto exit; + + Result = STATUS_SUCCESS; + +exit: + if (0 != Handle) + ZwClose(Handle); + + return Result; +} + typedef struct { IO_STATUS_BLOCK IoStatus;