Index: src/shared/Communication.cpp |
=================================================================== |
--- a/src/shared/Communication.cpp |
+++ b/src/shared/Communication.cpp |
@@ -73,8 +73,6 @@ |
explicitAccess[0].Trustee.TrusteeType = TRUSTEE_IS_USER; |
explicitAccess[0].Trustee.ptstrName = static_cast<LPWSTR>(logonSid); |
- std::tr1::shared_ptr<SID> sharedAllAppContainersSid; |
- |
// Create a well-known SID for the all appcontainers group. |
// We need to allow access to all AppContainers, since, apparently, |
// giving access to specific AppContainer (for example AppContainer of IE) |
@@ -90,7 +88,7 @@ |
SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE, |
0, 0, 0, 0, 0, 0, |
&allAppContainersSid); |
- sharedAllAppContainersSid.reset(static_cast<SID*>(allAppContainersSid), FreeSid); // Just to simplify cleanup |
+ std::tr1::shared_ptr<SID> sharedAllAppContainersSid(static_cast<SID*>(allAppContainersSid), FreeSid); // Just to simplify cleanup |
explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; |
explicitAccess[1].grfAccessMode = SET_ACCESS; |
@@ -99,32 +97,46 @@ |
explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; |
explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainersSid); |
+ // Will be released later |
PACL acl = 0; |
if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) |
return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
- std::tr1::shared_ptr<ACL> sharedAcl(static_cast<ACL*>(acl), LocalFree); // Just to simplify cleanup |
+ // NOTE: This only references the acl, not copies it. |
+ // DO NOT release the ACL before it's actually used |
if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE)) |
return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
- |
} |
- // Create a dummy security descriptor with low integrirty preset and copy its SACL into ours |
+ // Create a dummy security descriptor with low integrirty preset and refference its SACL in ours |
LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; |
ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &dummySecurityDescriptorLow, 0); |
std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedDummySecurityDescriptor(static_cast<SECURITY_DESCRIPTOR*>(dummySecurityDescriptorLow), LocalFree); // Just to simplify cleanup |
- BOOL saclPresent = FALSE; |
- BOOL saclDefaulted = FALSE; |
- PACL sacl; |
- GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, &saclDefaulted); |
- if (saclPresent) |
+ |
+ DWORD sdSize(0), saclSize(0), daclSize(0), ownerSize(0), primaryGroupSize(0); |
+ MakeAbsoluteSD(dummySecurityDescriptorLow, 0, &sdSize, 0, &daclSize, 0, &saclSize, 0, &ownerSize, 0, &primaryGroupSize); |
+ if (saclSize == 0 || sdSize == 0) |
{ |
- if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE)) |
- { |
- DWORD err = GetLastError(); |
return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
- } |
+ } |
+ // Will be released later |
+ PACL sacl = static_cast<PACL>(malloc(saclSize)); |
+ std::auto_ptr<SECURITY_DESCRIPTOR> absoluteDummySecurityDescriptorLow(static_cast<SECURITY_DESCRIPTOR*>(malloc(sdSize))); |
+ daclSize = 0; |
+ ownerSize = 0; |
+ primaryGroupSize = 0; |
+ BOOL res = MakeAbsoluteSD(dummySecurityDescriptorLow, absoluteDummySecurityDescriptorLow.get(), &sdSize, 0, &daclSize, sacl, &saclSize, 0, &ownerSize, 0, &primaryGroupSize); |
+ if (res == 0 || absoluteDummySecurityDescriptorLow.get() == 0 || saclSize == 0) |
+ { |
+ return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
+ } |
+ |
+ // NOTE: This only references the acl, not copies it. |
+ // DO NOT release the ACL before it's actually used |
+ if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE)) |
+ { |
+ return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
} |
return securityDescriptor; |
@@ -172,6 +184,27 @@ |
{ |
} |
+void FreeAbsoluteSecurityDescriptor(SECURITY_DESCRIPTOR* securityDescriptor) |
+{ |
+ BOOL aclPresent = FALSE; |
+ BOOL aclDefaulted = FALSE; |
+ PACL acl = 0; |
+ GetSecurityDescriptorDacl(securityDescriptor, &aclPresent, &acl, &aclDefaulted); |
+ if (aclPresent) |
+ { |
+ LocalFree(acl); |
+ } |
+ aclPresent = FALSE; |
+ aclDefaulted = FALSE; |
+ acl = 0; |
+ GetSecurityDescriptorSacl(securityDescriptor, &aclPresent, &acl, &aclDefaulted); |
+ if (aclPresent) |
+ { |
+ free(acl); |
+ } |
+ free(securityDescriptor); |
+} |
+ |
Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mode mode) |
{ |
pipe = INVALID_HANDLE_VALUE; |
@@ -182,7 +215,6 @@ |
securityAttributes.bInheritHandle = TRUE; |
std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup |
- |
AutoHandle token; |
OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); |
@@ -192,8 +224,9 @@ |
// Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows access to all AppContainers |
// This is needed since IE likes to jump out of Enhanced Protected Mode for specific pages (bing.com) |
std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDescriptor(logonSid.get()); |
+ |
securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); |
- sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityAttributes.lpSecurityDescriptor)); |
+ sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityAttributes.lpSecurityDescriptor), FreeAbsoluteSecurityDescriptor); |
} |
pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); |
@@ -215,12 +248,12 @@ |
DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
- throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastError()); |
+ throw std::runtime_error(AppendErrorCode("SetNamedPipeHandleState failed")); |
if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
{ |
DWORD err = GetLastError(); |
- throw std::runtime_error("Client failed to connect: error " + GetLastError()); |
+ throw std::runtime_error(AppendErrorCode("Client failed to connect")); |
} |
} |