Bug 1196403 - Apply crbug/522201 to support Windows 10 build 10525. r=bobowen
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Tue, 25 Aug 2015 19:21:08 +0900
changeset 259233 c4b66462595789190a33a11b211e3977ecc7c5f6
parent 259232 4b0f0897663540d0129b77e69b5a43f314afaf65
child 259234 0d3b1fd5f2d10562fec06f21f7297c0722159a6b
push id29273
push userryanvm@gmail.com
push dateTue, 25 Aug 2015 14:44:17 +0000
treeherdermozilla-central@23a04f9a321c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbobowen
bugs1196403, 522201, 10525
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1196403 - Apply crbug/522201 to support Windows 10 build 10525. r=bobowen
security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc
security/sandbox/moz-chromium-commit-status.txt
--- a/security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc
+++ b/security/sandbox/chromium/sandbox/win/src/service_resolver_64.cc
@@ -12,16 +12,20 @@ namespace {
 #pragma pack(push, 1)
 
 const ULONG kMmovR10EcxMovEax = 0xB8D18B4C;
 const USHORT kSyscall = 0x050F;
 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 {
   // This struct contains roughly the following code:
   // 00 mov     r10,rcx
   // 03 mov     eax,52h
   // 08 syscall
   // 0a ret
@@ -55,34 +59,79 @@ struct ServiceEntryW8 {
   ULONG mov_3;                // = 89 4C 24 20
   ULONG mov_r10_rcx_mov_eax;  // = 4C 8B D1 B8
   ULONG service_id;
   USHORT syscall;             // = 0F 05
   BYTE ret;                   // = C3
   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;
   };
 };
 
 #pragma pack(pop)
 
 bool IsService(const void* source) {
   const ServiceEntry* service =
       reinterpret_cast<const ServiceEntry*>(source);
 
   return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax &&
           kSyscall == service->syscall && kRetNp == service->ret);
 }
 
+bool IsServiceW8(const void* source) {
+  const ServiceEntryW8* service =
+      reinterpret_cast<const ServiceEntryW8*>(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<const ServiceEntryWithInt2E*>(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 {
 
 NTSTATUS ServiceResolverThunk::Setup(const void* target_module,
                                      const void* interceptor_module,
                                      const char* target_name,
                                      const char* interceptor_name,
@@ -145,25 +194,19 @@ bool ServiceResolverThunk::IsFunctionASe
   SIZE_T read;
   if (!::ReadProcessMemory(process_, target_, &function_code,
                            sizeof(function_code), &read))
     return false;
 
   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));
 
   return true;
 }
 
 NTSTATUS ServiceResolverThunk::PerformPatch(void* local_thunk,
--- a/security/sandbox/moz-chromium-commit-status.txt
+++ b/security/sandbox/moz-chromium-commit-status.txt
@@ -1,4 +1,5 @@
 Chromium Commit                            Directory / File (relative to security/sandbox/)
 ----------------------------------------   ------------------------------------------------
 df7cc6c04725630dd4460f29d858a77507343b24   chromium
 b533d6533585377edd63ec6500469f6c4fba602a   chromium/sandbox/win/src/sharedmem_ipc_server.cc
+034bd64db1806d85b2ceacc736074ac07722af4a   chromium/sandbox/win/src/service_resolver_64.cc