Bug 1230910 Port simple __try blocks to __try1 draft
authorTom Ritter <tom@mozilla.com>
Wed, 08 Mar 2017 22:23:59 +0000
changeset 496072 efe15068d562a4e1dd6133f17d08bea6efe0513e
parent 496071 3fcd6c24bd15bcd433aa3a4196bff7aef4f16e4f
child 496073 249491dbdc3d6161ebb963ed6fa302499c407cca
push id48518
push userbmo:tom@mozilla.com
push dateThu, 09 Mar 2017 19:30:51 +0000
bugs1230910
milestone52.0.1
Bug 1230910 Port simple __try blocks to __try1 If __try1 works at all, it should work for these. MozReview-Commit-ID: 5oUOmJi1mjW
security/sandbox/chromium/sandbox/win/src/crosscall_client.h
security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc
security/sandbox/chromium/sandbox/win/src/registry_interception.cc
security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.cc
security/sandbox/chromium/sandbox/win/src/sync_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/crosscall_client.h
+++ b/security/sandbox/chromium/sandbox/win/src/crosscall_client.h
@@ -5,16 +5,17 @@
 #ifndef SANDBOX_SRC_CROSSCALL_CLIENT_H_
 #define SANDBOX_SRC_CROSSCALL_CLIENT_H_
 
 #include <stddef.h>
 #include <stdint.h>
 
 #include "sandbox/win/src/crosscall_params.h"
 #include "sandbox/win/src/sandbox.h"
+#include "sandbox/win/src/mingw_ehandler.h"
 
 // This header defines the CrossCall(..) family of templated functions
 // Their purpose is to simulate the syntax of regular call but to generate
 // and IPC from the client-side.
 //
 // The basic pattern is to
 //   1) use template argument deduction to compute the size of each
 //      parameter and the appropriate copy method
