28_derive_sid_from_name.patch (8181B)
1 # HG changeset patch 2 # User Bob Owen <bobowencode@gmail.com> 3 # Date 1677499923 0 4 # Mon Feb 27 12:12:03 2023 +0000 5 Expose Sid::FromNamedCapability through broker services. 6 7 diff --git a/base/win/sid.cc b/base/win/sid.cc 8 --- a/base/win/sid.cc 9 +++ b/base/win/sid.cc 10 @@ -17,18 +17,22 @@ 11 #include "base/check.h" 12 #include "base/no_destructor.h" 13 #include "base/rand_util.h" 14 #include "base/ranges/algorithm.h" 15 #include "base/strings/string_util_win.h" 16 #include "base/win/scoped_handle.h" 17 #include "base/win/scoped_localalloc.h" 18 #include "base/win/windows_version.h" 19 -#include "third_party/boringssl/src/include/openssl/crypto.h" 20 -#include "third_party/boringssl/src/include/openssl/sha.h" 21 +#if defined(MOZ_SANDBOX) 22 +#include <winternl.h> 23 +#else 24 +#include "third_party/boringssl/src/include/openssl/crypto.h" 25 +#include "third_party/boringssl/src/include/openssl/sha.h" 26 +#endif 27 28 namespace base::win { 29 30 namespace { 31 32 template <typename Iterator> 33 Sid FromSubAuthorities(const SID_IDENTIFIER_AUTHORITY& identifier_authority, 34 size_t sub_authority_count, 35 @@ -94,16 +98,19 @@ 36 } 37 38 Sid Sid::FromKnownCapability(WellKnownCapability capability) { 39 int32_t capability_rid = WellKnownCapabilityToRid(capability); 40 return FromSubAuthorities(SECURITY_APP_PACKAGE_AUTHORITY, 41 {SECURITY_CAPABILITY_BASE_RID, capability_rid}); 42 } 43 44 +typedef NTSTATUS(WINAPI* RtlDeriveCapabilitySidsFromNameFunction)( 45 + PCUNICODE_STRING SourceString, PSID CapabilityGroupSid, PSID CapabilitySid); 46 + 47 Sid Sid::FromNamedCapability(const std::wstring& capability_name) { 48 static const base::NoDestructor<std::map<std::wstring, WellKnownCapability>> 49 known_capabilities( 50 {{L"INTERNETCLIENT", WellKnownCapability::kInternetClient}, 51 {L"INTERNETCLIENTSERVER", 52 WellKnownCapability::kInternetClientServer}, 53 {L"PRIVATENETWORKCLIENTSERVER", 54 WellKnownCapability::kPrivateNetworkClientServer}, 55 @@ -119,28 +126,37 @@ 56 {L"APPOINTMENTS", WellKnownCapability::kAppointments}, 57 {L"CONTACTS", WellKnownCapability::kContacts}}); 58 59 std::wstring cap_upper = base::ToUpperASCII(capability_name); 60 auto known_cap = known_capabilities->find(cap_upper); 61 if (known_cap != known_capabilities->end()) { 62 return FromKnownCapability(known_cap->second); 63 } 64 - CRYPTO_library_init(); 65 - static_assert((SHA256_DIGEST_LENGTH / sizeof(DWORD)) == 66 - SECURITY_APP_PACKAGE_RID_COUNT); 67 - DWORD rids[(SHA256_DIGEST_LENGTH / sizeof(DWORD)) + 2]; 68 - rids[0] = SECURITY_CAPABILITY_BASE_RID; 69 - rids[1] = SECURITY_CAPABILITY_APP_RID; 70 - 71 - SHA256(reinterpret_cast<const uint8_t*>(cap_upper.c_str()), 72 - cap_upper.size() * sizeof(wchar_t), 73 - reinterpret_cast<uint8_t*>(&rids[2])); 74 - return FromSubAuthorities(SECURITY_APP_PACKAGE_AUTHORITY, std::size(rids), 75 - rids); 76 + 77 + HMODULE ntdll_handle = ::GetModuleHandleW(L"ntdll.dll"); 78 + CHECK(ntdll_handle); 79 + auto derive_capability_sids = 80 + reinterpret_cast<RtlDeriveCapabilitySidsFromNameFunction>( 81 + ::GetProcAddress(ntdll_handle, "RtlDeriveCapabilitySidsFromName")); 82 + if (!derive_capability_sids) { 83 + return Sid(); 84 + } 85 + 86 + UNICODE_STRING name = {}; 87 + ::RtlInitUnicodeString(&name, capability_name.c_str()); 88 + BYTE capability_sid[SECURITY_MAX_SID_SIZE]; 89 + BYTE group_sid[SECURITY_MAX_SID_SIZE]; 90 + 91 + NTSTATUS status = derive_capability_sids(&name, group_sid, capability_sid); 92 + if (!NT_SUCCESS(status)) { 93 + return Sid(); 94 + } 95 + 96 + return Sid(capability_sid, ::GetLengthSid(capability_sid)); 97 } 98 99 Sid Sid::FromKnownSid(WellKnownSid type) { 100 switch (type) { 101 case WellKnownSid::kNull: 102 return FromSubAuthorities(SECURITY_NULL_SID_AUTHORITY, 103 {SECURITY_NULL_RID}); 104 case WellKnownSid::kWorld: 105 diff --git a/security/sandbox/chromium/base/win/sid.h b/security/sandbox/chromium/base/win/sid.h 106 --- a/base/win/sid.h 107 +++ b/base/win/sid.h 108 @@ -127,15 +127,16 @@ class BASE_EXPORT Sid { 109 110 // Is this Sid equal to another Sid? 111 bool operator==(const Sid& sid) const; 112 113 // Is this Sid not equal to another Sid? 114 bool operator!=(const Sid& sid) const; 115 116 private: 117 + Sid() {} 118 Sid(const void* sid, size_t length); 119 std::vector<char> sid_; 120 }; 121 122 } // namespace base::win 123 124 #endif // BASE_WIN_SID_H_ 125 diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc 126 --- a/sandbox/win/src/broker_services.cc 127 +++ b/sandbox/win/src/broker_services.cc 128 @@ -11,16 +11,17 @@ 129 #include "base/containers/contains.h" 130 #include "base/memory/ptr_util.h" 131 #include "base/notreached.h" 132 #include "base/threading/platform_thread.h" 133 #include "base/win/access_token.h" 134 #include "base/win/current_module.h" 135 #include "base/win/scoped_handle.h" 136 #include "base/win/scoped_process_information.h" 137 +#include "base/win/sid.h" 138 #include "base/win/windows_version.h" 139 #include "build/build_config.h" 140 #include "sandbox/win/src/app_container.h" 141 #include "sandbox/win/src/process_mitigations.h" 142 #include "sandbox/win/src/sandbox.h" 143 #include "sandbox/win/src/sandbox_policy_base.h" 144 #include "sandbox/win/src/sandbox_policy_diagnostic.h" 145 #include "sandbox/win/src/startup_information_helper.h" 146 @@ -604,9 +604,16 @@ ResultCode BrokerServicesBase::GetPolicy 147 } 148 149 // static 150 void BrokerServicesBase::FreezeTargetConfigForTesting(TargetConfig* config) { 151 CHECK(!config->IsConfigured()); 152 static_cast<ConfigBase*>(config)->Freeze(); 153 } 154 155 +bool BrokerServicesBase::DeriveCapabilitySidFromName(const wchar_t* name, 156 + PSID derived_sid, 157 + DWORD sid_buffer_length) { 158 + return ::CopySid(sid_buffer_length, derived_sid, 159 + base::win::Sid::FromNamedCapability(name).GetPSID()); 160 +} 161 + 162 } // namespace sandbox 163 diff --git a/sandbox/win/src/broker_services.h b/sandbox/win/src/broker_services.h 164 --- a/sandbox/win/src/broker_services.h 165 +++ b/sandbox/win/src/broker_services.h 166 @@ -64,16 +64,19 @@ class BrokerServicesBase final : public 167 std::unique_ptr<PolicyDiagnosticsReceiver> receiver) override; 168 void SetStartingMitigations(MitigationFlags starting_mitigations) override; 169 bool RatchetDownSecurityMitigations( 170 MitigationFlags additional_flags) override; 171 std::wstring GetDesktopName(Desktop desktop) override; 172 173 static void FreezeTargetConfigForTesting(TargetConfig* config); 174 175 + bool DeriveCapabilitySidFromName(const wchar_t* name, PSID derived_sid, 176 + DWORD sid_buffer_length) override; 177 + 178 private: 179 // Implements Init and InitForTesting. 180 ResultCode Init(std::unique_ptr<BrokerServicesTargetTracker> target_tracker); 181 182 // Ensures the desktop integrity suits any process we are launching. 183 ResultCode UpdateDesktopIntegrity(Desktop desktop, IntegrityLevel integrity); 184 185 // The completion port used by the job objects to communicate events to 186 diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h 187 --- a/sandbox/win/src/sandbox.h 188 +++ b/sandbox/win/src/sandbox.h 189 @@ -149,16 +149,21 @@ class BrokerServices { 190 // RatchetDownSecurityMitigations is then called by the broker process to 191 // gradually increase our security as startup continues. It's designed to 192 // be called multiple times. If you don't call SetStartingMitigations first 193 // and there were mitigations applied early in startup, the new mitigations 194 // may not be applied. 195 virtual bool RatchetDownSecurityMitigations( 196 MitigationFlags additional_flags) = 0; 197 198 + // Derive a capability PSID from the given string. 199 + virtual bool DeriveCapabilitySidFromName(const wchar_t* name, 200 + PSID derived_sid, 201 + DWORD sid_buffer_length) = 0; 202 + 203 protected: 204 ~BrokerServices() {} 205 }; 206 207 // TargetServices models the current process from the perspective 208 // of a target process. To obtain a pointer to it use 209 // Sandbox::GetTargetServices(). Note that this call returns a non-null 210 // pointer only if this process is in fact a target. A process is a target