Merge from Chromium at DEPS revision 284076

This commit was generated by merge_to_master.py.

Change-Id: I9a279485b02fe7ceddcd32d992a714ff132e99ae
diff --git a/sandbox/win/src/handle_closer_test.cc b/sandbox/win/src/handle_closer_test.cc
index 9adcf6c..8e821ce 100644
--- a/sandbox/win/src/handle_closer_test.cc
+++ b/sandbox/win/src/handle_closer_test.cc
@@ -157,7 +157,8 @@
 // Run a thread pool inside a sandbox without a CSRSS connection.
 SBOX_TESTS_COMMAND int RunThreadPool(int argc, wchar_t **argv) {
   HANDLE wait_list[20];
-  CHECK(finish_event = ::CreateEvent(NULL, TRUE, FALSE, NULL));
+  finish_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+  CHECK(finish_event);
 
   // Set up a bunch of waiters.
   HANDLE pool = NULL;
diff --git a/sandbox/win/src/handle_dispatcher.cc b/sandbox/win/src/handle_dispatcher.cc
index 6acb6f9..fda7aac 100644
--- a/sandbox/win/src/handle_dispatcher.cc
+++ b/sandbox/win/src/handle_dispatcher.cc
@@ -44,7 +44,6 @@
                                             DWORD target_process_id,
                                             DWORD desired_access,
                                             DWORD options) {
-  NTSTATUS error;
   static NtQueryObject QueryObject = NULL;
   if (!QueryObject)
     ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
@@ -65,9 +64,10 @@
   OBJECT_TYPE_INFORMATION* type_info =
       reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer);
   ULONG size = sizeof(buffer) - sizeof(wchar_t);
-  error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size);
+  NTSTATUS error =
+      QueryObject(handle, ObjectTypeInformation, type_info, size, &size);
   if (!NT_SUCCESS(error)) {
-    ipc->return_info.win32_result = error;
+    ipc->return_info.nt_status = error;
     return false;
   }
   type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0';
diff --git a/sandbox/win/src/handle_interception.cc b/sandbox/win/src/handle_interception.cc
index af0bebc..a0df8d6 100644
--- a/sandbox/win/src/handle_interception.cc
+++ b/sandbox/win/src/handle_interception.cc
@@ -33,7 +33,7 @@
     return code;
 
   if (answer.win32_result) {
-    ::SetLastError(answer.nt_status);
+    ::SetLastError(answer.win32_result);
     return SBOX_ERROR_GENERIC;
   }
 
diff --git a/sandbox/win/src/integrity_level_test.cc b/sandbox/win/src/integrity_level_test.cc
index 67ea9de..f962033 100644
--- a/sandbox/win/src/integrity_level_test.cc
+++ b/sandbox/win/src/integrity_level_test.cc
@@ -52,6 +52,7 @@
 
   runner.SetTimeout(INFINITE);
 
+  runner.GetPolicy()->SetAlternateDesktop(true);
   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
 
   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckIntegrityLevel"));
diff --git a/sandbox/win/src/process_policy_test.cc b/sandbox/win/src/process_policy_test.cc
index af64f14..ae62606 100644
--- a/sandbox/win/src/process_policy_test.cc
+++ b/sandbox/win/src/process_policy_test.cc
@@ -154,28 +154,20 @@
   // TEST 4: Try file name in the app_name and current directory sets correctly.
   base::string16 system32 = MakeFullPathToSystem32(L"");
   wchar_t current_directory[MAX_PATH + 1];
-  int result4;
-  bool test_succeeded = false;
   DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory);
   if (!ret)
     return SBOX_TEST_FIRST_ERROR;
+  if (ret >= MAX_PATH)
+    return SBOX_TEST_FAILED;
 
-  if (ret < MAX_PATH) {
-    current_directory[ret] = L'\\';
-    current_directory[ret+1] = L'\0';
-    if (::SetCurrentDirectory(system32.c_str())) {
-      result4 = CreateProcessHelper(argv[0], base::string16());
-      if (::SetCurrentDirectory(current_directory)) {
-        test_succeeded = true;
-      }
-    } else {
-      return SBOX_TEST_SECOND_ERROR;
-    }
+  current_directory[ret] = L'\\';
+  current_directory[ret+1] = L'\0';
+  if (!::SetCurrentDirectory(system32.c_str())) {
+    return SBOX_TEST_SECOND_ERROR;
   }
-  if (!test_succeeded)
-    result4 = SBOX_TEST_FAILED;
 
-  return result4;
+  const int result4 = CreateProcessHelper(argv[0], base::string16());
+  return ::SetCurrentDirectory(current_directory) ? result4 : SBOX_TEST_FAILED;
 }
 
 SBOX_TESTS_COMMAND int Process_RunApp5(int argc, wchar_t **argv) {
diff --git a/sandbox/win/src/restricted_token_utils.h b/sandbox/win/src/restricted_token_utils.h
index f2a280a..69462b4 100644
--- a/sandbox/win/src/restricted_token_utils.h
+++ b/sandbox/win/src/restricted_token_utils.h
@@ -73,6 +73,10 @@
 // than the current integrity level, the function will fail.
 DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level);
 