@@ -142,21 +143,21 @@ class CopyHelper<const wchar_t*> {
   bool Update(void* buffer) {
     // Not supported;
     return true;
   }
 
   // Returns the size of the string in bytes. We define a NULL string to
   // be of zero length.
   uint32_t GetSize() const {
-    __try {
+    __try1(ehandler) {
       return (!t_) ? 0
                    : static_cast<uint32_t>(StringLength(t_) * sizeof(t_[0]));
     }
-    __except(EXCEPTION_EXECUTE_HANDLER) {
+    __except1 {
       return UINT32_MAX;
     }
   }
 
   // Returns true if the current type is used as an In or InOut parameter.
   bool IsInOut() {
     return false;
   }
@@ -253,20 +254,20 @@ class CopyHelper<InOutCountedBuffer> {
   const void* GetStart() const {
     return t_.Buffer();
   }
 
   // Updates the buffer with the value from the new buffer in parameter.
   bool Update(void* buffer) {
     // We are touching user memory, this has to be done from inside a try
     // except.
-    __try {
+    __try1(ehandler) {
       memcpy(t_.Buffer(), buffer, t_.Size());
     }
-    __except(EXCEPTION_EXECUTE_HANDLER) {
+    __except1 {
       return false;
     }
     return true;
   }
 
   // Returns the size of the string in bytes. We define a NULL string to
   // be of zero length.
   uint32_t GetSize() const { return t_.Size(); }
--- a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
@@ -10,16 +10,17 @@
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/policy_params.h"
 #include "sandbox/win/src/policy_target.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sharedmem_ipc_client.h"
 #include "sandbox/win/src/target_services.h"
 #include "mozilla/sandboxing/sandboxLogging.h"
+#include "sandbox/win/src/mingw_ehandler.h"
 
 namespace sandbox {
 
 NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
                                    PHANDLE file, ACCESS_MASK desired_access,
                                    POBJECT_ATTRIBUTES object_attributes,
                                    PIO_STATUS_BLOCK io_status,
                                    PLARGE_INTEGER allocation_size,
@@ -83,21 +84,21 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCre
     if (SBOX_ALL_OK != code)
       break;
 
     status = answer.nt_status;
 
     if (!NT_SUCCESS(answer.nt_status))
       break;
 
-    __try {
+    __try1(ehandler) {
       *file = answer.handle;
       io_status->Status = answer.nt_status;
       io_status->Information = answer.extended[0].ulong_ptr;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
     mozilla::sandboxing::LogAllowed("NtCreateFile",
                                     object_attributes->ObjectName->Buffer,
                                     object_attributes->ObjectName->Length);
   } while (false);
 
   if (name)
@@ -164,21 +165,21 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenF
     if (SBOX_ALL_OK != code)
       break;
 
     status = answer.nt_status;
 
     if (!NT_SUCCESS(answer.nt_status))
       break;
 
-    __try {
+    __try1(ehandler) {
       *file = answer.handle;
       io_status->Status = answer.nt_status;
       io_status->Information = answer.extended[0].ulong_ptr;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
     mozilla::sandboxing::LogAllowed("NtOpenFile",
                                     object_attributes->ObjectName->Buffer,
                                     object_attributes->ObjectName->Length);
   } while (false);
 
   if (name)
--- a/security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc
@@ -9,16 +9,17 @@
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/policy_params.h"
 #include "sandbox/win/src/policy_target.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sharedmem_ipc_client.h"
 #include "sandbox/win/src/target_services.h"
+#include "sandbox/win/src/mingw_ehandler.h"
 #include "mozilla/sandboxing/sandboxLogging.h"
 
 namespace sandbox {
 
 SANDBOX_INTERCEPT NtExports g_nt;
 
 // Hooks NtOpenThread and proxy the call to the broker if it's trying to
 // open a thread in the same process.
@@ -35,17 +36,22 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpe
   do {
     if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
       break;
     if (!client_id)
       break;
 
     uint32_t thread_id = 0;
     bool should_break = false;
-    __try {
+    /*
+     * This is another tricky one, as tis is the interception of TargetNtOpenThread
+     * on the child process. If an exception is thrown, we return the original status
+     * code of the (failed) OpenThread call. We would like to preserve that behavior.
+     */
+    __try1(ehandler) {
       // We support only the calls for the current process
       if (NULL != client_id->UniqueProcess)
         should_break = true;
 
       // Object attributes should be NULL or empty.
       if (!should_break && NULL != object_attributes) {
         if (0 != object_attributes->Attributes ||
             NULL != object_attributes->ObjectName ||
@@ -53,17 +59,17 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpe
             NULL != object_attributes->SecurityDescriptor ||
             NULL != object_attributes->SecurityQualityOfService) {
           should_break = true;
         }
       }
 
       thread_id = static_cast<uint32_t>(
           reinterpret_cast<ULONG_PTR>(client_id->UniqueThread));
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
 
     if (should_break)
       break;
 
     if (!ValidParameter(thread, sizeof(HANDLE), WRITE))
       break;
@@ -85,20 +91,20 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpe
       // to be the current process. If you try to open a thread from another
       // process you will get this INVALID_CID error. On the other hand, if you
       // try to open a thread in your own process, it should return success.
       // We don't want to return STATUS_INVALID_CID here, so we return the
       // return of the original open thread status, which is most likely
       // STATUS_ACCESS_DENIED.
       break;
 
-    __try {
+    __try1(ehandler) {
       // Write the output parameters.
       *thread = answer.handle;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
 
     mozilla::sandboxing::LogAllowed("NtOpenThread");
     return answer.nt_status;
   } while (false);
 
   return status;
@@ -118,31 +124,31 @@ NTSTATUS WINAPI TargetNtOpenProcess(NtOp
   do {
     if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
       break;
     if (!client_id)
       break;
 
     uint32_t process_id = 0;
     bool should_break = false;
-    __try {
+    __try1(ehandler) {
       // Object attributes should be NULL or empty.
       if (!should_break && NULL != object_attributes) {
         if (0 != object_attributes->Attributes ||
             NULL != object_attributes->ObjectName ||
             NULL != object_attributes->RootDirectory ||
             NULL != object_attributes->SecurityDescriptor ||
             NULL != object_attributes->SecurityQualityOfService) {
           should_break = true;
         }
       }
 
       process_id = static_cast<uint32_t>(
           reinterpret_cast<ULONG_PTR>(client_id->UniqueProcess));
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
 
     if (should_break)
       break;
 
     if (!ValidParameter(process, sizeof(HANDLE), WRITE))
       break;
@@ -156,20 +162,20 @@ NTSTATUS WINAPI TargetNtOpenProcess(NtOp
     ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESS_TAG, desired_access,
                                 process_id, &answer);
     if (SBOX_ALL_OK != code)
       break;
 
     if (!NT_SUCCESS(answer.nt_status))
       return answer.nt_status;
 
-    __try {
+    __try1(ehandler) {
       // Write the output parameters.
       *process = answer.handle;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
 
     return answer.nt_status;
   } while (false);
 
   return status;
 }
@@ -202,20 +208,20 @@ NTSTATUS WINAPI TargetNtOpenProcessToken
     ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKEN_TAG, process,
                                 desired_access, &answer);
     if (SBOX_ALL_OK != code)
       break;
 
     if (!NT_SUCCESS(answer.nt_status))
       return answer.nt_status;
 
-    __try {
+    __try1(ehandler) {
       // Write the output parameters.
       *token = answer.handle;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
 
     mozilla::sandboxing::LogAllowed("NtOpenProcessToken");
     return answer.nt_status;
   } while (false);
 
   return status;
@@ -249,20 +255,20 @@ NTSTATUS WINAPI TargetNtOpenProcessToken
     ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKENEX_TAG, process,
                                 desired_access, handle_attributes, &answer);
     if (SBOX_ALL_OK != code)
       break;
 
     if (!NT_SUCCESS(answer.nt_status))
       return answer.nt_status;
 
-    __try {
+    __try1(ehandler) {
       // Write the output parameters.
       *token = answer.handle;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
 
     mozilla::sandboxing::LogAllowed("NtOpenProcessTokenEx");
     return answer.nt_status;
   } while (false);
 
   return status;
--- a/security/sandbox/chromium/sandbox/win/src/registry_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/registry_interception.cc
@@ -9,16 +9,17 @@
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/policy_params.h"
 #include "sandbox/win/src/policy_target.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sharedmem_ipc_client.h"
 #include "sandbox/win/src/target_services.h"
+#include "sandbox/win/src/mingw_ehandler.h"
 #include "mozilla/sandboxing/sandboxLogging.h"
 
 namespace sandbox {
 
 NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
                                   PHANDLE key, ACCESS_MASK desired_access,
                                   POBJECT_ATTRIBUTES object_attributes,
                                   ULONG title_index, PUNICODE_STRING class_name,
@@ -106,24 +107,28 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCrea
         // TODO(nsylvain): We should return answer.nt_status here instead
         // of status. We can do this only after we checked the policy.
         // otherwise we will returns ACCESS_DENIED for all paths
         // that are not specified by a policy, even though your token allows
         // access to that path, and the original call had a more meaningful
         // error. Bug 4369
         break;
 
-    __try {
+    /*
+     * Another case where we're modifying an interception function and we
+     * want to preserve the original behavior of the __except block
+     */
+    __try1(ehandler) {
       *key = answer.handle;
 
       if (disposition)
        *disposition = answer.extended[0].unsigned_int;
 
       status = answer.nt_status;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
     mozilla::sandboxing::LogAllowed("NtCreateKey",
                                     object_attributes->ObjectName->Buffer,
                                     object_attributes->ObjectName->Length);
   } while (false);
 
   return status;
@@ -189,20 +194,20 @@ NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS
         // TODO(nsylvain): We should return answer.nt_status here instead
         // of status. We can do this only after we checked the policy.
         // otherwise we will returns ACCESS_DENIED for all paths
         // that are not specified by a policy, even though your token allows
         // access to that path, and the original call had a more meaningful
         // error. Bug 4369
         break;
 
-    __try {
+    __try1(ehandler) {
       *key = answer.handle;
       status = answer.nt_status;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
     mozilla::sandboxing::LogAllowed("NtOpenKey[Ex]",
                                     object_attributes->ObjectName->Buffer,
                                     object_attributes->ObjectName->Length);
   } while (false);
 
   return status;
--- a/security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.cc
+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.cc
@@ -7,16 +7,17 @@
 #include <stddef.h>
 #include <stdint.h>
 
 #include <string>
 
 #include "base/win/pe_image.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/target_services.h"
+#include "sandbox/win/src/mingw_ehandler.h"
 
 namespace sandbox {
 
 // This is the list of all imported symbols from ntdll.dll.
 SANDBOX_INTERCEPT NtExports g_nt;
 
 }  // namespace sandbox
 
@@ -195,29 +196,29 @@ int TouchMemory(void* buffer, size_t siz
     dummy += *end;
   }
 
   return dummy;
 }
 
 bool ValidParameter(void* buffer, size_t size, RequiredAccess intent) {
   DCHECK_NT(size);
-  __try {
+  __try1(ehandler) {
     TouchMemory(buffer, size, intent);
-  } __except(EXCEPTION_EXECUTE_HANDLER) {
+  } __except1 {
     return false;
   }
   return true;
 }
 
 NTSTATUS CopyData(void* destination, const void* source, size_t bytes) {
   NTSTATUS ret = STATUS_SUCCESS;
-  __try {
+  __try1(ehandler) {
     g_nt.memcpy(destination, source, bytes);
-  } __except(EXCEPTION_EXECUTE_HANDLER) {
+  } __except1 {
     ret = GetExceptionCode();
   }
   return ret;
 }
 
 NTSTATUS AllocAndGetFullPath(HANDLE root,
                              wchar_t* path,
                              wchar_t** full_path) {
--- a/security/sandbox/chromium/sandbox/win/src/sync_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/sync_interception.cc
@@ -9,16 +9,17 @@
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/policy_params.h"
 #include "sandbox/win/src/policy_target.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sharedmem_ipc_client.h"
 #include "sandbox/win/src/target_services.h"
+#include "sandbox/win/src/mingw_ehandler.h"
 #include "mozilla/sandboxing/sandboxLogging.h"
 
 namespace sandbox {
 
 ResultCode ProxyCreateEvent(LPCWSTR name,
                             uint32_t initial_state,
                             EVENT_TYPE event_type,
                             void* ipc_memory,
@@ -97,20 +98,20 @@ NTSTATUS WINAPI TargetNtCreateEvent(NtCr
     ResultCode code = ProxyCreateEvent(name, initial_state, event_type, memory,
                                        &answer);
     operator delete(name, NT_ALLOC);
 
     if (code != SBOX_ALL_OK) {
       status = answer.nt_status;
       break;
     }
-    __try {
+    __try1(ehandler) {
       *event_handle = answer.handle;
       status = STATUS_SUCCESS;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
     mozilla::sandboxing::LogAllowed("NtCreateEvent",
                                     object_attributes->ObjectName->Buffer,
                                     object_attributes->ObjectName->Length);
   } while (false);
 
   return status;
@@ -156,20 +157,20 @@ NTSTATUS WINAPI TargetNtOpenEvent(NtOpen
     answer.nt_status = status;
     ResultCode code = ProxyOpenEvent(name, desired_access, memory, &answer);
     operator delete(name, NT_ALLOC);
 
     if (code != SBOX_ALL_OK) {
       status = answer.nt_status;
       break;
     }
-    __try {
+    __try1(ehandler) {
       *event_handle = answer.handle;
       status = STATUS_SUCCESS;
-    } __except(EXCEPTION_EXECUTE_HANDLER) {
+    } __except1 {
       break;
     }
     mozilla::sandboxing::LogAllowed("NtOpenEvent",
                                     object_attributes->ObjectName->Buffer,
                                     object_attributes->ObjectName->Length);
   } while (false);
 
   return status;