From 7073895edfe1530289cab6eb13345868887a5d01 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Tue, 25 Aug 2015 19:21:08 +0900 Subject: [PATCH] Bug 1196403 - Apply crbug/522201 to support Windows 10 build 10525. r=bobowen --- .../sandbox/win/src/service_resolver_64.cc | 61 ++++++++++++++++--- .../sandbox/moz-chromium-commit-status.txt | 1 + 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc b/security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc index 984cb384e277..c0e684c795b2 100644 --- a/security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc +++ b/security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc @@ -17,6 +17,10 @@ const BYTE kRetNp = 0xC3; const ULONG64 kMov1 = 0x54894808244C8948; const ULONG64 kMov2 = 0x4C182444894C1024; const ULONG kMov3 = 0x20244C89; +const USHORT kTestByte = 0x04F6; +const BYTE kPtr = 0x25; +const BYTE kRet = 0xC3; +const USHORT kJne = 0x0375; // Service code for 64 bit systems. struct ServiceEntry { @@ -60,11 +64,37 @@ struct ServiceEntryW8 { BYTE nop; // = 90 }; +// Service code for 64 bit systems with int 2e fallback. +struct ServiceEntryWithInt2E { + // This struct contains roughly the following code: + // 00 4c8bd1 mov r10,rcx + // 03 b855000000 mov eax,52h + // 08 f604250803fe7f01 test byte ptr SharedUserData!308, 1 + // 10 7503 jne [over syscall] + // 12 0f05 syscall + // 14 c3 ret + // 15 cd2e int 2e + // 17 c3 ret + + ULONG mov_r10_rcx_mov_eax; // = 4C 8B D1 B8 + ULONG service_id; + USHORT test_byte; // = F6 04 + BYTE ptr; // = 25 + ULONG user_shared_data_ptr; + BYTE one; // = 01 + USHORT jne_over_syscall; // = 75 03 + USHORT syscall; // = 0F 05 + BYTE ret; // = C3 + USHORT int2e; // = CD 2E + BYTE ret2; // = C3 +}; + // We don't have an internal thunk for x64. struct ServiceFullThunk { union { ServiceEntry original; ServiceEntryW8 original_w8; + ServiceEntryWithInt2E original_int2e_fallback; }; }; @@ -78,6 +108,25 @@ bool IsService(const void* source) { kSyscall == service->syscall && kRetNp == service->ret); } +bool IsServiceW8(const void* source) { + const ServiceEntryW8* service = + reinterpret_cast(source); + + return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax && + kMov1 == service->mov_1 && kMov2 == service->mov_2 && + kMov3 == service->mov_3); +} + +bool IsServiceWithInt2E(const void* source) { + const ServiceEntryWithInt2E* service = + reinterpret_cast(source); + + return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax && + kTestByte == service->test_byte && kPtr == service->ptr && + kJne == service->jne_over_syscall && kSyscall == service->syscall && + kRet == service->ret && kRet == service->ret2); +} + }; // namespace namespace sandbox { @@ -150,15 +199,9 @@ bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const { if (sizeof(function_code) != read) return false; - if (!IsService(&function_code)) { - // See if it's the Win8 signature. - ServiceEntryW8* w8_service = &function_code.original_w8; - if (!IsService(&w8_service->mov_r10_rcx_mov_eax) || - w8_service->mov_1 != kMov1 || w8_service->mov_1 != kMov1 || - w8_service->mov_1 != kMov1) { - return false; - } - } + if (!IsService(&function_code) && !IsServiceW8(&function_code) && + !IsServiceWithInt2E(&function_code)) + return false; // Save the verified code. memcpy(local_thunk, &function_code, sizeof(function_code)); diff --git a/security/sandbox/moz-chromium-commit-status.txt b/security/sandbox/moz-chromium-commit-status.txt index 2ffe8036df9c..cac160b51146 100644 --- a/security/sandbox/moz-chromium-commit-status.txt +++ b/security/sandbox/moz-chromium-commit-status.txt @@ -2,3 +2,4 @@ Chromium Commit Directory / File (relative to securit ---------------------------------------- ------------------------------------------------ df7cc6c04725630dd4460f29d858a77507343b24 chromium b533d6533585377edd63ec6500469f6c4fba602a chromium/sandbox/win/src/sharedmem_ipc_server.cc +034bd64db1806d85b2ceacc736074ac07722af4a chromium/sandbox/win/src/service_resolver_64.cc