diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-17 13:57:45 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-19 13:44:40 +0000 |
commit | 6ec7b8da05d21a3878bd21c691b41e675d74bb1c (patch) | |
tree | b87f250bc19413750b9bb9cdbf2da20ef5014820 /chromium/sandbox | |
parent | ec02ee4181c49b61fce1c8fb99292dbb8139cc90 (diff) | |
download | qtwebengine-chromium-6ec7b8da05d21a3878bd21c691b41e675d74bb1c.tar.gz |
BASELINE: Update Chromium to 60.0.3112.70
Change-Id: I9911c2280a014d4632f254857876a395d4baed2d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/sandbox')
40 files changed, 577 insertions, 1527 deletions
diff --git a/chromium/sandbox/BUILD.gn b/chromium/sandbox/BUILD.gn index 8c0405ed8ec..bb5e7674bcd 100644 --- a/chromium/sandbox/BUILD.gn +++ b/chromium/sandbox/BUILD.gn @@ -5,6 +5,14 @@ import("//build/buildflag_header.gni") import("//sandbox/features.gni") +# Several targets want to include this header file. We separate it out +# here so multiple targets can depend on it. +source_set("sandbox_export") { + sources = [ + "sandbox_export.h", + ] +} + # Meta-target that forwards to the proper platform one. group("sandbox") { if (is_win) { diff --git a/chromium/sandbox/linux/BUILD.gn b/chromium/sandbox/linux/BUILD.gn index d250d216acc..e833e4d71ca 100644 --- a/chromium/sandbox/linux/BUILD.gn +++ b/chromium/sandbox/linux/BUILD.gn @@ -193,7 +193,7 @@ action("bpf_dsl_golden") { test("sandbox_linux_unittests") { deps = [ ":sandbox_linux_unittests_sources", - "//build/config/sanitizers:deps", + "//build/config:exe_and_shlib_deps", ] if (is_android) { use_raw_android_executable = true @@ -240,6 +240,7 @@ component("seccomp_bpf") { public_deps = [ ":sandbox_services_headers", + "//sandbox:sandbox_export", ] deps = [ ":sandbox_services", @@ -339,7 +340,9 @@ component("sandbox_services") { defines = [ "SANDBOX_IMPLEMENTATION" ] - public_deps = [] + public_deps = [ + "//sandbox:sandbox_export", + ] deps = [ "//base", ] @@ -418,7 +421,9 @@ if (compile_suid_client || is_nacl_nonsfi) { "suid/common/suid_unsafe_environment_variables.h", ] defines = [ "SANDBOX_IMPLEMENTATION" ] - + public_deps = [ + "//sandbox:sandbox_export", + ] deps = [ ":sandbox_services", "//base", @@ -434,13 +439,3 @@ if (compile_suid_client || is_nacl_nonsfi) { } } } - -if (is_android) { - # TODO(GYP_GONE) Delete this after we've converted everything to GN. - group("sandbox_linux_unittests_deps") { - testonly = true - deps = [ - ":sandbox_linux_unittests", - ] - } -} diff --git a/chromium/sandbox/linux/services/credentials.cc b/chromium/sandbox/linux/services/credentials.cc index ba2cb7f1fcb..92decad2675 100644 --- a/chromium/sandbox/linux/services/credentials.cc +++ b/chromium/sandbox/linux/services/credentials.cc @@ -154,16 +154,14 @@ int CapabilityToKernelValue(Credentials::Capability cap) { bool SetGidAndUidMaps(gid_t gid, uid_t uid) { const char kGidMapFile[] = "/proc/self/gid_map"; const char kUidMapFile[] = "/proc/self/uid_map"; - struct stat buf; - if (stat(kGidMapFile, &buf) || stat(kGidMapFile, &buf)) { - return false; - } if (NamespaceUtils::KernelSupportsDenySetgroups()) { PCHECK(NamespaceUtils::DenySetgroups()); } DCHECK(GetRESIds(NULL, NULL)); - PCHECK(NamespaceUtils::WriteToIdMapFile(kGidMapFile, gid)); - PCHECK(NamespaceUtils::WriteToIdMapFile(kUidMapFile, uid)); + if (!NamespaceUtils::WriteToIdMapFile(kGidMapFile, gid) || + !NamespaceUtils::WriteToIdMapFile(kUidMapFile, uid)) { + return false; + } DCHECK(GetRESIds(NULL, NULL)); return true; } diff --git a/chromium/sandbox/linux/suid/sandbox.c b/chromium/sandbox/linux/suid/sandbox.c index b655d1c79c4..66f68ef1387 100644 --- a/chromium/sandbox/linux/suid/sandbox.c +++ b/chromium/sandbox/linux/suid/sandbox.c @@ -353,10 +353,10 @@ static bool SetupChildEnvironment() { unsigned i; // ld.so may have cleared several environment variables because we are SUID. - // However, the child process might need them so zygote_host_linux.cc saves a - // copy in SANDBOX_$x. This is safe because we have dropped root by this - // point, so we can only exec a binary with the permissions of the user who - // ran us in the first place. + // However, the child process might need them so zygote_host_impl_linux.cc + // saves a copy in SANDBOX_$x. This is safe because we have dropped root by + // this point, so we can only exec a binary with the permissions of the user + // who ran us in the first place. for (i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) { const char* const envvar = kSUIDUnsafeEnvironmentVariables[i]; diff --git a/chromium/sandbox/mac/BUILD.gn b/chromium/sandbox/mac/BUILD.gn index 5174b54f812..ab446273481 100644 --- a/chromium/sandbox/mac/BUILD.gn +++ b/chromium/sandbox/mac/BUILD.gn @@ -4,6 +4,7 @@ import("//build/config/mac/mac_sdk.gni") import("//testing/test.gni") +import("//third_party/protobuf/proto_library.gni") component("sandbox") { sources = [ @@ -27,21 +28,39 @@ component("sandbox") { defines = [ "SANDBOX_IMPLEMENTATION" ] libs = [ "bsm" ] - + public_deps = [ + "//sandbox:sandbox_export", + ] deps = [ "//base", ] } +proto_library("seatbelt_proto") { + visibility = [ ":*" ] + sources = [ + "seatbelt.proto", + ] +} + component("seatbelt") { sources = [ "sandbox_compiler.cc", "sandbox_compiler.h", "seatbelt.cc", "seatbelt.h", + "seatbelt_exec.cc", + "seatbelt_exec.h", "seatbelt_export.h", ] libs = [ "sandbox" ] + deps = [ + ":seatbelt_proto", + ] + public_deps = [ + "//base", + "//third_party/protobuf:protobuf_lite", + ] defines = [ "SEATBELT_IMPLEMENTATION" ] } @@ -51,6 +70,7 @@ test("sandbox_mac_unittests") { "policy_unittest.cc", "sandbox_mac_compiler_unittest.mm", "sandbox_mac_compiler_v2_unittest.mm", + "sandbox_mac_seatbelt_exec_unittest.cc", "xpc_message_server_unittest.cc", ] @@ -62,6 +82,7 @@ test("sandbox_mac_unittests") { deps = [ ":sandbox", ":seatbelt", + ":seatbelt_proto", "//base", "//base/test:run_all_unittests", "//testing/gtest", diff --git a/chromium/sandbox/mac/sandbox_mac_compiler_unittest.mm b/chromium/sandbox/mac/sandbox_mac_compiler_unittest.mm index 0e9ee97c739..c04d89f97ef 100644 --- a/chromium/sandbox/mac/sandbox_mac_compiler_unittest.mm +++ b/chromium/sandbox/mac/sandbox_mac_compiler_unittest.mm @@ -21,6 +21,7 @@ class SandboxMacCompilerTest : public base::MultiProcessTest {}; MULTIPROCESS_TEST_MAIN(BasicProfileProcess) { std::string profile = "(version 1)" + "(deny default (with no-log))" "(allow file-read* file-write* (literal \"/\"))"; SandboxCompiler compiler(profile); @@ -43,6 +44,7 @@ TEST_F(SandboxMacCompilerTest, BasicProfileTest) { MULTIPROCESS_TEST_MAIN(BasicProfileWithParamProcess) { std::string profile = "(version 1)" + "(deny default (with no-log))" "(allow file-read* file-write* (literal (param \"DIR\")))"; SandboxCompiler compiler(profile); @@ -67,7 +69,7 @@ TEST_F(SandboxMacCompilerTest, BasicProfileTestWithParam) { MULTIPROCESS_TEST_MAIN(ProfileFunctionalProcess) { std::string profile = "(version 1)" - "(debug deny)" + "(deny default (with no-log))" "(allow file-read-data file-read-metadata (literal \"/dev/urandom\"))"; SandboxCompiler compiler(profile); @@ -98,7 +100,7 @@ TEST_F(SandboxMacCompilerTest, ProfileFunctionalityTest) { MULTIPROCESS_TEST_MAIN(ProfileFunctionalTestWithParamsProcess) { std::string profile = "(version 1)" - "(debug deny)" + "(deny default (with no-log))" "(if (string=? (param \"ALLOW_FILE\") \"TRUE\")" " (allow file-read-data file-read-metadata (literal (param " "\"URANDOM\"))))"; diff --git a/chromium/sandbox/mac/sandbox_mac_compiler_v2_unittest.mm b/chromium/sandbox/mac/sandbox_mac_compiler_v2_unittest.mm index adb9895c3ef..4b0ee197b66 100644 --- a/chromium/sandbox/mac/sandbox_mac_compiler_v2_unittest.mm +++ b/chromium/sandbox/mac/sandbox_mac_compiler_v2_unittest.mm @@ -35,7 +35,7 @@ MULTIPROCESS_TEST_MAIN(V2ProfileProcess) { // print the profile out for debugging purposes. std::string profile = "(version 1)\n" - "(deny default)\n" + "(deny default (with no-log))\n" "(define allowed-dir \"ALLOWED_READ_DIR\")\n" "(define temp-file \"ALLOWED_TEMP_FILE\")\n" "(define is-pre-10_10 \"IS_PRE_10_10\")\n" diff --git a/chromium/sandbox/mac/sandbox_mac_seatbelt_exec_unittest.cc b/chromium/sandbox/mac/sandbox_mac_seatbelt_exec_unittest.cc new file mode 100644 index 00000000000..86ae8153e4b --- /dev/null +++ b/chromium/sandbox/mac/sandbox_mac_seatbelt_exec_unittest.cc @@ -0,0 +1,86 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/mac/seatbelt_exec.h" + +#include "base/process/kill.h" +#include "base/test/multiprocess_test.h" +#include "base/test/test_timeouts.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/multiprocess_func_list.h" + +namespace sandbox { + +class SeatbeltExecTest : public base::MultiProcessTest {}; + +MULTIPROCESS_TEST_MAIN(ServerTest) { + std::string profile = + "(version 1)\n" + "(deny default (with no-log))\n" + "(define allowed-dir \"ALLOWED_READ_DIR\")\n" + "(define executable-path \"EXECUTABLE_PATH\")\n" + "(allow process-exec (literal (param executable-path)))\n" + "(allow file-read* (literal (param executable-path)))\n" + "(allow file-read* (subpath (param allowed-dir)))\n"; + + SeatbeltExecServer exec_server(-1); + std::string exec_path = "/bin/ls"; + std::string allowed_path = "/Applications"; + + mac::SandboxPolicy policy; + google::protobuf::MapPair<std::string, std::string> allowed_pair( + "ALLOWED_READ_DIR", allowed_path); + google::protobuf::MapPair<std::string, std::string> exec_pair( + "EXECUTABLE_PATH", exec_path); + CHECK(policy.mutable_params()->insert(allowed_pair).second); + CHECK(policy.mutable_params()->insert(exec_pair).second); + policy.set_profile(profile); + + CHECK(exec_server.ApplySandboxProfile(policy)); + + // Test that the sandbox profile is actually applied. + struct stat sb; + CHECK_EQ(0, stat(allowed_path.c_str(), &sb)); + CHECK_EQ(-1, stat("/", &sb)); + CHECK_EQ(0, stat(exec_path.c_str(), &sb)); + + return 0; +} + +TEST_F(SeatbeltExecTest, ServerTest) { + base::SpawnChildResult spawn_child = SpawnChild("ServerTest"); + ASSERT_TRUE(spawn_child.process.IsValid()); + int exit_code = 42; + EXPECT_TRUE(spawn_child.process.WaitForExitWithTimeout( + TestTimeouts::action_max_timeout(), &exit_code)); + EXPECT_EQ(exit_code, 0); +} + +MULTIPROCESS_TEST_MAIN(ClientTest) { + SeatbeltExecClient exec_client; + + CHECK(exec_client.SetBooleanParameter("key1", true)); + CHECK(!exec_client.SetBooleanParameter("key1", false)); + CHECK(exec_client.SetBooleanParameter("key2", false)); + CHECK(exec_client.SetParameter("key3", "value")); + CHECK(!exec_client.SetParameter("key3", "value")); + exec_client.SetProfile("(version 1)(deny default)"); + + mac::SandboxPolicy policy = exec_client.GetPolicyForTesting(); + CHECK(policy.params_size() == 3); + CHECK(!policy.profile().empty()); + + return 0; +} + +TEST_F(SeatbeltExecTest, ClientTest) { + base::SpawnChildResult spawn_child = SpawnChild("ClientTest"); + ASSERT_TRUE(spawn_child.process.IsValid()); + int exit_code = 42; + EXPECT_TRUE(spawn_child.process.WaitForExitWithTimeout( + TestTimeouts::action_max_timeout(), &exit_code)); + EXPECT_EQ(exit_code, 0); +} + +} // namespace sandbox diff --git a/chromium/sandbox/mac/seatbelt.proto b/chromium/sandbox/mac/seatbelt.proto new file mode 100644 index 00000000000..4615402053c --- /dev/null +++ b/chromium/sandbox/mac/seatbelt.proto @@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; + +package sandbox.mac; + +// Optional fields are considered best practice, but since the client and server +// come from the same code base, this uses required fields to save on +// validation. + +message SandboxPolicy { + required string profile = 1; + map<string, string> params = 2; +} diff --git a/chromium/sandbox/mac/seatbelt_exec.cc b/chromium/sandbox/mac/seatbelt_exec.cc new file mode 100644 index 00000000000..6a1a7b940f6 --- /dev/null +++ b/chromium/sandbox/mac/seatbelt_exec.cc @@ -0,0 +1,133 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/mac/seatbelt_exec.h" + +#include <sys/socket.h> +#include <sys/uio.h> +#include <unistd.h> + +#include <vector> + +#include "base/logging.h" +#include "base/macros.h" +#include "base/posix/eintr_wrapper.h" +#include "base/strings/stringprintf.h" +#include "sandbox/mac/seatbelt.h" + +namespace sandbox { + +SeatbeltExecClient::SeatbeltExecClient() { + PCHECK(pipe(pipe_) == 0) << "pipe"; +} + +SeatbeltExecClient::~SeatbeltExecClient() { + if (pipe_[1] != -1) + IGNORE_EINTR(close(pipe_[1])); + // If pipe() fails, PCHECK() will be hit in the constructor, so this file + // descriptor should always be closed if the proess is alive at this point. + IGNORE_EINTR(close(pipe_[0])); +} + +bool SeatbeltExecClient::SetBooleanParameter(const base::StringPiece key, + bool value) { + google::protobuf::MapPair<std::string, std::string> pair( + key.as_string(), value ? "TRUE" : "FALSE"); + return policy_.mutable_params()->insert(pair).second; +} + +bool SeatbeltExecClient::SetParameter(const base::StringPiece key, + const base::StringPiece value) { + google::protobuf::MapPair<std::string, std::string> pair(key.as_string(), + value.as_string()); + return policy_.mutable_params()->insert(pair).second; +} + +void SeatbeltExecClient::SetProfile(const base::StringPiece policy) { + policy_.set_profile(policy.as_string()); +} + +int SeatbeltExecClient::SendProfileAndGetFD() { + std::string serialized_protobuf; + if (!policy_.SerializeToString(&serialized_protobuf)) + return -1; + + if (!WriteString(&serialized_protobuf)) + return -1; + + IGNORE_EINTR(close(pipe_[1])); + pipe_[1] = -1; + + return pipe_[0]; +} + +bool SeatbeltExecClient::WriteString(std::string* str) { + struct iovec iov[1]; + iov[0].iov_base = &(*str)[0]; + iov[0].iov_len = str->size(); + + ssize_t written = HANDLE_EINTR(writev(pipe_[1], iov, arraysize(iov))); + if (written < 0) { + PLOG(ERROR) << "writev"; + return false; + } + return static_cast<uint64_t>(written) == str->size(); +} + +SeatbeltExecServer::SeatbeltExecServer(int fd) : fd_(fd) {} + +SeatbeltExecServer::~SeatbeltExecServer() {} + +bool SeatbeltExecServer::InitializeSandbox() { + std::string policy_string; + if (!ReadString(&policy_string)) + return false; + + mac::SandboxPolicy policy; + if (!policy.ParseFromString(policy_string)) { + LOG(ERROR) << "ParseFromString failed"; + return false; + } + + return ApplySandboxProfile(policy); +} + +bool SeatbeltExecServer::ApplySandboxProfile(const mac::SandboxPolicy& policy) { + std::vector<const char*> weak_params; + for (const auto& pair : policy.params()) { + weak_params.push_back(pair.first.c_str()); + weak_params.push_back(pair.second.c_str()); + } + weak_params.push_back(nullptr); + + char* error = nullptr; + int rv = Seatbelt::InitWithParams(policy.profile().c_str(), 0, + weak_params.data(), &error); + if (error) { + LOG(ERROR) << "Failed to initialize sandbox: " << rv << " " << error; + Seatbelt::FreeError(error); + return false; + } + + return rv == 0; +} + +bool SeatbeltExecServer::ReadString(std::string* str) { + // 4 pages of memory is enough to hold the sandbox profiles. + std::vector<char> buffer(4096 * 4, '\0'); + + struct iovec iov[1]; + iov[0].iov_base = buffer.data(); + iov[0].iov_len = buffer.size(); + + ssize_t read_length = HANDLE_EINTR(readv(fd_.get(), iov, arraysize(iov))); + if (read_length < 0) { + PLOG(ERROR) << "readv"; + return false; + } + str->assign(buffer.data()); + return true; +} + +} // namespace sandbox diff --git a/chromium/sandbox/mac/seatbelt_exec.h b/chromium/sandbox/mac/seatbelt_exec.h new file mode 100644 index 00000000000..57096ccdefc --- /dev/null +++ b/chromium/sandbox/mac/seatbelt_exec.h @@ -0,0 +1,88 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_MAC_SEATBELT_EXEC_H_ +#define SANDBOX_MAC_SEATBELT_EXEC_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/files/scoped_file.h" +#include "base/strings/string_piece.h" +#include "sandbox/mac/seatbelt.pb.h" +#include "sandbox/mac/seatbelt_export.h" + +namespace sandbox { + +// SeatbeltExecClient is used by the process that is launching another sandboxed +// process. The API allows the launcher process to supply a sandbox profile and +// parameters, which will be communicated to the sandboxed process over IPC. +class SEATBELT_EXPORT SeatbeltExecClient { + public: + SeatbeltExecClient(); + ~SeatbeltExecClient(); + + // The Set*Parameter functions return true if the parameter was successfully + // inserted. Check the return value, which indicates if the parameter was + // added successfully. + + // Set a boolean parameter in the sandbox profile. + bool SetBooleanParameter(const base::StringPiece key, + bool value) WARN_UNUSED_RESULT; + + // Set a string parameter in the sandbox profile. + bool SetParameter(const base::StringPiece key, + const base::StringPiece value) WARN_UNUSED_RESULT; + + // Set the actual sandbox profile, using the scheme-like SBPL. + void SetProfile(const base::StringPiece policy); + + // Sends the policy to the SeatbeltExecServer and returns the communication + // FD. The FD should be mapped into the sandboxed child process. + int SendProfileAndGetFD(); + + // Returns the underlying protobuf for testing purposes. + const mac::SandboxPolicy& GetPolicyForTesting() { return policy_; } + + private: + // This writes a string (the serialized protobuf) to the |pipe_|. + bool WriteString(std::string* str); + + // This is the protobuf which contains the sandbox profile and parameters, + // and is serialized and sent to the other process. + mac::SandboxPolicy policy_; + + // A file descriptor pair used for interprocess communication. + int pipe_[2]; +}; + +// SeatbeltExecServer is used by the process that will be sandboxed to receive +// the profile and parameters from the launcher process. It can then initialize +// the profile, sandboxing the process. +class SEATBELT_EXPORT SeatbeltExecServer { + public: + // |sandbox_fd| should be the result of SendProfileAndGetFD(). + explicit SeatbeltExecServer(int sandbox_fd); + ~SeatbeltExecServer(); + + // Reads the policy from the client, applies the profile, and returns whether + // or not the operation succeeds. + bool InitializeSandbox(); + + // Applies the given sandbox policy, and returns whether or not the operation + // succeeds. + bool ApplySandboxProfile(const mac::SandboxPolicy& sandbox_policy); + + private: + // Reads from the |fd_| and stores the data into a string. This does + // not append a NUL terminator as protobuf does not expect one. + bool ReadString(std::string* string); + + // The file descriptor used to communicate with the launcher process. + base::ScopedFD fd_; +}; + +} // namespace sandbox + +#endif // SANDBOX_MAC_SEATBELT_EXEC_H_ diff --git a/chromium/sandbox/win/BUILD.gn b/chromium/sandbox/win/BUILD.gn index 1d51220c5ab..7bdaf430cbb 100644 --- a/chromium/sandbox/win/BUILD.gn +++ b/chromium/sandbox/win/BUILD.gn @@ -30,6 +30,8 @@ static_library("sandbox") { "src/handle_closer.h", "src/handle_closer_agent.cc", "src/handle_closer_agent.h", + "src/heap_helper.cc", + "src/heap_helper.h", "src/interception.cc", "src/interception.h", "src/interception_agent.cc", @@ -218,7 +220,7 @@ executable("cfi_unittest_exe") { ] deps = [ "//base", - "//build/config/sanitizers:deps", + "//build/config:exe_and_shlib_deps", "//build/win:default_exe_manifest", ] } @@ -314,6 +316,7 @@ shared_library("pocdll") { "sandbox_poc/pocdll/handles.cc", "sandbox_poc/pocdll/invasive.cc", "sandbox_poc/pocdll/network.cc", + "sandbox_poc/pocdll/ntundoc.h", "sandbox_poc/pocdll/pocdll.cc", "sandbox_poc/pocdll/processes_and_threads.cc", "sandbox_poc/pocdll/registry.cc", @@ -324,6 +327,6 @@ shared_library("pocdll") { defines = [ "POCDLL_EXPORTS" ] deps = [ - "//build/config/sanitizers:deps", + "//build/config:exe_and_shlib_deps", ] } diff --git a/chromium/sandbox/win/sandbox_poc/main_ui_window.h b/chromium/sandbox/win/sandbox_poc/main_ui_window.h index b995b34d8d1..5bf98dd4261 100644 --- a/chromium/sandbox/win/sandbox_poc/main_ui_window.h +++ b/chromium/sandbox/win/sandbox_poc/main_ui_window.h @@ -14,7 +14,6 @@ namespace sandbox { class BrokerServices; -enum ResultCode; } // Header file for the MainUIWindow, a simple window with a menu bar that diff --git a/chromium/sandbox/win/sandbox_poc/pocdll/handles.cc b/chromium/sandbox/win/sandbox_poc/pocdll/handles.cc index 1c6116ec6c7..8a51cf8e210 100644 --- a/chromium/sandbox/win/sandbox_poc/pocdll/handles.cc +++ b/chromium/sandbox/win/sandbox_poc/pocdll/handles.cc @@ -3,8 +3,8 @@ // found in the LICENSE file. #include "sandbox/win/sandbox_poc/pocdll/exports.h" +#include "sandbox/win/sandbox_poc/pocdll/ntundoc.h" #include "sandbox/win/sandbox_poc/pocdll/utils.h" -#include "sandbox/win/tools/finder/ntundoc.h" // This file contains the tests used to verify the security of handles in // the process diff --git a/chromium/sandbox/win/tools/finder/ntundoc.h b/chromium/sandbox/win/sandbox_poc/pocdll/ntundoc.h index dc8c3a57cb1..dc8c3a57cb1 100644 --- a/chromium/sandbox/win/tools/finder/ntundoc.h +++ b/chromium/sandbox/win/sandbox_poc/pocdll/ntundoc.h diff --git a/chromium/sandbox/win/src/filesystem_policy.h b/chromium/sandbox/win/src/filesystem_policy.h index c2ee160d504..0ed1e5de6c8 100644 --- a/chromium/sandbox/win/src/filesystem_policy.h +++ b/chromium/sandbox/win/src/filesystem_policy.h @@ -17,8 +17,6 @@ namespace sandbox { -enum EvalResult; - // This class centralizes most of the knowledge related to file system policy class FileSystemPolicy { public: diff --git a/chromium/sandbox/win/src/handle_closer_test.cc b/chromium/sandbox/win/src/handle_closer_test.cc index 1e0ab498394..7e8e732c886 100644 --- a/chromium/sandbox/win/src/handle_closer_test.cc +++ b/chromium/sandbox/win/src/handle_closer_test.cc @@ -289,10 +289,9 @@ TEST(HandleCloserTest, RunThreadPool) { TestRunner runner; runner.SetTimeout(2000); runner.SetTestState(AFTER_REVERT); - sandbox::TargetPolicy* policy = runner.GetPolicy(); - // Sever the CSRSS connection by closing ALPC ports inside the sandbox. - CHECK_EQ(policy->AddKernelObjectToClose(L"ALPC Port", NULL), SBOX_ALL_OK); + // Sandbox policy will determine which platforms to disconnect CSRSS and when + // to close the CSRSS handle. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"RunThreadPool")); } diff --git a/chromium/sandbox/win/src/heap_helper.cc b/chromium/sandbox/win/src/heap_helper.cc new file mode 100644 index 00000000000..605a7ac11a2 --- /dev/null +++ b/chromium/sandbox/win/src/heap_helper.cc @@ -0,0 +1,65 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/win/src/heap_helper.h" + +#include <windows.h> + +#include "base/memory/ref_counted.h" +#include "base/win/windows_version.h" + +namespace sandbox { + +// These are undocumented, but readily found on the internet. +#define HEAP_CLASS_8 0x00008000 // CSR port heap +#define HEAP_CLASS_MASK 0x0000f000 + +// This structure is not documented, but the flags field is the only relevant +// field. +struct _HEAP { + char reserved[0x70]; + DWORD flags; +}; + +bool HeapFlags(HANDLE handle, DWORD* flags) { + if (!handle || !flags) { + // This is an error. + return false; + } + _HEAP* heap = reinterpret_cast<_HEAP*>(handle); + *flags = heap->flags; + return true; +} + +HANDLE FindCsrPortHeap() { + if (base::win::GetVersion() < base::win::VERSION_WIN10) { + // This functionality has not been verified on versions before Win10. + return nullptr; + } + DWORD number_of_heaps = ::GetProcessHeaps(0, NULL); + std::unique_ptr<HANDLE[]> all_heaps(new HANDLE[number_of_heaps]); + if (::GetProcessHeaps(number_of_heaps, all_heaps.get()) != number_of_heaps) + return nullptr; + + // Search for the CSR port heap handle, identified purely based on flags. + HANDLE csr_port_heap = nullptr; + for (size_t i = 0; i < number_of_heaps; ++i) { + HANDLE handle = all_heaps[i]; + DWORD flags = 0; + if (!HeapFlags(handle, &flags)) { + DLOG(ERROR) << "Unable to get flags for this heap"; + continue; + } + if ((flags & HEAP_CLASS_MASK) == HEAP_CLASS_8) { + if (nullptr != csr_port_heap) { + DLOG(ERROR) << "Found multiple suitable CSR Port heaps"; + return nullptr; + } + csr_port_heap = handle; + } + } + return csr_port_heap; +} + +} // namespace sandbox diff --git a/chromium/sandbox/win/src/heap_helper.h b/chromium/sandbox/win/src/heap_helper.h new file mode 100644 index 00000000000..63ce34570cd --- /dev/null +++ b/chromium/sandbox/win/src/heap_helper.h @@ -0,0 +1,21 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <windows.h> + +#include "base/win/windows_version.h" + +namespace sandbox { +// These helper functions are not expected to be used generally, but are exposed +// only to allow direct testing of this functionality. + +// Return the flags for this heap handle. Limited verification of the handle is +// performed. No verification of the flags is performed. +bool HeapFlags(HANDLE handle, DWORD* flags); + +// Return the handle to the CSR Port Heap, return nullptr if none or more than +// one candidate was found. +HANDLE FindCsrPortHeap(); + +} // namespace sandbox diff --git a/chromium/sandbox/win/src/interception.h b/chromium/sandbox/win/src/interception.h index 969b367547d..d21bed30b5f 100644 --- a/chromium/sandbox/win/src/interception.h +++ b/chromium/sandbox/win/src/interception.h @@ -17,12 +17,12 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/strings/string16.h" +#include "sandbox/win/src/interceptors.h" #include "sandbox/win/src/sandbox_types.h" namespace sandbox { class TargetProcess; -enum InterceptorId; // Internal structures used for communication between the broker and the target. struct DllPatchInfo; diff --git a/chromium/sandbox/win/src/interception_internal.h b/chromium/sandbox/win/src/interception_internal.h index 45a0557e5ef..390bd9eb129 100644 --- a/chromium/sandbox/win/src/interception_internal.h +++ b/chromium/sandbox/win/src/interception_internal.h @@ -11,14 +11,13 @@ #include <stddef.h> +#include "sandbox/win/src/interceptors.h" #include "sandbox/win/src/sandbox_types.h" namespace sandbox { const int kMaxThunkDataBytes = 64; -enum InterceptorId; - // The following structures contain variable size fields at the end, and will be // used to transfer information between two processes. In order to guarantee // our ability to follow the chain of structures, the alignment should be fixed, diff --git a/chromium/sandbox/win/src/lpc_policy_test.cc b/chromium/sandbox/win/src/lpc_policy_test.cc index 51931c665e8..8b8e7453626 100644 --- a/chromium/sandbox/win/src/lpc_policy_test.cc +++ b/chromium/sandbox/win/src/lpc_policy_test.cc @@ -12,6 +12,7 @@ #include <winioctl.h> #include "base/win/windows_version.h" +#include "sandbox/win/src/heap_helper.h" #include "sandbox/win/src/sandbox.h" #include "sandbox/win/src/sandbox_factory.h" #include "sandbox/win/src/sandbox_policy.h" @@ -149,4 +150,66 @@ TEST(LpcPolicyTest, GetUserDefaultLocaleName) { EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd.c_str())); } +// Closing ALPC port can invalidate its heap. +// Test that all heaps are valid. +SBOX_TESTS_COMMAND int Lpc_TestValidProcessHeaps(int argc, wchar_t** argv) { + if (argc != 0) + return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; + // Retrieves the number of heaps in the current process. + DWORD number_of_heaps = ::GetProcessHeaps(0, NULL); + // Try to retrieve a handle to all the heaps owned by this process. Returns + // false if the number of heaps has changed. + // + // This is inherently racy as is, but it's not something that we observe a lot + // in Chrome, the heaps tend to be created at startup only. + std::unique_ptr<HANDLE[]> all_heaps(new HANDLE[number_of_heaps]); + if (::GetProcessHeaps(number_of_heaps, all_heaps.get()) != number_of_heaps) + return SBOX_TEST_FAILED; + + for (size_t i = 0; i < number_of_heaps; ++i) { + HANDLE handle = all_heaps[i]; + if (!HeapLock(handle)) { + return SBOX_TEST_FAILED; + } + + if (!HeapUnlock(handle)) { + return SBOX_TEST_FAILED; + } + } + return SBOX_TEST_SUCCEEDED; +} + +TEST(LpcPolicyTest, TestValidProcessHeaps) { + TestRunner runner; + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Lpc_TestValidProcessHeaps")); +} + +// All processes should have a shared heap with csrss.exe. This test ensures +// that this heap can be found. +TEST(LpcPolicyTest, TestCanFindCsrPortHeap) { + if (base::win::GetVersion() < base::win::VERSION_WIN10) { + // This functionality has not been verified on versions before Win10. + return; + } + HANDLE csr_port_handle = sandbox::FindCsrPortHeap(); + EXPECT_NE(nullptr, csr_port_handle); +} + +TEST(LpcPolicyTest, TestHeapFlags) { + if (base::win::GetVersion() < base::win::VERSION_WIN10) { + // This functionality has not been verified on versions before Win10. + return; + } + // Windows does not support callers supplying arbritary flag values. So we + // write some non-trivial value to reduce the chance we match this in random + // data. + DWORD flags = 0x41007; + HANDLE heap = HeapCreate(flags, 0, 0); + EXPECT_NE(nullptr, heap); + DWORD actual_flags = 0; + EXPECT_TRUE(sandbox::HeapFlags(heap, &actual_flags)); + EXPECT_EQ(flags, actual_flags); + EXPECT_TRUE(HeapDestroy(heap)); +} + } // namespace sandbox diff --git a/chromium/sandbox/win/src/named_pipe_policy.h b/chromium/sandbox/win/src/named_pipe_policy.h index 02aa26c6184..20f0e97f8fb 100644 --- a/chromium/sandbox/win/src/named_pipe_policy.h +++ b/chromium/sandbox/win/src/named_pipe_policy.h @@ -14,8 +14,6 @@ namespace sandbox { -enum EvalResult; - // This class centralizes most of the knowledge related to named pipe creation. class NamedPipePolicy { public: diff --git a/chromium/sandbox/win/src/process_mitigations_win32k_dispatcher.cc b/chromium/sandbox/win/src/process_mitigations_win32k_dispatcher.cc index 347cdf14e73..b44164001bb 100644 --- a/chromium/sandbox/win/src/process_mitigations_win32k_dispatcher.cc +++ b/chromium/sandbox/win/src/process_mitigations_win32k_dispatcher.cc @@ -8,6 +8,7 @@ #include "base/memory/shared_memory.h" #include "base/strings/string16.h" +#include "base/unguessable_token.h" #include "base/win/windows_version.h" #include "sandbox/win/src/interception.h" #include "sandbox/win/src/interceptors.h" @@ -20,7 +21,8 @@ namespace sandbox { namespace { base::SharedMemoryHandle GetSharedMemoryHandle(const ClientInfo& client_info, - HANDLE handle) { + HANDLE handle, + size_t size) { HANDLE result_handle = nullptr; intptr_t handle_int = reinterpret_cast<intptr_t>(handle); if (handle_int <= 0 || @@ -28,7 +30,8 @@ base::SharedMemoryHandle GetSharedMemoryHandle(const ClientInfo& client_info, &result_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { result_handle = nullptr; } - return base::SharedMemoryHandle(result_handle, ::GetCurrentProcessId()); + return base::SharedMemoryHandle(result_handle, size, + base::UnguessableToken::Create()); } } // namespace @@ -409,8 +412,8 @@ bool ProcessMitigationsWin32KDispatcher::GetCertificate( ipc->return_info.nt_status = STATUS_ACCESS_DENIED; return true; } - base::SharedMemoryHandle handle = - GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle); + base::SharedMemoryHandle handle = GetSharedMemoryHandle( + *ipc->client_info, shared_buffer_handle, shared_buffer_size); if (!handle.IsValid()) { ipc->return_info.nt_status = STATUS_ACCESS_DENIED; return true; @@ -514,7 +517,8 @@ bool ProcessMitigationsWin32KDispatcher::ConfigureOPMProtectedOutput( return true; }; base::SharedMemoryHandle handle = - GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle); + GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle, + sizeof(DXGKMDT_OPM_CONFIGURE_PARAMETERS)); if (!handle.IsValid()) { ipc->return_info.nt_status = STATUS_ACCESS_DENIED; return true; @@ -545,17 +549,18 @@ bool ProcessMitigationsWin32KDispatcher::GetOPMInformation( ipc->return_info.nt_status = STATUS_ACCESS_DENIED; return true; } - base::SharedMemoryHandle handle = - GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle); + size_t shared_buffer_size = + std::max(sizeof(DXGKMDT_OPM_GET_INFO_PARAMETERS), + sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION)); + + base::SharedMemoryHandle handle = GetSharedMemoryHandle( + *ipc->client_info, shared_buffer_handle, shared_buffer_size); if (!handle.IsValid()) { ipc->return_info.nt_status = STATUS_ACCESS_DENIED; return true; } base::SharedMemory buffer(handle, false); - size_t shared_buffer_size = - std::max(sizeof(DXGKMDT_OPM_GET_INFO_PARAMETERS), - sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION)); if (!buffer.Map(shared_buffer_size)) { ipc->return_info.nt_status = STATUS_ACCESS_DENIED; return true; diff --git a/chromium/sandbox/win/src/process_mitigations_win32k_policy.h b/chromium/sandbox/win/src/process_mitigations_win32k_policy.h index bc39b99e348..1fffdc776ba 100644 --- a/chromium/sandbox/win/src/process_mitigations_win32k_policy.h +++ b/chromium/sandbox/win/src/process_mitigations_win32k_policy.h @@ -12,8 +12,6 @@ namespace sandbox { -enum EvalResult; - // A callback function type to get a function for testing. typedef void* (*OverrideForTestFunction)(const char* name); diff --git a/chromium/sandbox/win/src/process_thread_policy.h b/chromium/sandbox/win/src/process_thread_policy.h index f51d89fc723..f92f9963529 100644 --- a/chromium/sandbox/win/src/process_thread_policy.h +++ b/chromium/sandbox/win/src/process_thread_policy.h @@ -17,8 +17,6 @@ namespace sandbox { -enum EvalResult; - // This class centralizes most of the knowledge related to process execution. class ProcessPolicy { public: diff --git a/chromium/sandbox/win/src/registry_policy.h b/chromium/sandbox/win/src/registry_policy.h index ddea1bf5a14..de4690e3c5c 100644 --- a/chromium/sandbox/win/src/registry_policy.h +++ b/chromium/sandbox/win/src/registry_policy.h @@ -17,8 +17,6 @@ namespace sandbox { -enum EvalResult; - // This class centralizes most of the knowledge related to registry policy class RegistryPolicy { public: diff --git a/chromium/sandbox/win/src/sandbox_policy_base.cc b/chromium/sandbox/win/src/sandbox_policy_base.cc index fbdeb29fea7..391f5599174 100644 --- a/chromium/sandbox/win/src/sandbox_policy_base.cc +++ b/chromium/sandbox/win/src/sandbox_policy_base.cc @@ -196,9 +196,6 @@ JobLevel PolicyBase::GetJobLevel() const { } ResultCode PolicyBase::SetJobMemoryLimit(size_t memory_limit) { - if (memory_limit && job_level_ == JOB_NONE) { - return SBOX_ERROR_BAD_PARAMS; - } memory_limit_ = memory_limit; return SBOX_ALL_OK; } diff --git a/chromium/sandbox/win/src/sandbox_types.h b/chromium/sandbox/win/src/sandbox_types.h index ae36ef5c95f..7282fa53dcf 100644 --- a/chromium/sandbox/win/src/sandbox_types.h +++ b/chromium/sandbox/win/src/sandbox_types.h @@ -13,7 +13,8 @@ namespace sandbox { // Operation result codes returned by the sandbox API. // // Note: These codes are listed in a histogram and any new codes should be added -// at the end. +// at the end. If the underlying type is changed then the forward declaration in +// sandbox_init.h must be updated. // enum ResultCode : int { SBOX_ALL_OK = 0, diff --git a/chromium/sandbox/win/src/sync_policy.h b/chromium/sandbox/win/src/sync_policy.h index 24e5c7d87b6..6cb9d830545 100644 --- a/chromium/sandbox/win/src/sync_policy.h +++ b/chromium/sandbox/win/src/sync_policy.h @@ -17,8 +17,6 @@ namespace sandbox { -enum EvalResult; - // This class centralizes most of the knowledge related to sync policy class SyncPolicy { public: diff --git a/chromium/sandbox/win/src/target_services.cc b/chromium/sandbox/win/src/target_services.cc index ec2fa7134c8..687fdd54b29 100644 --- a/chromium/sandbox/win/src/target_services.cc +++ b/chromium/sandbox/win/src/target_services.cc @@ -12,6 +12,7 @@ #include "base/win/windows_version.h" #include "sandbox/win/src/crosscall_client.h" #include "sandbox/win/src/handle_closer_agent.h" +#include "sandbox/win/src/heap_helper.h" #include "sandbox/win/src/ipc_tags.h" #include "sandbox/win/src/process_mitigations.h" #include "sandbox/win/src/restricted_token_utils.h" @@ -20,6 +21,7 @@ #include "sandbox/win/src/sandbox_types.h" #include "sandbox/win/src/sharedmem_ipc_client.h" +namespace sandbox { namespace { // Flushing a cached key is triggered by just opening the key and closing the @@ -45,16 +47,35 @@ bool FlushCachedRegHandles() { FlushRegKey(HKEY_USERS)); } +// Cleans up this process if CSRSS will be disconnected, as this disconnection +// is not supported Windows behavior. +// Currently, this step requires closing a heap that this shared with csrss.exe. +// Closing the ALPC Port handle to csrss.exe leaves this heap in an invalid +// state. This causes problems if anyone enumerates the heap. +bool CsrssDisconnectCleanup() { + HANDLE csr_port_heap = FindCsrPortHeap(); + if (!csr_port_heap) { + DLOG(ERROR) << "Failed to find CSR Port heap handle"; + return false; + } + HeapDestroy(csr_port_heap); + return true; +} + // Checks if we have handle entries pending and runs the closer. // Updates is_csrss_connected based on which handle types are closed. bool CloseOpenHandles(bool* is_csrss_connected) { - if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) { - sandbox::HandleCloserAgent handle_closer; + if (HandleCloserAgent::NeedsHandlesClosed()) { + HandleCloserAgent handle_closer; handle_closer.InitializeHandlesToClose(is_csrss_connected); + if (!*is_csrss_connected) { + if (!CsrssDisconnectCleanup()) { + return false; + } + } if (!handle_closer.CloseHandles()) return false; } - return true; } @@ -98,12 +119,11 @@ bool WarmupWindowsLocales() { // are not available early. We can't use a regular function static because on // VS2015, because the CRT tries to acquire a lock to guard initialization, but // this code runs before the CRT is initialized. -char g_target_services_memory[sizeof(sandbox::TargetServicesBase)]; -sandbox::TargetServicesBase* g_target_services = nullptr; +char g_target_services_memory[sizeof(TargetServicesBase)]; +TargetServicesBase* g_target_services = nullptr; } // namespace -namespace sandbox { SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; diff --git a/chromium/sandbox/win/tools/finder/finder.cc b/chromium/sandbox/win/tools/finder/finder.cc deleted file mode 100644 index 7753dd03e37..00000000000 --- a/chromium/sandbox/win/tools/finder/finder.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/win/src/restricted_token.h" -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/tools/finder/finder.h" - -Finder::Finder() { - file_output_ = NULL; - object_type_ = 0; - access_type_ = 0; - memset(filesystem_stats_, 0, sizeof(filesystem_stats_)); - memset(registry_stats_, 0, sizeof(registry_stats_)); - memset(kernel_object_stats_, 0, sizeof(kernel_object_stats_)); -} - -Finder::~Finder() { -} - -DWORD Finder::Init(sandbox::TokenLevel token_type, - DWORD object_type, - DWORD access_type, - FILE *file_output) { - DWORD err_code = ERROR_SUCCESS; - - err_code = InitNT(); - if (ERROR_SUCCESS != err_code) - return err_code; - - object_type_ = object_type; - access_type_ = access_type; - file_output_ = file_output; - - err_code = sandbox::CreateRestrictedToken(token_type, - sandbox::INTEGRITY_LEVEL_LAST, - sandbox::PRIMARY, &token_handle_); - return err_code; -} - -DWORD Finder::Scan() { - if (!token_handle_.IsValid()) { - return ERROR_NO_TOKEN; - } - - if (object_type_ & kScanRegistry) { - ParseRegistry(HKEY_LOCAL_MACHINE, L"HKLM\\"); - ParseRegistry(HKEY_USERS, L"HKU\\"); - ParseRegistry(HKEY_CURRENT_CONFIG, L"HKCC\\"); - } - - if (object_type_ & kScanFileSystem) { - ParseFileSystem(L"\\\\?\\C:"); - } - - if (object_type_ & kScanKernelObjects) { - ParseKernelObjects(L"\\"); - } - - return ERROR_SUCCESS; -} diff --git a/chromium/sandbox/win/tools/finder/finder.h b/chromium/sandbox/win/tools/finder/finder.h deleted file mode 100644 index 503447d06f5..00000000000 --- a/chromium/sandbox/win/tools/finder/finder.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SANDBOX_TOOLS_FINDER_FINDER_H_ -#define SANDBOX_TOOLS_FINDER_FINDER_H_ - -#include "base/win/scoped_handle.h" -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/tools/finder/ntundoc.h" - -// Type of stats that we calculate during the Scan operation -enum Stats { - READ = 0, // Number of objects with read access - WRITE, // Number of objects with write access - ALL, // Number of objects with r/w access - PARSE, // Number of objects parsed - BROKEN, // Number of errors while parsing the objects - SIZE_STATS // size of the enum -}; - -const int kScanRegistry = 0x01; -const int kScanFileSystem = 0x02; -const int kScanKernelObjects = 0x04; - -const int kTestForRead = 0x01; -const int kTestForWrite = 0x02; -const int kTestForAll = 0x04; - -#define FS_ERR L"FILE-ERROR" -#define OBJ_ERR L"OBJ-ERROR" -#define REG_ERR L"REG_ERROR" -#define OBJ L"OBJ" -#define FS L"FILE" -#define REG L"REG" - -// The impersonater class will impersonate a token when the object is created -// and revert when the object is going out of scope. -class Impersonater { - public: - Impersonater(HANDLE token_handle) { - if (token_handle) - ::ImpersonateLoggedOnUser(token_handle); - }; - ~Impersonater() { - ::RevertToSelf(); - }; -}; - -// The finder class handles the search of objects (file system, registry, kernel -// objects) on the system that can be opened by a restricted token. It can -// support multiple levels of restriction for the restricted token and can check -// for read, write or r/w access. It outputs the results to a file or stdout. -class Finder { - public: - Finder(); - ~Finder(); - DWORD Init(sandbox::TokenLevel token_type, DWORD object_type, - DWORD access_type, FILE *file_output); - DWORD Scan(); - - private: - // Parses a file system path and perform an access check on all files and - // folder found. - // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the - // win32 error code associated with the error. - DWORD ParseFileSystem(ATL::CString path); - - // Parses a registry hive referenced by "key" and performs an access check on - // all subkeys found. - // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the - // win32 error code associated with the error. - DWORD ParseRegistry(HKEY key, ATL::CString print_name); - - // Parses the kernel namespace beginning at "path" and performs an access - // check on all objects found. However, only some object types are supported, - // all non supported objects are ignored. - // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the - // win32 error code associated with the error. - DWORD ParseKernelObjects(ATL::CString path); - - // Checks if "path" can be accessed with the restricted token. - // Returns the access granted. - DWORD TestFileAccess(ATL::CString path); - - // Checks if the registry key with the path key\name can be accessed with the - // restricted token. - // print_name is only use for logging purpose. - // Returns the access granted. - DWORD TestRegAccess(HKEY key, ATL::CString name, ATL::CString print_name); - - // Checks if the kernel object "path" of type "type" can be accessed with - // the restricted token. - // Returns the access granted. - DWORD TestKernelObjectAccess(ATL::CString path, ATL::CString type); - - // Outputs information to the logfile - void Output(ATL::CString type, ATL::CString access, ATL::CString info) { - fprintf(file_output_, "\n%S;%S;%S", type.GetBuffer(), access.GetBuffer(), - info.GetBuffer()); - }; - - // Output information to the log file. - void Output(ATL::CString type, DWORD error, ATL::CString info) { - fprintf(file_output_, "\n%S;0x%X;%S", type.GetBuffer(), error, - info.GetBuffer()); - }; - - // Set func_to_call to the function pointer of the function used to handle - // requests for the kernel objects of type "type". If the type is not - // supported at the moment the function returns false and the func_to_call - // parameter is not modified. - bool GetFunctionForType(ATL::CString type, NTGENERICOPEN * func_to_call); - - // Initializes the NT function pointers to be able to use all the needed - // functions in NTDDL. - // Returns ERROR_SUCCESS if the function succeeded, otherwise, it returns the - // win32 error code associated with the error. - DWORD InitNT(); - - // Calls func_to_call with the parameters desired_access, object_attributes - // and handle. func_to_call is a pointer to a function to open a kernel - // object. - NTSTATUS NtGenericOpen(ACCESS_MASK desired_access, - OBJECT_ATTRIBUTES *object_attributes, - NTGENERICOPEN func_to_call, - HANDLE *handle); - - // Type of object to check for. - DWORD object_type_; - // Access to try. - DWORD access_type_; - // Output file for the results. - FILE * file_output_; - // Handle to the restricted token. - base::win::ScopedHandle token_handle_; - // Stats containing the number of operations performed on the different - // objects. - int filesystem_stats_[SIZE_STATS]; - int registry_stats_[SIZE_STATS]; - int kernel_object_stats_[SIZE_STATS]; -}; - -#endif // SANDBOX_TOOLS_FINDER_FINDER_H_ diff --git a/chromium/sandbox/win/tools/finder/finder.vcproj b/chromium/sandbox/win/tools/finder/finder.vcproj deleted file mode 100644 index 787c8477c2c..00000000000 --- a/chromium/sandbox/win/tools/finder/finder.vcproj +++ /dev/null @@ -1,201 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="finder" - ProjectGUID="{ACDC2E06-0366-41A4-A646-C37E130A605D}" - RootNamespace="finder" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - ConfigurationType="1" - InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;$(SolutionDir)..\build\common.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="2" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - ConfigurationType="1" - InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\build\common.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <File - RelativePath=".\finder.cc" - > - </File> - <File - RelativePath=".\finder.h" - > - </File> - <File - RelativePath=".\finder_fs.cc" - > - </File> - <File - RelativePath=".\finder_kernel.cc" - > - </File> - <File - RelativePath=".\finder_registry.cc" - > - </File> - <File - RelativePath=".\main.cc" - > - </File> - <File - RelativePath=".\ntundoc.h" - > - </File> - <File - RelativePath=".\stdafx.cc" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\stdafx.h" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/chromium/sandbox/win/tools/finder/finder_fs.cc b/chromium/sandbox/win/tools/finder/finder_fs.cc deleted file mode 100644 index ddcc4bec605..00000000000 --- a/chromium/sandbox/win/tools/finder/finder_fs.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/win/src/restricted_token.h" -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/tools/finder/finder.h" - -DWORD Finder::ParseFileSystem(ATL::CString directory) { - WIN32_FIND_DATA find_data; - HANDLE find; - - //Search for items in the directory. - ATL::CString name_to_search = directory + L"\\*"; - find = ::FindFirstFile(name_to_search, &find_data); - if (INVALID_HANDLE_VALUE == find) { - DWORD error = ::GetLastError(); - Output(FS_ERR, error, directory); - filesystem_stats_[BROKEN]++; - return error; - } - - // parse all files or folders. - do { - if (_tcscmp(find_data.cFileName, L".") == 0 || - _tcscmp(find_data.cFileName, L"..") == 0) - continue; - - ATL::CString complete_name = directory + L"\\" + find_data.cFileName; - TestFileAccess(complete_name); - - // Call recursively the function if the path found is a directory. - if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { - ParseFileSystem(complete_name); - } - } while (::FindNextFile(find, &find_data) != 0); - - DWORD err_code = ::GetLastError(); - ::FindClose(find); - - if (ERROR_NO_MORE_FILES != err_code) { - Output(FS_ERR, err_code, directory); - filesystem_stats_[BROKEN]++; - return err_code; - } - - return ERROR_SUCCESS; -} - -DWORD Finder::TestFileAccess(ATL::CString name) { - Impersonater impersonate(token_handle_); - - filesystem_stats_[PARSE]++; - - HANDLE file; - if (access_type_ & kTestForAll) { - file = ::CreateFile(name.GetBuffer(), - GENERIC_ALL, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (file != INVALID_HANDLE_VALUE) { - filesystem_stats_[ALL]++; - Output(FS, L"R/W", name.GetBuffer()); - ::CloseHandle(file); - return GENERIC_ALL; - } else if (::GetLastError() != ERROR_ACCESS_DENIED) { - Output(FS_ERR, GetLastError(), name); - filesystem_stats_[BROKEN]++; - } - } - - if (access_type_ & kTestForWrite) { - file = ::CreateFile(name.GetBuffer(), - GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (file != INVALID_HANDLE_VALUE) { - filesystem_stats_[WRITE]++; - Output(FS, L"W", name); - ::CloseHandle(file); - return GENERIC_WRITE; - } else if (::GetLastError() != ERROR_ACCESS_DENIED) { - Output(FS_ERR, ::GetLastError(), name); - filesystem_stats_[BROKEN]++; - } - } - - if (access_type_ & kTestForRead) { - file = ::CreateFile(name.GetBuffer(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (file != INVALID_HANDLE_VALUE) { - filesystem_stats_[READ]++; - Output(FS, L"R", name); - ::CloseHandle(file); - return GENERIC_READ; - } else if (::GetLastError() != ERROR_ACCESS_DENIED) { - Output(FS_ERR, GetLastError(), name); - filesystem_stats_[BROKEN]++; - } - } - - return 0; -} diff --git a/chromium/sandbox/win/tools/finder/finder_kernel.cc b/chromium/sandbox/win/tools/finder/finder_kernel.cc deleted file mode 100644 index 430a4c08ab4..00000000000 --- a/chromium/sandbox/win/tools/finder/finder_kernel.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/win/src/restricted_token.h" -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/tools/finder/finder.h" -#include "sandbox/win/tools/finder/ntundoc.h" - -#define BUFFER_SIZE 0x800 -#define CHECKPTR(x) if (!x) return ::GetLastError() - -// NT API -NTQUERYDIRECTORYOBJECT NtQueryDirectoryObject; -NTOPENDIRECTORYOBJECT NtOpenDirectoryObject; -NTOPENEVENT NtOpenEvent; -NTOPENJOBOBJECT NtOpenJobObject; -NTOPENKEYEDEVENT NtOpenKeyedEvent; -NTOPENMUTANT NtOpenMutant; -NTOPENSECTION NtOpenSection; -NTOPENSEMAPHORE NtOpenSemaphore; -NTOPENSYMBOLICLINKOBJECT NtOpenSymbolicLinkObject; -NTOPENTIMER NtOpenTimer; -NTOPENFILE NtOpenFile; -NTCLOSE NtClose; - -DWORD Finder::InitNT() { - HMODULE ntdll_handle = ::LoadLibrary(L"ntdll.dll"); - CHECKPTR(ntdll_handle); - - NtOpenSymbolicLinkObject = (NTOPENSYMBOLICLINKOBJECT) ::GetProcAddress( - ntdll_handle, "NtOpenSymbolicLinkObject"); - CHECKPTR(NtOpenSymbolicLinkObject); - - NtQueryDirectoryObject = (NTQUERYDIRECTORYOBJECT) ::GetProcAddress( - ntdll_handle, "NtQueryDirectoryObject"); - CHECKPTR(NtQueryDirectoryObject); - - NtOpenDirectoryObject = (NTOPENDIRECTORYOBJECT) ::GetProcAddress( - ntdll_handle, "NtOpenDirectoryObject"); - CHECKPTR(NtOpenDirectoryObject); - - NtOpenKeyedEvent = (NTOPENKEYEDEVENT) ::GetProcAddress( - ntdll_handle, "NtOpenKeyedEvent"); - CHECKPTR(NtOpenKeyedEvent); - - NtOpenJobObject = (NTOPENJOBOBJECT) ::GetProcAddress( - ntdll_handle, "NtOpenJobObject"); - CHECKPTR(NtOpenJobObject); - - NtOpenSemaphore = (NTOPENSEMAPHORE) ::GetProcAddress( - ntdll_handle, "NtOpenSemaphore"); - CHECKPTR(NtOpenSemaphore); - - NtOpenSection = (NTOPENSECTION) ::GetProcAddress( - ntdll_handle, "NtOpenSection"); - CHECKPTR(NtOpenSection); - - NtOpenMutant= (NTOPENMUTANT) ::GetProcAddress(ntdll_handle, "NtOpenMutant"); - CHECKPTR(NtOpenMutant); - - NtOpenEvent = (NTOPENEVENT) ::GetProcAddress(ntdll_handle, "NtOpenEvent"); - CHECKPTR(NtOpenEvent); - - NtOpenTimer = (NTOPENTIMER) ::GetProcAddress(ntdll_handle, "NtOpenTimer"); - CHECKPTR(NtOpenTimer); - - NtOpenFile = (NTOPENFILE) ::GetProcAddress(ntdll_handle, "NtOpenFile"); - CHECKPTR(NtOpenFile); - - NtClose = (NTCLOSE) ::GetProcAddress(ntdll_handle, "NtClose"); - CHECKPTR(NtClose); - - return ERROR_SUCCESS; -} - -DWORD Finder::ParseKernelObjects(ATL::CString path) { - UNICODE_STRING unicode_str; - unicode_str.Length = (USHORT)path.GetLength()*2; - unicode_str.MaximumLength = (USHORT)path.GetLength()*2+2; - unicode_str.Buffer = path.GetBuffer(); - - OBJECT_ATTRIBUTES path_attributes; - InitializeObjectAttributes(&path_attributes, - &unicode_str, - 0, // No Attributes - NULL, // No Root Directory - NULL); // No Security Descriptor - - - DWORD object_index = 0; - DWORD data_written = 0; - - // TODO(nsylvain): Do not use BUFFER_SIZE. Try to get the size - // dynamically. - OBJDIR_INFORMATION *object_directory_info = - (OBJDIR_INFORMATION*) ::HeapAlloc(GetProcessHeap(), - 0, - BUFFER_SIZE); - - HANDLE file_handle; - NTSTATUS status_code = NtOpenDirectoryObject(&file_handle, - DIRECTORY_QUERY, - &path_attributes); - if (status_code != 0) - return ERROR_UNIDENTIFIED_ERROR; - - status_code = NtQueryDirectoryObject(file_handle, - object_directory_info, - BUFFER_SIZE, - TRUE, // Get Next Index - TRUE, // Ignore Input Index - &object_index, - &data_written); - - if (status_code != 0) - return ERROR_UNIDENTIFIED_ERROR; - - while (NtQueryDirectoryObject(file_handle, object_directory_info, - BUFFER_SIZE, TRUE, FALSE, &object_index, - &data_written) == 0 ) { - ATL::CString cur_path(object_directory_info->ObjectName.Buffer, - object_directory_info->ObjectName.Length / sizeof(WCHAR)); - - ATL::CString cur_type(object_directory_info->ObjectTypeName.Buffer, - object_directory_info->ObjectTypeName.Length / sizeof(WCHAR)); - - ATL::CString new_path; - if (path == L"\\") { - new_path = path + cur_path; - } else { - new_path = path + L"\\" + cur_path; - } - - TestKernelObjectAccess(new_path, cur_type); - - // Call the function recursively for all subdirectories - if (cur_type == L"Directory") { - ParseKernelObjects(new_path); - } - } - - NtClose(file_handle); - return ERROR_SUCCESS; -} - -DWORD Finder::TestKernelObjectAccess(ATL::CString path, ATL::CString type) { - Impersonater impersonate(token_handle_); - - kernel_object_stats_[PARSE]++; - - NTGENERICOPEN func = NULL; - GetFunctionForType(type, &func); - - if (!func) { - kernel_object_stats_[BROKEN]++; - Output(OBJ_ERR, type + L" Unsupported", path); - return ERROR_UNSUPPORTED_TYPE; - } - - UNICODE_STRING unicode_str; - unicode_str.Length = (USHORT)path.GetLength()*2; - unicode_str.MaximumLength = (USHORT)path.GetLength()*2+2; - unicode_str.Buffer = path.GetBuffer(); - - OBJECT_ATTRIBUTES path_attributes; - InitializeObjectAttributes(&path_attributes, - &unicode_str, - 0, // No Attributes - NULL, // No Root Directory - NULL); // No Security Descriptor - - HANDLE handle; - NTSTATUS status_code = 0; - - if (access_type_ & kTestForAll) { - status_code = NtGenericOpen(GENERIC_ALL, &path_attributes, func, &handle); - if (STATUS_SUCCESS == status_code) { - kernel_object_stats_[ALL]++; - Output(OBJ, L"R/W", path); - NtClose(handle); - return GENERIC_ALL; - } else if (status_code != EXCEPTION_ACCESS_VIOLATION && - status_code != STATUS_ACCESS_DENIED) { - Output(OBJ_ERR, status_code, path); - kernel_object_stats_[BROKEN]++; - } - } - - if (access_type_ & kTestForWrite) { - status_code = NtGenericOpen(GENERIC_WRITE, &path_attributes, func, &handle); - if (STATUS_SUCCESS == status_code) { - kernel_object_stats_[WRITE]++; - Output(OBJ, L"W", path); - NtClose(handle); - return GENERIC_WRITE; - } else if (status_code != EXCEPTION_ACCESS_VIOLATION && - status_code != STATUS_ACCESS_DENIED) { - Output(OBJ_ERR, status_code, path); - kernel_object_stats_[BROKEN]++; - } - } - - if (access_type_ & kTestForRead) { - status_code = NtGenericOpen(GENERIC_READ, &path_attributes, func, &handle); - if (STATUS_SUCCESS == status_code) { - kernel_object_stats_[READ]++; - Output(OBJ, L"R", path); - NtClose(handle); - return GENERIC_READ; - } else if (status_code != EXCEPTION_ACCESS_VIOLATION && - status_code != STATUS_ACCESS_DENIED) { - Output(OBJ_ERR, status_code, path); - kernel_object_stats_[BROKEN]++; - } - } - - return 0; -} - -NTSTATUS Finder::NtGenericOpen(ACCESS_MASK desired_access, - OBJECT_ATTRIBUTES *object_attributes, - NTGENERICOPEN func_to_call, - HANDLE *handle) { - return func_to_call(handle, desired_access, object_attributes); -} - -bool Finder::GetFunctionForType(ATL::CString type, - NTGENERICOPEN * func_to_call) { - NTGENERICOPEN func = NULL; - - if (type == L"Event") func = NtOpenEvent; - else if (type == L"Job") func = NtOpenJobObject; - else if (type == L"KeyedEvent") func = NtOpenKeyedEvent; - else if (type == L"Mutant") func = NtOpenMutant; - else if (type == L"Section") func = NtOpenSection; - else if (type == L"Semaphore") func = NtOpenSemaphore; - else if (type == L"Timer") func = NtOpenTimer; - else if (type == L"SymbolicLink") func = NtOpenSymbolicLinkObject; - else if (type == L"Directory") func = NtOpenDirectoryObject; - - if (func) { - *func_to_call = func; - return true; - } - - return false; -} diff --git a/chromium/sandbox/win/tools/finder/finder_registry.cc b/chromium/sandbox/win/tools/finder/finder_registry.cc deleted file mode 100644 index a84e413d326..00000000000 --- a/chromium/sandbox/win/tools/finder/finder_registry.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/win/src/restricted_token.h" -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/tools/finder/finder.h" - -DWORD Finder::ParseRegistry(HKEY key, ATL::CString print_name) { - DWORD index = 0; - DWORD name_size = 2048; - wchar_t buffer[2048] = {0}; - // TODO(nsylvain): Don't hardcode 2048. Get the key len by calling the - // function. - LONG err_code = ::RegEnumKey(key, index, buffer, name_size); - while (ERROR_SUCCESS == err_code) { - ATL::CString name_complete = print_name + buffer + L"\\"; - TestRegAccess(key, buffer, name_complete); - - // Call the function recursively to parse all subkeys - HKEY key_to_parse; - err_code = ::RegOpenKeyEx(key, buffer, 0, KEY_ENUMERATE_SUB_KEYS, - &key_to_parse); - if (ERROR_SUCCESS == err_code) { - ParseRegistry(key_to_parse, name_complete); - ::RegCloseKey(key_to_parse); - } else { - registry_stats_[BROKEN]++; - Output(REG_ERR, err_code, name_complete); - } - - index++; - err_code = ::RegEnumKey(key, index, buffer, name_size); - } - - if (ERROR_NO_MORE_ITEMS != err_code) { - registry_stats_[BROKEN]++; - Output(REG_ERR, err_code, print_name); - } - - return ERROR_SUCCESS; -} - -DWORD Finder::TestRegAccess(HKEY key, ATL::CString name, - ATL::CString print_name) { - Impersonater impersonate(token_handle_); - - registry_stats_[PARSE]++; - - HKEY key_res; - LONG err_code = 0; - - if (access_type_ & kTestForAll) { - err_code = ::RegOpenKeyEx(key, name, 0, GENERIC_ALL, &key_res); - if (ERROR_SUCCESS == err_code) { - registry_stats_[ALL]++; - Output(REG, L"R/W", print_name); - ::RegCloseKey(key_res); - return GENERIC_ALL; - } else if (err_code != ERROR_ACCESS_DENIED) { - Output(REG_ERR, err_code, print_name); - registry_stats_[BROKEN]++; - } - } - - if (access_type_ & kTestForWrite) { - err_code = ::RegOpenKeyEx(key, name, 0, GENERIC_WRITE, &key_res); - if (ERROR_SUCCESS == err_code) { - registry_stats_[WRITE]++; - Output(REG, L"W", print_name); - ::RegCloseKey(key_res); - return GENERIC_WRITE; - } else if (err_code != ERROR_ACCESS_DENIED) { - Output(REG_ERR, err_code, print_name); - registry_stats_[BROKEN]++; - } - } - - if (access_type_ & kTestForRead) { - err_code = ::RegOpenKeyEx(key, name, 0, GENERIC_READ, &key_res); - if (ERROR_SUCCESS == err_code) { - registry_stats_[READ]++; - Output(REG, L"R", print_name); - ::RegCloseKey(key_res); - return GENERIC_READ; - } else if (err_code != ERROR_ACCESS_DENIED) { - Output(REG_ERR, err_code, print_name); - registry_stats_[BROKEN]++; - } - } - - return 0; -} diff --git a/chromium/sandbox/win/tools/finder/main.cc b/chromium/sandbox/win/tools/finder/main.cc deleted file mode 100644 index 7cadbef8f69..00000000000 --- a/chromium/sandbox/win/tools/finder/main.cc +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/tools/finder/finder.h" - -#define PARAM_IS(y) (argc > i) && (_wcsicmp(argv[i], y) == 0) - -void PrintUsage(wchar_t *application_name) { - wprintf(L"\n\nUsage: \n %ls --token type --object ob1 [ob2 ob3] " - L"--access ac1 [ac2 ac3] [--log filename]", application_name); - wprintf(L"\n\n Token Types : \n\tLOCKDOWN \n\tRESTRICTED " - L"\n\tLIMITED_USER \n\tINTERACTIVE_USER \n\tNON_ADMIN \n\tUNPROTECTED"); - wprintf(L"\n Object Types: \n\tREG \n\tFILE \n\tKERNEL"); - wprintf(L"\n Access Types: \n\tR \n\tW \n\tALL"); - wprintf(L"\n\nSample: \n %ls --token LOCKDOWN --object REG FILE KERNEL " - L"--access R W ALL", application_name); -} - -int wmain(int argc, wchar_t* argv[]) { - // Extract the filename from the path. - wchar_t *app_name = wcsrchr(argv[0], L'\\'); - if (!app_name) { - app_name = argv[0]; - } else { - app_name++; - } - - // parameters to read - ATL::CString log_file; - sandbox::TokenLevel token_type = sandbox::USER_LOCKDOWN; - DWORD object_type = 0; - DWORD access_type = 0; - - // no arguments - if (argc == 1) { - PrintUsage(app_name); - return -1; - } - - // parse command line. - for (int i = 1; i < argc; ++i) { - if (PARAM_IS(L"--token")) { - i++; - if (argc > i) { - if (PARAM_IS(L"LOCKDOWN")) { - token_type = sandbox::USER_LOCKDOWN; - } else if (PARAM_IS(L"RESTRICTED")) { - token_type = sandbox::USER_RESTRICTED; - } else if (PARAM_IS(L"LIMITED_USER")) { - token_type = sandbox::USER_LIMITED; - } else if (PARAM_IS(L"INTERACTIVE_USER")) { - token_type = sandbox::USER_INTERACTIVE; - } else if (PARAM_IS(L"NON_ADMIN")) { - token_type = sandbox::USER_NON_ADMIN; - } else if (PARAM_IS(L"USER_RESTRICTED_SAME_ACCESS")) { - token_type = sandbox::USER_RESTRICTED_SAME_ACCESS; - } else if (PARAM_IS(L"UNPROTECTED")) { - token_type = sandbox::USER_UNPROTECTED; - } else { - wprintf(L"\nAbord. Invalid token type \"%ls\"", argv[i]); - PrintUsage(app_name); - return -1; - } - } - } else if (PARAM_IS(L"--object")) { - bool is_object = true; - do { - i++; - if (PARAM_IS(L"REG")) { - object_type |= kScanRegistry; - } else if (PARAM_IS(L"FILE")) { - object_type |= kScanFileSystem; - } else if (PARAM_IS(L"KERNEL")) { - object_type |= kScanKernelObjects; - } else { - is_object = false; - } - } while(is_object); - i--; - } else if (PARAM_IS(L"--access")) { - bool is_access = true; - do { - i++; - if (PARAM_IS(L"R")) { - access_type |= kTestForRead; - } else if (PARAM_IS(L"W")) { - access_type |= kTestForWrite; - } else if (PARAM_IS(L"ALL")) { - access_type |= kTestForAll; - } else { - is_access = false; - } - } while(is_access); - i--; - } else if (PARAM_IS(L"--log")) { - i++; - if (argc > i) { - log_file = argv[i]; - } - else { - wprintf(L"\nAbord. No log file specified"); - PrintUsage(app_name); - return -1; - } - } else { - wprintf(L"\nAbord. Unrecognized parameter \"%ls\"", argv[i]); - PrintUsage(app_name); - return -1; - } - } - - // validate parameters - if (0 == access_type) { - wprintf(L"\nAbord, Access type not specified"); - PrintUsage(app_name); - return -1; - } - - if (0 == object_type) { - wprintf(L"\nAbord, Object type not specified"); - PrintUsage(app_name); - return -1; - } - - - // Open log file - FILE * file_output; - if (log_file.GetLength()) { - errno_t err = _wfopen_s(&file_output, log_file, L"w"); - if (err) { - wprintf(L"\nAbord, Cannot open file \"%ls\"", log_file.GetBuffer()); - return -1; - } - } else { - file_output = stdout; - } - - Finder finder_obj; - finder_obj.Init(token_type, object_type, access_type, file_output); - finder_obj.Scan(); - - fclose(file_output); - - return 0; -} diff --git a/chromium/sandbox/win/tools/launcher/launcher.cc b/chromium/sandbox/win/tools/launcher/launcher.cc deleted file mode 100644 index a037702a43c..00000000000 --- a/chromium/sandbox/win/tools/launcher/launcher.cc +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/win/scoped_handle.h" -#include "base/win/scoped_process_information.h" -#include "base/win/windows_version.h" -#include "sandbox/win/src/restricted_token_utils.h" - -// launcher.exe is an application used to launch another application with a -// restricted token. This is to be used for testing only. -// The parameters are the level of security of the primary token, the -// impersonation token and the job object along with the command line to -// execute. -// See the usage (launcher.exe without parameters) for the correct format. - -namespace { - -// Starts the process described by the input parameter command_line in a job -// with a restricted token. Also set the main thread of this newly created -// process to impersonate a user with more rights so it can initialize -// correctly. -// -// Parameters: primary_level is the security level of the primary token. -// impersonation_level is the security level of the impersonation token used -// to initialize the process. job_level is the security level of the job -// object used to encapsulate the process. -// -// The output parameter job_handle is the handle to the job object. Closing this -// handle will kill the process started. -// -// Note: The process started with this function has to call RevertToSelf() as -// soon as possible to stop using the impersonation token and start being -// secure. -// -// Note: The Unicode version of this function will fail if the command_line -// parameter is a const string. -DWORD StartRestrictedProcessInJob(wchar_t* command_line, - TokenLevel primary_level, - TokenLevel impersonation_level, - JobLevel job_level, - base::win::ScopedHandle* job_handle) { - Job job; - DWORD err_code = job.Init(job_level, NULL, 0, 0); - if (ERROR_SUCCESS != err_code) - return err_code; - - if (JOB_UNPROTECTED != job_level) { - // Share the Desktop handle to be able to use MessageBox() in the sandboxed - // application. - err_code = job.UserHandleGrantAccess(GetDesktopWindow()); - if (ERROR_SUCCESS != err_code) - return err_code; - } - - // Create the primary (restricted) token for the process - base::win::ScopedHandle primary_token; - err_code = sandbox::CreateRestrictedToken(primary_level, INTEGRITY_LEVEL_LAST, - PRIMARY, &primary_token); - if (ERROR_SUCCESS != err_code) - return err_code; - - - // Create the impersonation token (restricted) to be able to start the - // process. - base::win::ScopedHandle impersonation_token; - err_code = sandbox::CreateRestrictedToken(impersonation_level, - INTEGRITY_LEVEL_LAST, - IMPERSONATION, - &impersonation_token); - if (ERROR_SUCCESS != err_code) - return err_code; - - // Start the process - STARTUPINFO startup_info = {0}; - PROCESS_INFORMATION temp_process_info = {}; - DWORD flags = CREATE_SUSPENDED; - - if (base::win::GetVersion() < base::win::VERSION_WIN8) { - // Windows 8 implements nested jobs, but for older systems we need to - // break out of any job we're in to enforce our restrictions. - flags |= CREATE_BREAKAWAY_FROM_JOB; - } - - if (!::CreateProcessAsUser(primary_token.Get(), - NULL, // No application name. - command_line, - NULL, // No security attribute. - NULL, // No thread attribute. - FALSE, // Do not inherit handles. - flags, - NULL, // Use the environment of the caller. - NULL, // Use current directory of the caller. - &startup_info, - &temp_process_info)) { - return ::GetLastError(); - } - base::win::ScopedProcessInformation process_info(temp_process_info); - - // Change the token of the main thread of the new process for the - // impersonation token with more rights. - { - HANDLE temp_thread = process_info.thread_handle(); - if (!::SetThreadToken(&temp_thread, impersonation_token.Get())) { - auto last_error = ::GetLastError(); - ::TerminateProcess(process_info.process_handle(), - 0); // exit code - return last_error; - } - } - - err_code = job.AssignProcessToJob(process_info.process_handle()); - if (ERROR_SUCCESS != err_code) { - auto last_error = ::GetLastError(); - ::TerminateProcess(process_info.process_handle(), - 0); // exit code - return last_error; - } - - // Start the application - ::ResumeThread(process_info.thread_handle()); - - *job_handle = job.Take(); - - return ERROR_SUCCESS; -} - -} // namespace - -#define PARAM_IS(y) (argc > i) && (_wcsicmp(argv[i], y) == 0) - -void PrintUsage(const wchar_t *application_name) { - wprintf(L"\n\nUsage: \n %ls --main level --init level --job level cmd_line ", - application_name); - wprintf(L"\n\n Levels : \n\tLOCKDOWN \n\tRESTRICTED " - L"\n\tLIMITED_USER \n\tINTERACTIVE_USER \n\tNON_ADMIN \n\tUNPROTECTED"); - wprintf(L"\n\n main: Security level of the main token"); - wprintf(L"\n init: Security level of the impersonation token"); - wprintf(L"\n job: Security level of the job object"); -} - -bool GetTokenLevelFromString(const wchar_t *param, - sandbox::TokenLevel* level) { - if (_wcsicmp(param, L"LOCKDOWN") == 0) { - *level = sandbox::USER_LOCKDOWN; - } else if (_wcsicmp(param, L"RESTRICTED") == 0) { - *level = sandbox::USER_RESTRICTED; - } else if (_wcsicmp(param, L"LIMITED_USER") == 0) { - *level = sandbox::USER_LIMITED; - } else if (_wcsicmp(param, L"INTERACTIVE_USER") == 0) { - *level = sandbox::USER_INTERACTIVE; - } else if (_wcsicmp(param, L"NON_ADMIN") == 0) { - *level = sandbox::USER_NON_ADMIN; - } else if (_wcsicmp(param, L"USER_RESTRICTED_SAME_ACCESS") == 0) { - *level = sandbox::USER_RESTRICTED_SAME_ACCESS; - } else if (_wcsicmp(param, L"UNPROTECTED") == 0) { - *level = sandbox::USER_UNPROTECTED; - } else { - return false; - } - - return true; -} - -bool GetJobLevelFromString(const wchar_t *param, sandbox::JobLevel* level) { - if (_wcsicmp(param, L"LOCKDOWN") == 0) { - *level = sandbox::JOB_LOCKDOWN; - } else if (_wcsicmp(param, L"RESTRICTED") == 0) { - *level = sandbox::JOB_RESTRICTED; - } else if (_wcsicmp(param, L"LIMITED_USER") == 0) { - *level = sandbox::JOB_LIMITED_USER; - } else if (_wcsicmp(param, L"INTERACTIVE_USER") == 0) { - *level = sandbox::JOB_INTERACTIVE; - } else if (_wcsicmp(param, L"NON_ADMIN") == 0) { - wprintf(L"\nNON_ADMIN is not a supported job type"); - return false; - } else if (_wcsicmp(param, L"UNPROTECTED") == 0) { - *level = sandbox::JOB_UNPROTECTED; - } else { - return false; - } - - return true; -} - -int wmain(int argc, wchar_t *argv[]) { - // Extract the filename from the path. - wchar_t *app_name = wcsrchr(argv[0], L'\\'); - if (!app_name) { - app_name = argv[0]; - } else { - app_name++; - } - - // no argument - if (argc == 1) { - PrintUsage(app_name); - return -1; - } - - sandbox::TokenLevel primary_level = sandbox::USER_LOCKDOWN; - sandbox::TokenLevel impersonation_level = - sandbox::USER_RESTRICTED_SAME_ACCESS; - sandbox::JobLevel job_level = sandbox::JOB_LOCKDOWN; - ATL::CString command_line; - - // parse command line. - for (int i = 1; i < argc; ++i) { - if (PARAM_IS(L"--main")) { - i++; - if (argc > i) { - if (!GetTokenLevelFromString(argv[i], &primary_level)) { - wprintf(L"\nAbord, Unrecognized main token level \"%ls\"", argv[i]); - PrintUsage(app_name); - return -1; - } - } - } else if (PARAM_IS(L"--init")) { - i++; - if (argc > i) { - if (!GetTokenLevelFromString(argv[i], &impersonation_level)) { - wprintf(L"\nAbord, Unrecognized init token level \"%ls\"", argv[i]); - PrintUsage(app_name); - return -1; - } - } - } else if (PARAM_IS(L"--job")) { - i++; - if (argc > i) { - if (!GetJobLevelFromString(argv[i], &job_level)) { - wprintf(L"\nAbord, Unrecognized job security level \"%ls\"", argv[i]); - PrintUsage(app_name); - return -1; - } - } - } else { - if (command_line.GetLength()) { - command_line += L' '; - } - command_line += argv[i]; - } - } - - if (!command_line.GetLength()) { - wprintf(L"\nAbord, No command line specified"); - PrintUsage(app_name); - return -1; - } - - wprintf(L"\nLaunching command line: \"%ls\"\n", command_line.GetBuffer()); - - base::win::ScopedHandle job_handle; - DWORD err_code = StartRestrictedProcessInJob( - command_line.GetBuffer(), - primary_level, - impersonation_level, - job_level, - &job_handle); - if (ERROR_SUCCESS != err_code) { - wprintf(L"\nAbord, Error %d while launching command line.", err_code); - return -1; - } - - wprintf(L"\nPress any key to continue."); - while(!_kbhit()) { - Sleep(100); - } - - return 0; -} diff --git a/chromium/sandbox/win/tools/launcher/launcher.vcproj b/chromium/sandbox/win/tools/launcher/launcher.vcproj deleted file mode 100644 index 71ed011d2b2..00000000000 --- a/chromium/sandbox/win/tools/launcher/launcher.vcproj +++ /dev/null @@ -1,177 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="launcher" - ProjectGUID="{386FA217-FBC2-4461-882D-CDAD221ED800}" - RootNamespace="launcher" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - ConfigurationType="1" - InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;$(SolutionDir)..\build\common.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="2" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - ConfigurationType="1" - InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\build\common.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <File - RelativePath=".\launcher.cc" - > - </File> - <File - RelativePath=".\stdafx.cc" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\stdafx.h" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> |