+// Returns the integrity level SDDL string associated with a given
+// IntegrityLevel value.
+const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level);
+
 // Sets the integrity level on the current process on Vista. It returns without
 // failing on XP. If the integrity level that you specify is greater than the
 // current integrity level, the function will fail.
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc
index 711fafc..7b9262b 100644
--- a/sandbox/win/src/sandbox_policy_base.cc
+++ b/sandbox/win/src/sandbox_policy_base.cc
@@ -4,6 +4,8 @@
 
 #include "sandbox/win/src/sandbox_policy_base.h"
 
+#include <sddl.h>
+
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/logging.h"
@@ -75,6 +77,8 @@
 // Initializes static members.
 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL;
 HDESK PolicyBase::alternate_desktop_handle_ = NULL;
+IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ =
+    INTEGRITY_LEVEL_SYSTEM;
 
 PolicyBase::PolicyBase()
     : ref_count(1),
@@ -517,8 +521,28 @@
   // with the process and therefore with any thread that is not impersonating.
   DWORD result = CreateRestrictedToken(lockdown, lockdown_level_,
                                        integrity_level_, PRIMARY);
-  if (ERROR_SUCCESS != result) {
+  if (ERROR_SUCCESS != result)
     return SBOX_ERROR_GENERIC;
+
+  // If we're launching on the alternate desktop we need to make sure the
+  // integrity label on the object is no higher than the sandboxed process's
+  // integrity level. So, we lower the label on the desktop process if it's
+  // not already low enough for our process.
+  if (use_alternate_desktop_ &&
+      integrity_level_ != INTEGRITY_LEVEL_LAST &&
+      alternate_desktop_integrity_level_label_ < integrity_level_ &&
+      base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) {
+    // Integrity label enum is reversed (higher level is a lower value).
+    static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED,
+                  "Integrity level ordering reversed.");
+    result = SetObjectIntegrityLabel(alternate_desktop_handle_,
+                                     SE_WINDOW_OBJECT,
+                                     L"",
+                                     GetIntegrityLevelString(integrity_level_));
+    if (ERROR_SUCCESS != result)
+      return SBOX_ERROR_GENERIC;
+
+    alternate_desktop_integrity_level_label_ = integrity_level_;
   }
 
   if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) {
diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h
index 540f261..952df0d 100644
--- a/sandbox/win/src/sandbox_policy_base.h
+++ b/sandbox/win/src/sandbox_policy_base.h
@@ -157,6 +157,7 @@
 
   static HDESK alternate_desktop_handle_;
   static HWINSTA alternate_winstation_handle_;
+  static IntegrityLevel alternate_desktop_integrity_level_label_;
 
   DISALLOW_COPY_AND_ASSIGN(PolicyBase);
 };
diff --git a/sandbox/win/src/sync_dispatcher.cc b/sandbox/win/src/sync_dispatcher.cc
index d4b36d5..18a0743 100644
--- a/sandbox/win/src/sync_dispatcher.cc
+++ b/sandbox/win/src/sync_dispatcher.cc
@@ -35,12 +35,11 @@
 
 bool SyncDispatcher::SetupService(InterceptionManager* manager,
                                   int service) {
-  if (IPC_CREATEEVENT_TAG == service) {
+  if (service == IPC_CREATEEVENT_TAG) {
     return INTERCEPT_NT(manager, NtCreateEvent, CREATE_EVENT_ID, 24);
-  } else if (IPC_OPENEVENT_TAG == service) {
-    return INTERCEPT_NT(manager, NtOpenEvent, OPEN_EVENT_ID, 16);
   }
-  return false;
+  return (service == IPC_OPENEVENT_TAG) &&
+      INTERCEPT_NT(manager, NtOpenEvent, OPEN_EVENT_ID, 16);
 }
 
 bool SyncDispatcher::CreateEvent(IPCInfo* ipc, base::string16* name,
@@ -52,11 +51,9 @@
   EvalResult result = policy_base_->EvalPolicy(IPC_CREATEEVENT_TAG,
                                                params.GetBase());
   HANDLE handle = NULL;
-  DWORD ret = SyncPolicy::CreateEventAction(result, *ipc->client_info, *name,
-                                            event_type, initial_state,
-                                            &handle);
   // Return operation status on the IPC.
-  ipc->return_info.nt_status = ret;
+  ipc->return_info.nt_status = SyncPolicy::CreateEventAction(
+      result, *ipc->client_info, *name, event_type, initial_state, &handle);
   ipc->return_info.handle = handle;
   return true;
 }
@@ -72,10 +69,9 @@
   EvalResult result = policy_base_->EvalPolicy(IPC_OPENEVENT_TAG,
                                                params.GetBase());
   HANDLE handle = NULL;
-  DWORD ret = SyncPolicy::OpenEventAction(result, *ipc->client_info, *name,
-                                          desired_access, &handle);
   // Return operation status on the IPC.
-  ipc->return_info.win32_result = ret;
+  ipc->return_info.nt_status = SyncPolicy::OpenEventAction(
+      result, *ipc->client_info, *name, desired_access, &handle);
   ipc->return_info.handle = handle;
   return true;
 }
