Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/shared/Communication.cpp

Issue 6308036998070272: Release DACL after the named pipe was created (Closed)
Patch Set: Created July 1, 2014, 4:51 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include <Windows.h> 1 #include <Windows.h>
2 #include <Lmcons.h> 2 #include <Lmcons.h>
3 #include <Sddl.h> 3 #include <Sddl.h>
4 #include <aclapi.h> 4 #include <aclapi.h>
5 #include <strsafe.h> 5 #include <strsafe.h>
6 6
7 #include "AutoHandle.h" 7 #include "AutoHandle.h"
8 #include "Communication.h" 8 #include "Communication.h"
9 #include "Utils.h" 9 #include "Utils.h"
10 10
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 sharedAllAppContainersSid.reset(static_cast<SID*>(allAppContainersSid), Fr eeSid); // Just to simplify cleanup 93 sharedAllAppContainersSid.reset(static_cast<SID*>(allAppContainersSid), Fr eeSid); // Just to simplify cleanup
94 94
95 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI GHTS_ALL; 95 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI GHTS_ALL;
96 explicitAccess[1].grfAccessMode = SET_ACCESS; 96 explicitAccess[1].grfAccessMode = SET_ACCESS;
97 explicitAccess[1].grfInheritance= NO_INHERITANCE; 97 explicitAccess[1].grfInheritance= NO_INHERITANCE;
98 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; 98 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
99 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; 99 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
100 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers Sid); 100 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers Sid);
101 101
102 PACL acl = 0; 102 PACL acl = 0;
103 // acl has to be released after this
103 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) 104 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS)
104 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); 105 return std::auto_ptr<SECURITY_DESCRIPTOR>(0);
105 std::tr1::shared_ptr<ACL> sharedAcl(static_cast<ACL*>(acl), LocalFree); // Just to simplify cleanup
106 106
107 // This only references the acl, not copies it
107 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE) ) 108 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE) )
108 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); 109 return std::auto_ptr<SECURITY_DESCRIPTOR>(0);
109
110 } 110 }
111 111
112 // Create a dummy security descriptor with low integrirty preset and copy it s SACL into ours 112 // Create a dummy security descriptor with low integrirty preset and copy it s SACL into ours
113 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; 113 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)";
114 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; 114 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow;
115 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD L_REVISION_1, &dummySecurityDescriptorLow, 0); 115 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD L_REVISION_1, &dummySecurityDescriptorLow, 0);
116 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedDummySecurityDescriptor(stat ic_cast<SECURITY_DESCRIPTOR*>(dummySecurityDescriptorLow), LocalFree); // Just t o simplify cleanup 116 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedDummySecurityDescriptor(stat ic_cast<SECURITY_DESCRIPTOR*>(dummySecurityDescriptorLow), LocalFree); // Just t o simplify cleanup
117 BOOL saclPresent = FALSE; 117 BOOL saclPresent = FALSE;
118 BOOL saclDefaulted = FALSE; 118 BOOL saclDefaulted = FALSE;
119 PACL sacl; 119 PACL sacl;
120 GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, & saclDefaulted); 120 GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, & saclDefaulted);
121 if (saclPresent) 121 if (saclPresent)
122 { 122 {
123 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE )) 123 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE ))
124 { 124 {
125 DWORD err = GetLastError(); 125 DWORD err = GetLastError();
126 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); 126 return std::auto_ptr<SECURITY_DESCRIPTOR>(0);
127 } 127 }
128 } 128 }
129 129
130 return securityDescriptor; 130 return securityDescriptor;
131 } 131 }
132 } 132 }
133 133
134 // Releases the DACL structure in the provided security descriptor
135 void ReleaseDacl(PSECURITY_DESCRIPTOR securityDescriptor)
136 {
137 BOOL aclPresent = FALSE;
138 BOOL aclDefaulted = FALSE;
139 PACL acl;
140 GetSecurityDescriptorDacl(securityDescriptor, &aclPresent, &acl, &aclDefault ed);
141 if (aclPresent)
142 {
143 LocalFree(acl);
144 }
145 }
134 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); 146 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName();
135 147
136 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) 148 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType )
137 { 149 {
138 if (!hasType) 150 if (!hasType)
139 ReadBinary(currentType); 151 ReadBinary(currentType);
140 152
141 if (currentType != expectedType) 153 if (currentType != expectedType)
142 { 154 {
143 // Make sure we don't attempt to read the type again 155 // Make sure we don't attempt to read the type again
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode) 187 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode)
176 { 188 {
177 pipe = INVALID_HANDLE_VALUE; 189 pipe = INVALID_HANDLE_VALUE;
178 if (mode == MODE_CREATE) 190 if (mode == MODE_CREATE)
179 { 191 {
180 SECURITY_ATTRIBUTES securityAttributes = {}; 192 SECURITY_ATTRIBUTES securityAttributes = {};
181 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); 193 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
182 securityAttributes.bInheritHandle = TRUE; 194 securityAttributes.bInheritHandle = TRUE;
183 195
184 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup 196 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup
185 197
186 AutoHandle token; 198 AutoHandle token;
187 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); 199 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token);
188 200
189 if (IsWindowsVistaOrLater()) 201 if (IsWindowsVistaOrLater())
190 { 202 {
191 std::auto_ptr<SID> logonSid = GetLogonSid(token); 203 std::auto_ptr<SID> logonSid = GetLogonSid(token);
192 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc ess to all AppContainers 204 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc ess to all AppContainers
193 // This is needed since IE likes to jump out of Enhanced Protected Mode fo r specific pages (bing.com) 205 // This is needed since IE likes to jump out of Enhanced Protected Mode fo r specific pages (bing.com)
206
207 // ATTENTION: DACL in the returned securityDescriptor has to be manually r eleased by ReleaseDacl
194 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc riptor(logonSid.get()); 208 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc riptor(logonSid.get());
209
195 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); 210 securityAttributes.lpSecurityDescriptor = securityDescriptor.release();
196 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA ttributes.lpSecurityDescriptor)); 211 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA ttributes.lpSecurityDescriptor));
197 } 212 }
198 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 213 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
199 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); 214 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes);
215
216 if (IsWindowsVistaOrLater())
217 {
218 ReleaseDacl(securityAttributes.lpSecurityDescriptor);
219 }
200 } 220 }
201 else 221 else
202 { 222 {
203 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0); 223 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0);
204 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) 224 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY)
205 { 225 {
206 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) 226 if (!WaitNamedPipeW(pipeName.c_str(), 10000))
207 throw PipeBusyError(); 227 throw PipeBusyError();
208 228
209 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0); 229 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0);
210 } 230 }
211 } 231 }
212 232
213 if (pipe == INVALID_HANDLE_VALUE) 233 if (pipe == INVALID_HANDLE_VALUE)
214 throw PipeConnectionError(); 234 throw PipeConnectionError();
215 235
216 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; 236 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
217 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) 237 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0))
218 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE rror()); 238 throw std::runtime_error(AppendErrorCode("SetNamedPipeHandleState failed"));
219 239
220 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) 240 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0))
221 { 241 {
222 DWORD err = GetLastError(); 242 DWORD err = GetLastError();
223 throw std::runtime_error("Client failed to connect: error " + GetLastError() ); 243 throw std::runtime_error(AppendErrorCode("Client failed to connect"));
224 } 244 }
225 } 245 }
226 246
227 Communication::Pipe::~Pipe() 247 Communication::Pipe::~Pipe()
228 { 248 {
229 CloseHandle(pipe); 249 CloseHandle(pipe);
230 } 250 }
231 251
232 Communication::InputBuffer Communication::Pipe::ReadMessage() 252 Communication::InputBuffer Communication::Pipe::ReadMessage()
233 { 253 {
(...skipping 25 matching lines...) Expand all
259 return Communication::InputBuffer(stream.str()); 279 return Communication::InputBuffer(stream.str());
260 } 280 }
261 281
262 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) 282 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message)
263 { 283 {
264 DWORD bytesWritten; 284 DWORD bytesWritten;
265 std::string data = message.Get(); 285 std::string data = message.Get();
266 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0)) 286 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0))
267 throw std::runtime_error("Failed to write to pipe"); 287 throw std::runtime_error("Failed to write to pipe");
268 } 288 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld