36_add_back_registry_brokering.patch (20119B)
1 # HG changeset patch 2 # User Bob Owen <bobowencode@gmail.com> 3 Add back registry brokering. 4 5 This was removed from the chromium codebase, but we still require it. 6 The stand-alone files have been added to chromium-shim. This patch covers the 7 wiring back into other chromium code. 8 Much of this is reinstating removed code without change, but there are some 9 differences to allow for new policy config style. 10 11 diff --git a/sandbox/win/src/interceptors_64.cc b/sandbox/win/src/interceptors_64.cc 12 --- a/sandbox/win/src/interceptors_64.cc 13 +++ b/sandbox/win/src/interceptors_64.cc 14 @@ -5,16 +5,17 @@ 15 #include "sandbox/win/src/interceptors_64.h" 16 17 #include "sandbox/win/src/filesystem_interception.h" 18 #include "sandbox/win/src/interceptors.h" 19 #include "sandbox/win/src/named_pipe_interception.h" 20 #include "sandbox/win/src/policy_target.h" 21 #include "sandbox/win/src/process_mitigations_win32k_interception.h" 22 #include "sandbox/win/src/process_thread_interception.h" 23 +#include "sandbox/win/src/registry_interception.h" 24 #include "sandbox/win/src/sandbox_nt_types.h" 25 #include "sandbox/win/src/sandbox_types.h" 26 #include "sandbox/win/src/signed_interception.h" 27 #include "sandbox/win/src/target_interceptions.h" 28 29 namespace sandbox { 30 31 SANDBOX_INTERCEPT OriginalFunctions g_originals; 32 @@ -234,16 +235,46 @@ TargetCreateThread64(LPSECURITY_ATTRIBUT 33 reinterpret_cast<CreateThreadFunction>(g_originals[CREATE_THREAD_ID]); 34 return TargetCreateThread(orig_fn, thread_attributes, stack_size, 35 start_address, parameter, creation_flags, 36 thread_id); 37 } 38 39 // ----------------------------------------------------------------------- 40 41 +SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateKey64( 42 + PHANDLE key, ACCESS_MASK desired_access, 43 + POBJECT_ATTRIBUTES object_attributes, ULONG title_index, 44 + PUNICODE_STRING class_name, ULONG create_options, PULONG disposition) { 45 + NtCreateKeyFunction orig_fn = 46 + reinterpret_cast<NtCreateKeyFunction>(g_originals[CREATE_KEY_ID]); 47 + return TargetNtCreateKey(orig_fn, key, desired_access, object_attributes, 48 + title_index, class_name, create_options, 49 + disposition); 50 +} 51 + 52 +SANDBOX_INTERCEPT NTSTATUS WINAPI 53 +TargetNtOpenKey64(PHANDLE key, ACCESS_MASK desired_access, 54 + POBJECT_ATTRIBUTES object_attributes) { 55 + NtOpenKeyFunction orig_fn = 56 + reinterpret_cast<NtOpenKeyFunction>(g_originals[OPEN_KEY_ID]); 57 + return TargetNtOpenKey(orig_fn, key, desired_access, object_attributes); 58 +} 59 + 60 +SANDBOX_INTERCEPT NTSTATUS WINAPI 61 +TargetNtOpenKeyEx64(PHANDLE key, ACCESS_MASK desired_access, 62 + POBJECT_ATTRIBUTES object_attributes, ULONG open_options) { 63 + NtOpenKeyExFunction orig_fn = 64 + reinterpret_cast<NtOpenKeyExFunction>(g_originals[OPEN_KEY_EX_ID]); 65 + return TargetNtOpenKeyEx(orig_fn, key, desired_access, object_attributes, 66 + open_options); 67 +} 68 + 69 +// ----------------------------------------------------------------------- 70 + 71 SANDBOX_INTERCEPT BOOL WINAPI TargetGdiDllInitialize64(HANDLE dll, 72 DWORD reason) { 73 GdiDllInitializeFunction orig_fn = 74 reinterpret_cast<GdiDllInitializeFunction>(g_originals[GDIINITIALIZE_ID]); 75 return TargetGdiDllInitialize(orig_fn, dll, reason); 76 } 77 78 SANDBOX_INTERCEPT HGDIOBJ WINAPI TargetGetStockObject64(int object) { 79 diff --git a/sandbox/win/src/interceptors_64.h b/sandbox/win/src/interceptors_64.h 80 --- a/sandbox/win/src/interceptors_64.h 81 +++ b/sandbox/win/src/interceptors_64.h 82 @@ -155,16 +155,35 @@ SANDBOX_INTERCEPT HANDLE WINAPI 83 TargetCreateThread64(LPSECURITY_ATTRIBUTES thread_attributes, 84 SIZE_T stack_size, 85 LPTHREAD_START_ROUTINE start_address, 86 PVOID parameter, 87 DWORD creation_flags, 88 LPDWORD thread_id); 89 90 // ----------------------------------------------------------------------- 91 +// Interceptors handled by the registry dispatcher. 92 + 93 +// Interception of NtCreateKey on the child process. 94 +SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateKey64( 95 + PHANDLE key, ACCESS_MASK desired_access, 96 + POBJECT_ATTRIBUTES object_attributes, ULONG title_index, 97 + PUNICODE_STRING class_name, ULONG create_options, PULONG disposition); 98 + 99 +// Interception of NtOpenKey on the child process. 100 +SANDBOX_INTERCEPT NTSTATUS WINAPI 101 +TargetNtOpenKey64(PHANDLE key, ACCESS_MASK desired_access, 102 + POBJECT_ATTRIBUTES object_attributes); 103 + 104 +// Interception of NtOpenKeyEx on the child process. 105 +SANDBOX_INTERCEPT NTSTATUS WINAPI 106 +TargetNtOpenKeyEx64(PHANDLE key, ACCESS_MASK desired_access, 107 + POBJECT_ATTRIBUTES object_attributes, ULONG open_options); 108 + 109 +// ----------------------------------------------------------------------- 110 // Interceptors handled by the process mitigations win32k lockdown code. 111 112 // Interceptor for the GdiDllInitialize function. 113 SANDBOX_INTERCEPT BOOL WINAPI TargetGdiDllInitialize64(HANDLE dll, 114 DWORD reason); 115 116 // Interceptor for the GetStockObject function. 117 SANDBOX_INTERCEPT HGDIOBJ WINAPI TargetGetStockObject64(int object); 118 diff --git a/sandbox/win/src/ipc_tags.h b/sandbox/win/src/ipc_tags.h 119 --- a/sandbox/win/src/ipc_tags.h 120 +++ b/sandbox/win/src/ipc_tags.h 121 @@ -16,16 +16,18 @@ enum class IpcTag { 122 NTCREATEFILE, 123 NTOPENFILE, 124 NTQUERYATTRIBUTESFILE, 125 NTQUERYFULLATTRIBUTESFILE, 126 NTSETINFO_RENAME, 127 CREATENAMEDPIPEW, 128 NTOPENTHREAD, 129 NTOPENPROCESSTOKENEX, 130 + NTCREATEKEY, 131 + NTOPENKEY, 132 GDI_GDIDLLINITIALIZE, 133 GDI_GETSTOCKOBJECT, 134 USER_REGISTERCLASSW, 135 CREATETHREAD, 136 GETCOMPLEXLINEBREAKS, 137 NTCREATESECTION, 138 LAST 139 }; 140 diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h 141 --- a/sandbox/win/src/nt_internals.h 142 +++ b/sandbox/win/src/nt_internals.h 143 @@ -216,16 +216,33 @@ typedef NTSTATUS(WINAPI* NtOpenProcessTo 144 145 typedef NTSTATUS(WINAPI* NtOpenProcessTokenExFunction)( 146 IN HANDLE ProcessHandle, 147 IN ACCESS_MASK DesiredAccess, 148 IN ULONG HandleAttributes, 149 OUT PHANDLE TokenHandle); 150 151 // ----------------------------------------------------------------------- 152 +// Registry 153 + 154 +typedef NTSTATUS(WINAPI* NtCreateKeyFunction)( 155 + OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, 156 + IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, 157 + IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, 158 + OUT PULONG Disposition OPTIONAL); 159 + 160 +typedef NTSTATUS(WINAPI* NtOpenKeyFunction)( 161 + OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, 162 + IN POBJECT_ATTRIBUTES ObjectAttributes); 163 + 164 +typedef NTSTATUS(WINAPI* NtOpenKeyExFunction)( 165 + OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, 166 + IN POBJECT_ATTRIBUTES ObjectAttributes, IN DWORD open_options); 167 + 168 +// ----------------------------------------------------------------------- 169 // Memory 170 171 // Don't really need this structure right now. 172 typedef PVOID PRTL_HEAP_PARAMETERS; 173 174 typedef PVOID(WINAPI* RtlCreateHeapFunction)(IN ULONG Flags, 175 IN PVOID HeapBase OPTIONAL, 176 IN SIZE_T ReserveSize OPTIONAL, 177 diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc 178 --- a/sandbox/win/src/sandbox_nt_util.cc 179 +++ b/sandbox/win/src/sandbox_nt_util.cc 180 @@ -364,16 +364,109 @@ NTSTATUS CopyNameAndAttributes( 181 ret = (NTSTATUS)GetExceptionCode(); 182 } 183 184 if (!NT_SUCCESS(ret) && *out_name) 185 out_name->reset(nullptr); 186 187 return ret; 188 } 189 +NTSTATUS AllocAndGetFullPath( 190 + HANDLE root, const wchar_t* path, 191 + std::unique_ptr<wchar_t, NtAllocDeleter>* full_path) { 192 + if (!InitHeap()) return STATUS_NO_MEMORY; 193 + 194 + DCHECK_NT(full_path); 195 + DCHECK_NT(path); 196 + NTSTATUS ret = STATUS_UNSUCCESSFUL; 197 + __try { 198 + do { 199 + static NtQueryObjectFunction NtQueryObject = nullptr; 200 + if (!NtQueryObject) ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject); 201 + 202 + ULONG size = 0; 203 + // Query the name information a first time to get the size of the name. 204 + ret = NtQueryObject(root, ObjectNameInformation, nullptr, 0, &size); 205 + 206 + std::unique_ptr<OBJECT_NAME_INFORMATION, NtAllocDeleter> handle_name; 207 + if (size) { 208 + handle_name.reset(reinterpret_cast<OBJECT_NAME_INFORMATION*>( 209 + new (NT_ALLOC) BYTE[size])); 210 + 211 + // Query the name information a second time to get the name of the 212 + // object referenced by the handle. 213 + ret = NtQueryObject(root, ObjectNameInformation, handle_name.get(), 214 + size, &size); 215 + } 216 + 217 + if (STATUS_SUCCESS != ret) break; 218 + 219 + // Space for path + '\' + name + '\0'. 220 + size_t name_length = 221 + handle_name->ObjectName.Length + (wcslen(path) + 2) * sizeof(wchar_t); 222 + full_path->reset(new (NT_ALLOC) wchar_t[name_length / sizeof(wchar_t)]); 223 + if (!*full_path) break; 224 + wchar_t* off = full_path->get(); 225 + ret = CopyData(off, handle_name->ObjectName.Buffer, 226 + handle_name->ObjectName.Length); 227 + if (!NT_SUCCESS(ret)) break; 228 + off += handle_name->ObjectName.Length / sizeof(wchar_t); 229 + *off = L'\\'; 230 + off += 1; 231 + ret = CopyData(off, path, wcslen(path) * sizeof(wchar_t)); 232 + if (!NT_SUCCESS(ret)) break; 233 + off += wcslen(path); 234 + *off = L'\0'; 235 + } while (false); 236 + } __except (EXCEPTION_EXECUTE_HANDLER) { 237 + ret = GetExceptionCode(); 238 + } 239 + 240 + if (!NT_SUCCESS(ret) && *full_path) full_path->reset(nullptr); 241 + 242 + return ret; 243 +} 244 + 245 +// Hacky code... replace with AllocAndCopyObjectAttributes. 246 +NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object, 247 + std::unique_ptr<wchar_t, NtAllocDeleter>* out_name, 248 + uint32_t* attributes, HANDLE* root) { 249 + if (!InitHeap()) return STATUS_NO_MEMORY; 250 + 251 + DCHECK_NT(out_name); 252 + NTSTATUS ret = STATUS_UNSUCCESSFUL; 253 + __try { 254 + do { 255 + if (in_object->RootDirectory != static_cast<HANDLE>(0) && !root) break; 256 + if (!in_object->ObjectName) break; 257 + if (!in_object->ObjectName->Buffer) break; 258 + 259 + size_t size = in_object->ObjectName->Length + sizeof(wchar_t); 260 + out_name->reset(new (NT_ALLOC) wchar_t[size / sizeof(wchar_t)]); 261 + if (!*out_name) break; 262 + 263 + ret = CopyData(out_name->get(), in_object->ObjectName->Buffer, 264 + size - sizeof(wchar_t)); 265 + if (!NT_SUCCESS(ret)) break; 266 + 267 + out_name->get()[size / sizeof(wchar_t) - 1] = L'\0'; 268 + 269 + if (attributes) *attributes = in_object->Attributes; 270 + 271 + if (root) *root = in_object->RootDirectory; 272 + ret = STATUS_SUCCESS; 273 + } while (false); 274 + } __except (EXCEPTION_EXECUTE_HANDLER) { 275 + ret = GetExceptionCode(); 276 + } 277 + 278 + if (!NT_SUCCESS(ret) && *out_name) out_name->reset(nullptr); 279 + 280 + return ret; 281 +} 282 283 NTSTATUS GetProcessId(HANDLE process, DWORD* process_id) { 284 PROCESS_BASIC_INFORMATION proc_info; 285 ULONG bytes_returned; 286 287 NTSTATUS ret = GetNtExports()->QueryInformationProcess( 288 process, ProcessBasicInformation, &proc_info, sizeof(proc_info), 289 &bytes_returned); 290 diff --git a/sandbox/win/src/sandbox_nt_util.h b/sandbox/win/src/sandbox_nt_util.h 291 --- a/sandbox/win/src/sandbox_nt_util.h 292 +++ b/sandbox/win/src/sandbox_nt_util.h 293 @@ -127,16 +127,26 @@ NTSTATUS CopyData(void* destination, con 294 // string and |out_name_len| is the number of characters copied. |attributes| 295 // is a copy of the attribute flags from |in_object|. 296 NTSTATUS CopyNameAndAttributes( 297 const OBJECT_ATTRIBUTES* in_object, 298 std::unique_ptr<wchar_t, NtAllocDeleter>* out_name, 299 size_t* out_name_len, 300 uint32_t* attributes = nullptr); 301 302 +// Copies the name from an object attributes. 303 +NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object, 304 + std::unique_ptr<wchar_t, NtAllocDeleter>* out_name, 305 + uint32_t* attributes, HANDLE* root); 306 + 307 +// Determine full path name from object root and path. 308 +NTSTATUS AllocAndGetFullPath( 309 + HANDLE root, const wchar_t* path, 310 + std::unique_ptr<wchar_t, NtAllocDeleter>* full_path); 311 + 312 // Initializes our ntdll level heap 313 bool InitHeap(); 314 315 // Returns true if the provided handle refers to the current process. 316 bool IsSameProcess(HANDLE process); 317 318 enum MappedModuleFlags { 319 MODULE_IS_PE_IMAGE = 1, // Module is an executable. 320 diff --git a/sandbox/win/src/sandbox_policy.h b/sandbox/win/src/sandbox_policy.h 321 --- a/sandbox/win/src/sandbox_policy.h 322 +++ b/sandbox/win/src/sandbox_policy.h 323 @@ -161,16 +161,25 @@ class [[clang::lto_visibility_public]] T 324 // Adds a policy rule effective for processes spawned using this policy. 325 // Named pipes matching `pattern` (see AllowFileAccess) can be created. 326 // 327 // Note: Do not add new uses of this function - instead proxy pipe handles 328 // into your process via normal Chrome IPC. 329 [[nodiscard]] virtual ResultCode AllowNamedPipes(const wchar_t* pattern) = 0; 330 331 // Adds a policy rule effective for processes spawned using this policy. 332 + // Registry entries matching `pattern` (see AllowFileAccess) can be opened 333 + // for read access. 334 + // 335 + // Note: Do not add new uses of this function - instead proxy registry handles 336 + // into your process via normal Chrome IPC. 337 + [[nodiscard]] virtual ResultCode AllowRegistryRead( 338 + const wchar_t* pattern) = 0; 339 + 340 + // Adds a policy rule effective for processes spawned using this policy. 341 // Modules patching `pattern` (see AllowFileAccess) can still be loaded under 342 // Code-Integrity Guard (MITIGATION_FORCE_MS_SIGNED_BINS). 343 [[nodiscard]] virtual ResultCode AllowExtraDlls(const wchar_t* pattern) = 0; 344 345 // Adds a policy rule effective for processes spawned using this policy. 346 // Fake gdi init to allow user32 and gdi32 to initialize under Win32 Lockdown. 347 [[nodiscard]] virtual ResultCode SetFakeGdiInit() = 0; 348 349 diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc 350 --- a/sandbox/win/src/sandbox_policy_base.cc 351 +++ b/sandbox/win/src/sandbox_policy_base.cc 352 @@ -28,16 +28,17 @@ 353 #include "sandbox/win/src/line_break_policy.h" 354 #include "sandbox/win/src/named_pipe_policy.h" 355 #include "sandbox/win/src/policy_broker.h" 356 #include "sandbox/win/src/policy_engine_processor.h" 357 #include "sandbox/win/src/policy_low_level.h" 358 #include "sandbox/win/src/process_mitigations.h" 359 #include "sandbox/win/src/process_mitigations_win32k_policy.h" 360 #include "sandbox/win/src/process_thread_policy.h" 361 +#include "sandbox/win/src/registry_policy.h" 362 #include "sandbox/win/src/restricted_token_utils.h" 363 #include "sandbox/win/src/sandbox_policy.h" 364 #include "sandbox/win/src/sandbox_policy_diagnostic.h" 365 #include "sandbox/win/src/signed_policy.h" 366 #include "sandbox/win/src/target_process.h" 367 #include "sandbox/win/src/top_level_dispatcher.h" 368 #include "third_party/abseil-cpp/absl/types/optional.h" 369 370 @@ -241,16 +242,24 @@ ResultCode ConfigBase::AllowFileAccess(F 371 ResultCode ConfigBase::AllowNamedPipes(const wchar_t* pattern) { 372 if (!NamedPipePolicy::GenerateRules(pattern, PolicyMaker())) { 373 NOTREACHED(); 374 return SBOX_ERROR_BAD_PARAMS; 375 } 376 return SBOX_ALL_OK; 377 } 378 379 +ResultCode ConfigBase::AllowRegistryRead(const wchar_t* pattern) { 380 + if (!RegistryPolicy::GenerateRules(pattern, PolicyMaker())) { 381 + NOTREACHED(); 382 + return SBOX_ERROR_BAD_PARAMS; 383 + } 384 + return SBOX_ALL_OK; 385 +} 386 + 387 ResultCode ConfigBase::SetFakeGdiInit() { 388 DCHECK_EQ(MITIGATION_WIN32K_DISABLE, mitigations_ & MITIGATION_WIN32K_DISABLE) 389 << "Enable MITIGATION_WIN32K_DISABLE before adding win32k policy " 390 "rules."; 391 if (!ProcessMitigationsWin32KLockdownPolicy::GenerateRules(PolicyMaker())) { 392 NOTREACHED(); 393 return SBOX_ERROR_BAD_PARAMS; 394 } 395 diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h 396 --- a/sandbox/win/src/sandbox_policy_base.h 397 +++ b/sandbox/win/src/sandbox_policy_base.h 398 @@ -63,16 +63,17 @@ class ConfigBase final : public TargetCo 399 void SetAllowEveryoneForUserRestricted() final; 400 bool GetAllowEveryoneForUserRestricted() final; 401 ResultCode SetJobLevel(JobLevel job_level, uint32_t ui_exceptions) override; 402 JobLevel GetJobLevel() const override; 403 void SetJobMemoryLimit(size_t memory_limit) override; 404 ResultCode AllowFileAccess(FileSemantics semantics, 405 const wchar_t* pattern) override; 406 ResultCode AllowNamedPipes(const wchar_t* pattern) override; 407 + ResultCode AllowRegistryRead(const wchar_t* pattern) final; 408 ResultCode AllowExtraDlls(const wchar_t* pattern) override; 409 ResultCode SetFakeGdiInit() override; 410 ResultCode AllowLineBreaking() final; 411 void AddDllToUnload(const wchar_t* dll_name) override; 412 ResultCode SetIntegrityLevel(IntegrityLevel integrity_level) override; 413 IntegrityLevel GetIntegrityLevel() const override; 414 void SetDelayedIntegrityLevel(IntegrityLevel integrity_level) override; 415 ResultCode SetLowBox(const wchar_t* sid) override; 416 diff --git a/sandbox/win/src/top_level_dispatcher.cc b/sandbox/win/src/top_level_dispatcher.cc 417 --- a/sandbox/win/src/top_level_dispatcher.cc 418 +++ b/sandbox/win/src/top_level_dispatcher.cc 419 @@ -13,16 +13,17 @@ 420 #include "sandbox/win/src/filesystem_dispatcher.h" 421 #include "sandbox/win/src/interception.h" 422 #include "sandbox/win/src/internal_types.h" 423 #include "sandbox/win/src/ipc_tags.h" 424 #include "sandbox/win/src/line_break_dispatcher.h" 425 #include "sandbox/win/src/named_pipe_dispatcher.h" 426 #include "sandbox/win/src/process_mitigations_win32k_dispatcher.h" 427 #include "sandbox/win/src/process_thread_dispatcher.h" 428 +#include "sandbox/win/src/registry_dispatcher.h" 429 #include "sandbox/win/src/sandbox_policy_base.h" 430 #include "sandbox/win/src/signed_dispatcher.h" 431 432 namespace sandbox { 433 434 TopLevelDispatcher::TopLevelDispatcher(PolicyBase* policy) : policy_(policy) { 435 // Initialize the IPC dispatcher array. 436 memset(ipc_targets_, 0, sizeof(ipc_targets_)); 437 @@ -42,16 +43,21 @@ TopLevelDispatcher::TopLevelDispatcher(P 438 named_pipe_dispatcher_.reset(dispatcher); 439 440 dispatcher = new ThreadProcessDispatcher(); 441 ipc_targets_[static_cast<size_t>(IpcTag::NTOPENTHREAD)] = dispatcher; 442 ipc_targets_[static_cast<size_t>(IpcTag::NTOPENPROCESSTOKENEX)] = dispatcher; 443 ipc_targets_[static_cast<size_t>(IpcTag::CREATETHREAD)] = dispatcher; 444 thread_process_dispatcher_.reset(dispatcher); 445 446 + dispatcher = new RegistryDispatcher(policy_); 447 + ipc_targets_[static_cast<size_t>(IpcTag::NTCREATEKEY)] = dispatcher; 448 + ipc_targets_[static_cast<size_t>(IpcTag::NTOPENKEY)] = dispatcher; 449 + registry_dispatcher_.reset(dispatcher); 450 + 451 dispatcher = new ProcessMitigationsWin32KDispatcher(policy_); 452 ipc_targets_[static_cast<size_t>(IpcTag::GDI_GDIDLLINITIALIZE)] = dispatcher; 453 ipc_targets_[static_cast<size_t>(IpcTag::GDI_GETSTOCKOBJECT)] = dispatcher; 454 ipc_targets_[static_cast<size_t>(IpcTag::USER_REGISTERCLASSW)] = dispatcher; 455 process_mitigations_win32k_dispatcher_.reset(dispatcher); 456 457 dispatcher = new SignedDispatcher(policy_); 458 ipc_targets_[static_cast<size_t>(IpcTag::NTCREATESECTION)] = dispatcher; 459 diff --git a/sandbox/win/src/top_level_dispatcher.h b/sandbox/win/src/top_level_dispatcher.h 460 --- a/sandbox/win/src/top_level_dispatcher.h 461 +++ b/sandbox/win/src/top_level_dispatcher.h 462 @@ -37,16 +37,17 @@ class TopLevelDispatcher : public Dispat 463 464 // Returns a dispatcher from ipc_targets_. 465 Dispatcher* GetDispatcher(IpcTag ipc_tag); 466 467 raw_ptr<PolicyBase> policy_; 468 std::unique_ptr<Dispatcher> filesystem_dispatcher_; 469 std::unique_ptr<Dispatcher> named_pipe_dispatcher_; 470 std::unique_ptr<Dispatcher> thread_process_dispatcher_; 471 + std::unique_ptr<Dispatcher> registry_dispatcher_; 472 std::unique_ptr<Dispatcher> handle_dispatcher_; 473 std::unique_ptr<Dispatcher> process_mitigations_win32k_dispatcher_; 474 std::unique_ptr<Dispatcher> signed_dispatcher_; 475 std::unique_ptr<Dispatcher> line_break_dispatcher_; 476 Dispatcher* ipc_targets_[kMaxIpcTag]; 477 }; 478 479 } // namespace sandbox