diff --git a/sandbox/win/src/sync_policy.cc b/sandbox/win/src/sync_policy.cc
index 7b18fe7..75399e6 100644
--- a/sandbox/win/src/sync_policy.cc
+++ b/sandbox/win/src/sync_policy.cc
@@ -176,12 +176,12 @@
   return true;
 }
 
-DWORD SyncPolicy::CreateEventAction(EvalResult eval_result,
-                                    const ClientInfo& client_info,
-                                    const base::string16 &event_name,
-                                    uint32 event_type,
-                                    uint32 initial_state,
-                                    HANDLE *handle) {
+NTSTATUS SyncPolicy::CreateEventAction(EvalResult eval_result,
+                                       const ClientInfo& client_info,
+                                       const base::string16 &event_name,
+                                       uint32 event_type,
+                                       uint32 initial_state,
+                                       HANDLE *handle) {
   NtCreateEventFunction NtCreateEvent = NULL;
   ResolveNTFunctionPtr("NtCreateEvent", &NtCreateEvent);
 
@@ -214,11 +214,11 @@
   return status;
 }
 
-DWORD SyncPolicy::OpenEventAction(EvalResult eval_result,
-                                  const ClientInfo& client_info,
-                                  const base::string16 &event_name,
-                                  uint32 desired_access,
-                                  HANDLE *handle) {
+NTSTATUS SyncPolicy::OpenEventAction(EvalResult eval_result,
+                                     const ClientInfo& client_info,
+                                     const base::string16 &event_name,
+                                     uint32 desired_access,
+                                     HANDLE *handle) {
   NtOpenEventFunction NtOpenEvent = NULL;
   ResolveNTFunctionPtr("NtOpenEvent", &NtOpenEvent);
 
diff --git a/sandbox/win/src/sync_policy.h b/sandbox/win/src/sync_policy.h
index 4383998..e370e4b 100644
--- a/sandbox/win/src/sync_policy.h
+++ b/sandbox/win/src/sync_policy.h
@@ -33,17 +33,17 @@
   // Performs the desired policy action on a request.
   // client_info is the target process that is making the request and
   // eval_result is the desired policy action to accomplish.
-  static DWORD CreateEventAction(EvalResult eval_result,
-                                 const ClientInfo& client_info,
-                                 const base::string16 &event_name,
-                                 uint32 event_type,
-                                 uint32 initial_state,
-                                 HANDLE *handle);
-  static DWORD OpenEventAction(EvalResult eval_result,
-                               const ClientInfo& client_info,
-                               const base::string16 &event_name,
-                               uint32 desired_access,
-                               HANDLE *handle);
+  static NTSTATUS CreateEventAction(EvalResult eval_result,
+                                    const ClientInfo& client_info,
+                                    const base::string16 &event_name,
+                                    uint32 event_type,
+                                    uint32 initial_state,
+                                    HANDLE *handle);
+  static NTSTATUS OpenEventAction(EvalResult eval_result,
+                                  const ClientInfo& client_info,
+                                  const base::string16 &event_name,
+                                  uint32 desired_access,
+                                  HANDLE *handle);
 };
 
 }  // namespace sandbox
diff --git a/sandbox/win/tests/common/controller.cc b/sandbox/win/tests/common/controller.cc
index ac20f6c..8d355b6 100644
--- a/sandbox/win/tests/common/controller.cc
+++ b/sandbox/win/tests/common/controller.cc
@@ -247,13 +247,13 @@
   }
 
   if (WAIT_TIMEOUT == ::WaitForSingleObject(target.hProcess, timeout_)) {
-    ::TerminateProcess(target.hProcess, SBOX_TEST_TIMED_OUT);
+    ::TerminateProcess(target.hProcess, static_cast<UINT>(SBOX_TEST_TIMED_OUT));
     ::CloseHandle(target.hProcess);
     ::CloseHandle(target.hThread);
     return SBOX_TEST_TIMED_OUT;
   }
 
