Chromium Code Reviews| Index: chrome/installer/mini_installer/mini_installer.cc |
| diff --git a/chrome/installer/mini_installer/mini_installer.cc b/chrome/installer/mini_installer/mini_installer.cc |
| index 3ecd6e5fa90c156117f7d6d00e846d551a1a1003..09e5c72ec93c376f4f90684406324567f4c8f603 100644 |
| --- a/chrome/installer/mini_installer/mini_installer.cc |
| +++ b/chrome/installer/mini_installer/mini_installer.cc |
| @@ -22,6 +22,7 @@ |
| #pragma comment(linker, "/MERGE:.rdata=.text") |
| #include <windows.h> |
| +#include <sddl.h> |
| #include <shellapi.h> |
| #include <stdlib.h> |
| @@ -563,19 +564,35 @@ bool CreateWorkDir(const wchar_t* base_path, PathString* work_dir) { |
| if ((work_dir->capacity() - end) < (_countof("fffff.tmp") + 1)) |
| return false; |
| - // Generate a unique id. We only use the lowest 20 bits, so take the top |
| - // 12 bits and xor them with the lower bits. |
| - DWORD id = ::GetTickCount(); |
| - id ^= (id >> 12); |
| + // Add an ACL if supported by the filesystem. |
| + SECURITY_ATTRIBUTES sa = {0}; |
|
grt (UTC plus 2)
2015/12/03 21:38:32
nit: i prefer {} since {0} doesn't mean "initializ
jschuh
2015/12/04 00:40:27
Ah, good point.
|
| + sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| + DWORD flags; |
| + if (GetVolumeInformation(work_dir->get(), nullptr, 0, nullptr, nullptr, |
| + &flags, nullptr, 0) && |
| + (flags & FILE_PERSISTENT_ACLS)) { |
| + static const wchar_t sddl[] = |
| + L"D:AI(A;ID;FA;;;BA)" // Admin: Full control. |
| + L"(A;OICIIOID;GA;;;BA)" |
| + L"(A;ID;FA;;;SY)" // System: Full control. |
| + L"(A;OICIIOID;GA;;;SY)" |
| + L"(A;ID;FA;;;CO)"; // Owner: Full control. |
| + L"(A;OICIIOID;GA;;;CO)"; |
| + if (!ConvertStringSecurityDescriptorToSecurityDescriptor( |
| + sddl, SDDL_REVISION, &sa.lpSecurityDescriptor, NULL)) { |
| + return false; |
|
grt (UTC plus 2)
2015/12/03 21:38:32
how about falling through to the previous case if
jschuh
2015/12/04 00:40:27
This is one of those must-never-fail sort of thing
|
| + } |
| + } |
| - int max_attempts = 10; |
| - while (max_attempts--) { |
| + bool result = false; |
| + unsigned int id; |
| + rand_s(&id); |
|
grt (UTC plus 2)
2015/12/03 21:38:32
we link with /NODEFAULTLIB. will this work?
jschuh
2015/12/04 00:40:27
Switched it to call RtlGenRandom() directly.
|
| + for (int max_attempts = 10; max_attempts; --max_attempts) { |
| // This converts 'id' to a string in the format "78563412" on windows |
| // because of little endianness, but we don't care since it's just |
| // a name. |
| - if (!HexEncode(&id, sizeof(id), work_dir->get() + end, |
| - work_dir->capacity() - end)) { |
| - return false; |
| + if (!HexEncode(&id, 3, work_dir->get() + end, work_dir->capacity() - end)) { |
|
grt (UTC plus 2)
2015/12/03 21:38:32
nit: omit braces
jschuh
2015/12/04 00:40:28
Switched it back to sizeof.
|
| + break; |
| } |
| // We only want the first 5 digits to remain within the 8.3 file name |
| @@ -585,14 +602,19 @@ bool CreateWorkDir(const wchar_t* base_path, PathString* work_dir) { |
| // for consistency with the previous implementation which relied on |
| // GetTempFileName, we append the .tmp extension. |
| work_dir->append(L".tmp"); |
| - if (::CreateDirectory(work_dir->get(), NULL)) { |
| + |
| + if (::CreateDirectory(work_dir->get(), |
| + sa.lpSecurityDescriptor ? &sa : nullptr)) { |
| // Yay! Now let's just append the backslash and we're done. |
| - return work_dir->append(L"\\"); |
| + result = work_dir->append(L"\\"); |
| + break; |
| } |
| ++id; // Try a different name. |
| } |
| - return false; |
| + if (sa.lpSecurityDescriptor) |
| + LocalFree(sa.lpSecurityDescriptor); |
| + return result; |
| } |
| // Creates and returns a temporary directory in |work_dir| that can be used to |