-  DWORD exit_code = SBOX_TEST_LAST_RESULT;
+  DWORD exit_code = static_cast<DWORD>(SBOX_TEST_LAST_RESULT);
   if (!::GetExitCodeProcess(target.hProcess, &exit_code)) {
     ::CloseHandle(target.hProcess);
     ::CloseHandle(target.hThread);
diff --git a/sandbox/win/tests/validation_tests/commands.cc b/sandbox/win/tests/validation_tests/commands.cc
index 4b12094..45717b4 100644
--- a/sandbox/win/tests/validation_tests/commands.cc
+++ b/sandbox/win/tests/validation_tests/commands.cc
@@ -139,7 +139,7 @@
   }
 }
 
-SBOX_TESTS_COMMAND int OpenFile(int argc, wchar_t **argv) {
+SBOX_TESTS_COMMAND int OpenFileCmd(int argc, wchar_t **argv) {
   if (1 != argc)
     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
 
@@ -161,7 +161,7 @@
   trim_quote(&path);
 
   return TestOpenWriteFile(path);
-  }
+}
 
 int TestOpenWriteFile(const base::string16& path) {
   return TestOpenFile(path, true);
@@ -276,8 +276,8 @@
   }
 
   // Open by name with WRITE_DAC.
-  if ((desktop = ::OpenDesktop(desktop_name, 0, FALSE, WRITE_DAC)) ||
-      ::GetLastError() != ERROR_ACCESS_DENIED) {
+  desktop = ::OpenDesktop(desktop_name, 0, FALSE, WRITE_DAC);
+  if (desktop || ::GetLastError() != ERROR_ACCESS_DENIED) {
     ::CloseDesktop(desktop);
     return SBOX_TEST_SUCCEEDED;
   }
diff --git a/sandbox/win/tests/validation_tests/suite.cc b/sandbox/win/tests/validation_tests/suite.cc
index 4a8ae43..afb00b5 100644
--- a/sandbox/win/tests/validation_tests/suite.cc
+++ b/sandbox/win/tests/validation_tests/suite.cc
@@ -80,19 +80,19 @@
   ASSERT_TRUE(VolumeSupportsACLs(L"%AppData%\\"));
 
   TestRunner runner;
-  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %SystemDrive%"));
-  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %SystemRoot%"));
-  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %ProgramFiles%"));
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %SystemDrive%"));
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %SystemRoot%"));
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %ProgramFiles%"));
   EXPECT_EQ(SBOX_TEST_DENIED,
-      runner.RunTest(L"OpenFile %SystemRoot%\\System32"));
+      runner.RunTest(L"OpenFileCmd %SystemRoot%\\System32"));
   EXPECT_EQ(SBOX_TEST_DENIED,
-      runner.RunTest(L"OpenFile %SystemRoot%\\explorer.exe"));
+      runner.RunTest(L"OpenFileCmd %SystemRoot%\\explorer.exe"));
   EXPECT_EQ(SBOX_TEST_DENIED,
-      runner.RunTest(L"OpenFile %SystemRoot%\\Cursors\\arrow_i.cur"));
+      runner.RunTest(L"OpenFileCmd %SystemRoot%\\Cursors\\arrow_i.cur"));
   EXPECT_EQ(SBOX_TEST_DENIED,
-      runner.RunTest(L"OpenFile %AllUsersProfile%"));
-  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %Temp%"));
-  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %AppData%"));
+      runner.RunTest(L"OpenFileCmd %AllUsersProfile%"));
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %Temp%"));
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %AppData%"));
 }
 
 // Tests if the registry is correctly protected by the sandbox.
@@ -112,6 +112,7 @@
 TEST(ValidationSuite, TestDesktop) {
   TestRunner runner;
   runner.GetPolicy()->SetAlternateDesktop(true);
+  runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenInteractiveDesktop NULL"));
   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"SwitchToSboxDesktop NULL"));
 }
@@ -129,7 +130,7 @@
   wchar_t command[1024] = {0};
   runner.SetTimeout(3600000);
   runner.GetPolicy()->SetAlternateDesktop(true);
-  runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED);
+  runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   base::string16 desktop_name = runner.GetPolicy()->GetAlternateDesktop();
   desktop_name = desktop_name.substr(desktop_name.find('\\') + 1);
   wsprintf(command, L"OpenAlternateDesktop %lS", desktop_name.c_str());