diff options
author | Hidehiko Abe <hidehiko@google.com> | 2018-02-08 02:51:59 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-02-08 02:51:59 +0000 |
commit | 47916478b6e3a9c84e3e36939027ffc6b151aec8 (patch) | |
tree | 93f1e1795cacfa1dfd6173ffe2ec8e1e0071b572 | |
parent | 71b35b0847a13797ee777b614eef51578513b4ee (diff) | |
parent | 7245dd98b3ecdda3e0be84e9477d9e0ab5fdc47b (diff) | |
download | libchrome-47916478b6e3a9c84e3e36939027ffc6b151aec8.tar.gz |
Remove sandbox/.
am: 7245dd98b3
Change-Id: I218b8bef49015660d0b0a117b5bd5876b36ad7d3
168 files changed, 0 insertions, 34076 deletions
diff --git a/SConstruct b/SConstruct index 49cef6f434..77cdbdfde3 100644 --- a/SConstruct +++ b/SConstruct @@ -292,48 +292,6 @@ base_libs = [ 'libs' : '%s-dl-%s' % (base_name, BASE_VER), 'pc_libs' : 'nss openssl', }, - { - 'name' : 'sandbox', - 'sources' : """ - linux/bpf_dsl/bpf_dsl.cc - linux/bpf_dsl/codegen.cc - linux/bpf_dsl/dump_bpf.cc - linux/bpf_dsl/policy.cc - linux/bpf_dsl/policy_compiler.cc - linux/bpf_dsl/syscall_set.cc - linux/bpf_dsl/verifier.cc - linux/seccomp-bpf/die.cc - linux/seccomp-bpf/sandbox_bpf.cc - linux/seccomp-bpf/syscall.cc - linux/seccomp-bpf/trap.cc - - linux/seccomp-bpf-helpers/baseline_policy.cc - linux/seccomp-bpf-helpers/sigsys_handlers.cc - linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc - linux/seccomp-bpf-helpers/syscall_sets.cc - - linux/services/init_process_reaper.cc - linux/services/proc_util.cc - linux/services/resource_limits.cc - linux/services/scoped_process.cc - linux/services/syscall_wrappers.cc - linux/services/thread_helpers.cc - linux/services/yama.cc - linux/syscall_broker/broker_channel.cc - linux/syscall_broker/broker_client.cc - linux/syscall_broker/broker_file_permission.cc - linux/syscall_broker/broker_host.cc - linux/syscall_broker/broker_policy.cc - linux/syscall_broker/broker_process.cc - - linux/services/credentials.cc - linux/services/namespace_sandbox.cc - linux/services/namespace_utils.cc - """, - 'prefix' : 'sandbox', - 'libs' : '', - 'pc_libs' : '', - }, ] env.Append( diff --git a/sandbox/BUILD.gn b/sandbox/BUILD.gn deleted file mode 100644 index 8c0405ed8e..0000000000 --- a/sandbox/BUILD.gn +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2014 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. - -import("//build/buildflag_header.gni") -import("//sandbox/features.gni") - -# Meta-target that forwards to the proper platform one. -group("sandbox") { - if (is_win) { - public_deps = [ - "//sandbox/win:sandbox", - ] - } else if (is_mac) { - public_deps = [ - "//sandbox/mac:sandbox", - "//sandbox/mac:seatbelt", - ] - } else if (is_linux || is_android) { - public_deps = [ - "//sandbox/linux:sandbox", - ] - } -} - -buildflag_header("sandbox_features") { - header = "sandbox_features.h" - flags = [ "USE_SECCOMP_BPF=$use_seccomp_bpf" ] -} diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn deleted file mode 100644 index 3e98defa5c..0000000000 --- a/sandbox/linux/BUILD.gn +++ /dev/null @@ -1,441 +0,0 @@ -# Copyright 2014 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. - -import("//build/config/features.gni") -import("//build/config/nacl/config.gni") -import("//sandbox/features.gni") -import("//testing/test.gni") - -if (is_android) { - import("//build/config/android/rules.gni") -} - -declare_args() { - compile_suid_client = is_linux - - compile_credentials = is_linux - - # On Android, use plain GTest. - use_base_test_suite = is_linux -} - -if (is_nacl_nonsfi) { - config("nacl_nonsfi_warnings") { - # There are number of platform specific functions in - # seccomp-bpf syscall helpers, which are not being used. - cflags = [ "-Wno-unused-function" ] - } -} - -# We have two principal targets: sandbox and sandbox_linux_unittests -# All other targets are listed as dependencies. -# There is one notable exception: for historical reasons, chrome_sandbox is -# the setuid sandbox and is its own target. - -group("sandbox") { - public_deps = [ - ":sandbox_services", - ] - - if (compile_suid_client || is_nacl_nonsfi) { - public_deps += [ ":suid_sandbox_client" ] - } - if (use_seccomp_bpf || is_nacl_nonsfi) { - public_deps += [ ":seccomp_bpf" ] - } -} - -source_set("sandbox_linux_test_utils") { - testonly = true - sources = [ - "tests/sandbox_test_runner.cc", - "tests/sandbox_test_runner.h", - "tests/sandbox_test_runner_function_pointer.cc", - "tests/sandbox_test_runner_function_pointer.h", - "tests/unit_tests.cc", - "tests/unit_tests.h", - ] - - deps = [ - "//testing/gtest", - ] - - if (!is_nacl_nonsfi) { - sources += [ - "tests/test_utils.cc", - "tests/test_utils.h", - ] - } - - if (use_seccomp_bpf || is_nacl_nonsfi) { - sources += [ - "seccomp-bpf/bpf_tester_compatibility_delegate.h", - "seccomp-bpf/bpf_tests.h", - "seccomp-bpf/sandbox_bpf_test_runner.cc", - "seccomp-bpf/sandbox_bpf_test_runner.h", - ] - deps += [ ":seccomp_bpf" ] - } - - if (use_base_test_suite) { - deps += [ "//base/test:test_support" ] - defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ] - } -} - -# Sources for sandbox_linux_unittests. -source_set("sandbox_linux_unittests_sources") { - testonly = true - - sources = [ - "services/proc_util_unittest.cc", - "services/resource_limits_unittests.cc", - "services/scoped_process_unittest.cc", - "services/syscall_wrappers_unittest.cc", - "services/thread_helpers_unittests.cc", - "services/yama_unittests.cc", - "syscall_broker/broker_file_permission_unittest.cc", - "syscall_broker/broker_process_unittest.cc", - "tests/main.cc", - "tests/scoped_temporary_file.cc", - "tests/scoped_temporary_file.h", - "tests/scoped_temporary_file_unittest.cc", - "tests/test_utils_unittest.cc", - "tests/unit_tests_unittest.cc", - ] - - deps = [ - ":sandbox", - ":sandbox_linux_test_utils", - "//base", - "//testing/gtest", - ] - - if (use_base_test_suite) { - deps += [ "//base/test:test_support" ] - defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ] - } - - if (compile_suid_client) { - sources += [ - "suid/client/setuid_sandbox_client_unittest.cc", - "suid/client/setuid_sandbox_host_unittest.cc", - ] - } - if (use_seccomp_bpf) { - sources += [ - "bpf_dsl/bpf_dsl_unittest.cc", - "bpf_dsl/codegen_unittest.cc", - "bpf_dsl/cons_unittest.cc", - "bpf_dsl/dump_bpf.cc", - "bpf_dsl/dump_bpf.h", - "bpf_dsl/syscall_set_unittest.cc", - "bpf_dsl/test_trap_registry.cc", - "bpf_dsl/test_trap_registry.h", - "bpf_dsl/test_trap_registry_unittest.cc", - "bpf_dsl/verifier.cc", - "bpf_dsl/verifier.h", - "integration_tests/bpf_dsl_seccomp_unittest.cc", - "integration_tests/seccomp_broker_process_unittest.cc", - "seccomp-bpf-helpers/baseline_policy_unittest.cc", - "seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc", - "seccomp-bpf/bpf_tests_unittest.cc", - "seccomp-bpf/sandbox_bpf_unittest.cc", - "seccomp-bpf/syscall_unittest.cc", - "seccomp-bpf/trap_unittest.cc", - ] - deps += [ ":bpf_dsl_golden" ] - } - if (compile_credentials) { - sources += [ - "integration_tests/namespace_unix_domain_socket_unittest.cc", - "services/credentials_unittest.cc", - "services/namespace_utils_unittest.cc", - ] - - if (use_base_test_suite) { - # Tests that use advanced features not available in stock GTest. - sources += [ "services/namespace_sandbox_unittest.cc" ] - } - - # For credentials_unittest.cc - configs += [ "//build/config/linux:libcap" ] - } -} - -action("bpf_dsl_golden") { - script = "bpf_dsl/golden/generate.py" - inputs = [ - "bpf_dsl/golden/i386/ArgSizePolicy.txt", - "bpf_dsl/golden/i386/BasicPolicy.txt", - "bpf_dsl/golden/i386/ElseIfPolicy.txt", - "bpf_dsl/golden/i386/MaskingPolicy.txt", - "bpf_dsl/golden/i386/MoreBooleanLogicPolicy.txt", - "bpf_dsl/golden/i386/NegativeConstantsPolicy.txt", - "bpf_dsl/golden/i386/SwitchPolicy.txt", - "bpf_dsl/golden/x86-64/ArgSizePolicy.txt", - "bpf_dsl/golden/x86-64/BasicPolicy.txt", - "bpf_dsl/golden/x86-64/BooleanLogicPolicy.txt", - "bpf_dsl/golden/x86-64/ElseIfPolicy.txt", - "bpf_dsl/golden/x86-64/MaskingPolicy.txt", - "bpf_dsl/golden/x86-64/MoreBooleanLogicPolicy.txt", - "bpf_dsl/golden/x86-64/NegativeConstantsPolicy.txt", - "bpf_dsl/golden/x86-64/SwitchPolicy.txt", - ] - outputs = [ - "$target_gen_dir/bpf_dsl/golden/golden_files.h", - ] - args = - rebase_path(outputs, root_build_dir) + rebase_path(inputs, root_build_dir) -} - -test("sandbox_linux_unittests") { - deps = [ - ":sandbox_linux_unittests_sources", - "//build/config/sanitizers:deps", - ] - if (is_android) { - use_raw_android_executable = true - } -} - -component("seccomp_bpf") { - sources = [ - "bpf_dsl/bpf_dsl.cc", - "bpf_dsl/bpf_dsl.h", - "bpf_dsl/bpf_dsl_forward.h", - "bpf_dsl/bpf_dsl_impl.h", - "bpf_dsl/codegen.cc", - "bpf_dsl/codegen.h", - "bpf_dsl/cons.h", - "bpf_dsl/errorcode.h", - "bpf_dsl/linux_syscall_ranges.h", - "bpf_dsl/policy.cc", - "bpf_dsl/policy.h", - "bpf_dsl/policy_compiler.cc", - "bpf_dsl/policy_compiler.h", - "bpf_dsl/seccomp_macros.h", - "bpf_dsl/syscall_set.cc", - "bpf_dsl/syscall_set.h", - "bpf_dsl/trap_registry.h", - "seccomp-bpf-helpers/baseline_policy.cc", - "seccomp-bpf-helpers/baseline_policy.h", - "seccomp-bpf-helpers/sigsys_handlers.cc", - "seccomp-bpf-helpers/sigsys_handlers.h", - "seccomp-bpf-helpers/syscall_parameters_restrictions.cc", - "seccomp-bpf-helpers/syscall_parameters_restrictions.h", - "seccomp-bpf-helpers/syscall_sets.cc", - "seccomp-bpf-helpers/syscall_sets.h", - "seccomp-bpf/die.cc", - "seccomp-bpf/die.h", - "seccomp-bpf/sandbox_bpf.cc", - "seccomp-bpf/sandbox_bpf.h", - "seccomp-bpf/syscall.cc", - "seccomp-bpf/syscall.h", - "seccomp-bpf/trap.cc", - "seccomp-bpf/trap.h", - ] - defines = [ "SANDBOX_IMPLEMENTATION" ] - - public_deps = [ - ":sandbox_services_headers", - ] - deps = [ - ":sandbox_services", - "//base", - ] - - if (is_nacl_nonsfi) { - cflags = [ "-fgnu-inline-asm" ] - sources -= [ - "bpf_dsl/bpf_dsl_forward.h", - "bpf_dsl/bpf_dsl_impl.h", - "bpf_dsl/cons.h", - "bpf_dsl/errorcode.h", - "bpf_dsl/linux_syscall_ranges.h", - "bpf_dsl/seccomp_macros.h", - "bpf_dsl/trap_registry.h", - "seccomp-bpf-helpers/baseline_policy.cc", - "seccomp-bpf-helpers/baseline_policy.h", - "seccomp-bpf-helpers/syscall_sets.cc", - "seccomp-bpf-helpers/syscall_sets.h", - ] - configs += [ ":nacl_nonsfi_warnings" ] - } -} - -if (is_linux) { - # The setuid sandbox for Linux. - executable("chrome_sandbox") { - sources = [ - "suid/common/sandbox.h", - "suid/common/suid_unsafe_environment_variables.h", - "suid/process_util.h", - "suid/process_util_linux.c", - "suid/sandbox.c", - ] - - cflags = [ - # For ULLONG_MAX - "-std=gnu99", - - # These files have a suspicious comparison. - # TODO fix this and re-enable this warning. - "-Wno-sign-compare", - ] - - import("//build/config/compiler/compiler.gni") - import("//build/config/sanitizers/sanitizers.gni") - if (is_component_build || using_sanitizer) { - # WARNING! We remove this config so that we don't accidentally - # pick up the //build/config:rpath_for_built_shared_libraries - # sub-config. However, this means that we need to duplicate any - # other flags that executable_config might have. - configs -= [ "//build/config:executable_config" ] - if (!use_gold) { - ldflags = [ "-Wl,--disable-new-dtags" ] - } - } - - # We also do not want to pick up any of the other sanitizer - # flags (i.e. we do not want to build w/ the sanitizers at all). - # This is safe to delete unconditionally, because it is part of the - # default configs and empty when not using the sanitizers. - configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ] - } -} - -component("sandbox_services") { - sources = [ - "services/init_process_reaper.cc", - "services/init_process_reaper.h", - "services/proc_util.cc", - "services/proc_util.h", - "services/resource_limits.cc", - "services/resource_limits.h", - "services/scoped_process.cc", - "services/scoped_process.h", - "services/syscall_wrappers.cc", - "services/syscall_wrappers.h", - "services/thread_helpers.cc", - "services/thread_helpers.h", - "services/yama.cc", - "services/yama.h", - "syscall_broker/broker_channel.cc", - "syscall_broker/broker_channel.h", - "syscall_broker/broker_client.cc", - "syscall_broker/broker_client.h", - "syscall_broker/broker_common.h", - "syscall_broker/broker_file_permission.cc", - "syscall_broker/broker_file_permission.h", - "syscall_broker/broker_host.cc", - "syscall_broker/broker_host.h", - "syscall_broker/broker_policy.cc", - "syscall_broker/broker_policy.h", - "syscall_broker/broker_process.cc", - "syscall_broker/broker_process.h", - ] - - defines = [ "SANDBOX_IMPLEMENTATION" ] - - public_deps = [] - deps = [ - "//base", - ] - - if (compile_credentials || is_nacl_nonsfi) { - sources += [ - "services/credentials.cc", - "services/credentials.h", - "services/namespace_sandbox.cc", - "services/namespace_sandbox.h", - "services/namespace_utils.cc", - "services/namespace_utils.h", - ] - - public_deps += [ ":sandbox_services_headers" ] - } - - if (is_nacl_nonsfi) { - cflags = [ "-fgnu-inline-asm" ] - - sources -= [ - "services/init_process_reaper.cc", - "services/init_process_reaper.h", - "services/scoped_process.cc", - "services/scoped_process.h", - "services/yama.cc", - "services/yama.h", - "syscall_broker/broker_channel.cc", - "syscall_broker/broker_channel.h", - "syscall_broker/broker_client.cc", - "syscall_broker/broker_client.h", - "syscall_broker/broker_common.h", - "syscall_broker/broker_file_permission.cc", - "syscall_broker/broker_file_permission.h", - "syscall_broker/broker_host.cc", - "syscall_broker/broker_host.h", - "syscall_broker/broker_policy.cc", - "syscall_broker/broker_policy.h", - "syscall_broker/broker_process.cc", - "syscall_broker/broker_process.h", - ] - } -} - -source_set("sandbox_services_headers") { - sources = [ - "system_headers/arm64_linux_syscalls.h", - "system_headers/arm64_linux_ucontext.h", - "system_headers/arm_linux_syscalls.h", - "system_headers/arm_linux_ucontext.h", - "system_headers/i386_linux_ucontext.h", - "system_headers/linux_futex.h", - "system_headers/linux_seccomp.h", - "system_headers/linux_signal.h", - "system_headers/linux_syscalls.h", - "system_headers/linux_time.h", - "system_headers/linux_ucontext.h", - "system_headers/x86_32_linux_syscalls.h", - "system_headers/x86_64_linux_syscalls.h", - ] -} - -if (compile_suid_client || is_nacl_nonsfi) { - component("suid_sandbox_client") { - sources = [ - "suid/client/setuid_sandbox_client.cc", - "suid/client/setuid_sandbox_client.h", - "suid/client/setuid_sandbox_host.cc", - "suid/client/setuid_sandbox_host.h", - "suid/common/sandbox.h", - "suid/common/suid_unsafe_environment_variables.h", - ] - defines = [ "SANDBOX_IMPLEMENTATION" ] - - deps = [ - ":sandbox_services", - "//base", - ] - - if (is_nacl_nonsfi) { - sources -= [ - "suid/client/setuid_sandbox_host.cc", - "suid/client/setuid_sandbox_host.h", - "suid/common/sandbox.h", - "suid/common/suid_unsafe_environment_variables.h", - ] - } - } -} - -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/sandbox/linux/DEPS b/sandbox/linux/DEPS deleted file mode 100644 index 3912859344..0000000000 --- a/sandbox/linux/DEPS +++ /dev/null @@ -1,25 +0,0 @@ -include_rules = [ - # First, exclude everything. - # Exclude a few dependencies that are included in the root DEPS and that we - # don't need. - # Sadly, there is no way to exclude all root DEPS since the root has no name. - "-ipc", - "-library_loaders", - "-third_party", - "-url", - # Make sure that each subdirectory has to declare its dependencies in - # sandbox/ explicitly. - "-sandbox/linux", - - # Second, add what we want to allow. - # Anything included from sandbox/linux must be declared after this line or in - # a more specific DEPS file. - # base/, build/ and testing/ are already included in the global DEPS file, - # but be explicit. - "+base", - "+build", - "+testing", - "+sandbox/sandbox_export.h", - # Everyone can use tests/ - "+sandbox/linux/tests", -] diff --git a/sandbox/linux/bpf_dsl/DEPS b/sandbox/linux/bpf_dsl/DEPS deleted file mode 100644 index 70d9b18aa1..0000000000 --- a/sandbox/linux/bpf_dsl/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+sandbox/linux/system_headers", -] diff --git a/sandbox/linux/bpf_dsl/bpf_dsl.cc b/sandbox/linux/bpf_dsl/bpf_dsl.cc deleted file mode 100644 index fed6368db6..0000000000 --- a/sandbox/linux/bpf_dsl/bpf_dsl.cc +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright 2014 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/linux/bpf_dsl/bpf_dsl.h" - -#include <stddef.h> -#include <stdint.h> - -#include <limits> - -#include "base/logging.h" -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h" -#include "sandbox/linux/bpf_dsl/errorcode.h" -#include "sandbox/linux/bpf_dsl/policy_compiler.h" -#include "sandbox/linux/system_headers/linux_seccomp.h" - -namespace sandbox { -namespace bpf_dsl { -namespace { - -class ReturnResultExprImpl : public internal::ResultExprImpl { - public: - explicit ReturnResultExprImpl(uint32_t ret) : ret_(ret) {} - ~ReturnResultExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc) const override { - return pc->Return(ret_); - } - - bool IsAllow() const override { return IsAction(SECCOMP_RET_ALLOW); } - - bool IsDeny() const override { - return IsAction(SECCOMP_RET_ERRNO) || IsAction(SECCOMP_RET_KILL); - } - - private: - bool IsAction(uint32_t action) const { - return (ret_ & SECCOMP_RET_ACTION) == action; - } - - uint32_t ret_; - - DISALLOW_COPY_AND_ASSIGN(ReturnResultExprImpl); -}; - -class TrapResultExprImpl : public internal::ResultExprImpl { - public: - TrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg, bool safe) - : func_(func), arg_(arg), safe_(safe) { - DCHECK(func_); - } - ~TrapResultExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc) const override { - return pc->Trap(func_, arg_, safe_); - } - - bool HasUnsafeTraps() const override { return safe_ == false; } - - bool IsDeny() const override { return true; } - - private: - TrapRegistry::TrapFnc func_; - const void* arg_; - bool safe_; - - DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl); -}; - -class IfThenResultExprImpl : public internal::ResultExprImpl { - public: - IfThenResultExprImpl(BoolExpr cond, - ResultExpr then_result, - ResultExpr else_result) - : cond_(std::move(cond)), - then_result_(std::move(then_result)), - else_result_(std::move(else_result)) {} - ~IfThenResultExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc) const override { - // We compile the "then" and "else" expressions in separate statements so - // they have a defined sequencing. See https://crbug.com/529480. - CodeGen::Node then_node = then_result_->Compile(pc); - CodeGen::Node else_node = else_result_->Compile(pc); - return cond_->Compile(pc, then_node, else_node); - } - - bool HasUnsafeTraps() const override { - return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps(); - } - - private: - BoolExpr cond_; - ResultExpr then_result_; - ResultExpr else_result_; - - DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl); -}; - -class ConstBoolExprImpl : public internal::BoolExprImpl { - public: - ConstBoolExprImpl(bool value) : value_(value) {} - ~ConstBoolExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc, - CodeGen::Node then_node, - CodeGen::Node else_node) const override { - return value_ ? then_node : else_node; - } - - private: - bool value_; - - DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl); -}; - -class MaskedEqualBoolExprImpl : public internal::BoolExprImpl { - public: - MaskedEqualBoolExprImpl(int argno, - size_t width, - uint64_t mask, - uint64_t value) - : argno_(argno), width_(width), mask_(mask), value_(value) {} - ~MaskedEqualBoolExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc, - CodeGen::Node then_node, - CodeGen::Node else_node) const override { - return pc->MaskedEqual(argno_, width_, mask_, value_, then_node, else_node); - } - - private: - int argno_; - size_t width_; - uint64_t mask_; - uint64_t value_; - - DISALLOW_COPY_AND_ASSIGN(MaskedEqualBoolExprImpl); -}; - -class NegateBoolExprImpl : public internal::BoolExprImpl { - public: - explicit NegateBoolExprImpl(BoolExpr cond) : cond_(std::move(cond)) {} - ~NegateBoolExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc, - CodeGen::Node then_node, - CodeGen::Node else_node) const override { - return cond_->Compile(pc, else_node, then_node); - } - - private: - BoolExpr cond_; - - DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl); -}; - -class AndBoolExprImpl : public internal::BoolExprImpl { - public: - AndBoolExprImpl(BoolExpr lhs, BoolExpr rhs) - : lhs_(std::move(lhs)), rhs_(std::move(rhs)) {} - ~AndBoolExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc, - CodeGen::Node then_node, - CodeGen::Node else_node) const override { - return lhs_->Compile(pc, rhs_->Compile(pc, then_node, else_node), - else_node); - } - - private: - BoolExpr lhs_; - BoolExpr rhs_; - - DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl); -}; - -class OrBoolExprImpl : public internal::BoolExprImpl { - public: - OrBoolExprImpl(BoolExpr lhs, BoolExpr rhs) - : lhs_(std::move(lhs)), rhs_(std::move(rhs)) {} - ~OrBoolExprImpl() override {} - - CodeGen::Node Compile(PolicyCompiler* pc, - CodeGen::Node then_node, - CodeGen::Node else_node) const override { - return lhs_->Compile(pc, then_node, - rhs_->Compile(pc, then_node, else_node)); - } - - private: - BoolExpr lhs_; - BoolExpr rhs_; - - DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl); -}; - -} // namespace - -namespace internal { - -bool ResultExprImpl::HasUnsafeTraps() const { - return false; -} - -bool ResultExprImpl::IsAllow() const { - return false; -} - -bool ResultExprImpl::IsDeny() const { - return false; -} - -uint64_t DefaultMask(size_t size) { - switch (size) { - case 4: - return std::numeric_limits<uint32_t>::max(); - case 8: - return std::numeric_limits<uint64_t>::max(); - default: - CHECK(false) << "Unimplemented DefaultMask case"; - return 0; - } -} - -BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) { - // If this is changed, update Arg<T>::EqualTo's static_cast rules - // accordingly. - CHECK(size == 4 || size == 8); - - return std::make_shared<MaskedEqualBoolExprImpl>(num, size, mask, val); -} - -} // namespace internal - -ResultExpr Allow() { - return std::make_shared<ReturnResultExprImpl>(SECCOMP_RET_ALLOW); -} - -ResultExpr Error(int err) { - CHECK(err >= ErrorCode::ERR_MIN_ERRNO && err <= ErrorCode::ERR_MAX_ERRNO); - return std::make_shared<ReturnResultExprImpl>(SECCOMP_RET_ERRNO + err); -} - -ResultExpr Kill() { - return std::make_shared<ReturnResultExprImpl>(SECCOMP_RET_KILL); -} - -ResultExpr Trace(uint16_t aux) { - return std::make_shared<ReturnResultExprImpl>(SECCOMP_RET_TRACE + aux); -} - -ResultExpr Trap(TrapRegistry::TrapFnc trap_func, const void* aux) { - return std::make_shared<TrapResultExprImpl>(trap_func, aux, true /* safe */); -} - -ResultExpr UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux) { - return std::make_shared<TrapResultExprImpl>(trap_func, aux, - false /* unsafe */); -} - -BoolExpr BoolConst(bool value) { - return std::make_shared<ConstBoolExprImpl>(value); -} - -BoolExpr Not(BoolExpr cond) { - return std::make_shared<NegateBoolExprImpl>(std::move(cond)); -} - -BoolExpr AllOf() { - return BoolConst(true); -} - -BoolExpr AllOf(BoolExpr lhs, BoolExpr rhs) { - return std::make_shared<AndBoolExprImpl>(std::move(lhs), std::move(rhs)); -} - -BoolExpr AnyOf() { - return BoolConst(false); -} - -BoolExpr AnyOf(BoolExpr lhs, BoolExpr rhs) { - return std::make_shared<OrBoolExprImpl>(std::move(lhs), std::move(rhs)); -} - -Elser If(BoolExpr cond, ResultExpr then_result) { - return Elser(nullptr).ElseIf(std::move(cond), std::move(then_result)); -} - -Elser::Elser(cons::List<Clause> clause_list) : clause_list_(clause_list) { -} - -Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) { -} - -Elser::~Elser() { -} - -Elser Elser::ElseIf(BoolExpr cond, ResultExpr then_result) const { - return Elser(Cons(std::make_pair(std::move(cond), std::move(then_result)), - clause_list_)); -} - -ResultExpr Elser::Else(ResultExpr else_result) const { - // We finally have the default result expression for this - // if/then/else sequence. Also, we've already accumulated all - // if/then pairs into a list of reverse order (i.e., lower priority - // conditions are listed before higher priority ones). E.g., an - // expression like - // - // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4) - // - // will have built up a list like - // - // [(b3, e3), (b2, e2), (b1, e1)]. - // - // Now that we have e4, we can walk the list and create a ResultExpr - // tree like: - // - // expr = e4 - // expr = (b3 ? e3 : expr) = (b3 ? e3 : e4) - // expr = (b2 ? e2 : expr) = (b2 ? e2 : (b3 ? e3 : e4)) - // expr = (b1 ? e1 : expr) = (b1 ? e1 : (b2 ? e2 : (b3 ? e3 : e4))) - // - // and end up with an appropriately chained tree. - - ResultExpr expr = std::move(else_result); - for (const Clause& clause : clause_list_) { - expr = std::make_shared<IfThenResultExprImpl>(clause.first, clause.second, - std::move(expr)); - } - return expr; -} - -} // namespace bpf_dsl -} // namespace sandbox - -namespace std { -template class shared_ptr<const sandbox::bpf_dsl::internal::BoolExprImpl>; -template class shared_ptr<const sandbox::bpf_dsl::internal::ResultExprImpl>; -} // namespace std diff --git a/sandbox/linux/bpf_dsl/bpf_dsl.h b/sandbox/linux/bpf_dsl/bpf_dsl.h deleted file mode 100644 index 6f0dd4eb39..0000000000 --- a/sandbox/linux/bpf_dsl/bpf_dsl.h +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright 2014 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_LINUX_BPF_DSL_BPF_DSL_H_ -#define SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <utility> -#include <vector> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/linux/bpf_dsl/cons.h" -#include "sandbox/linux/bpf_dsl/trap_registry.h" -#include "sandbox/sandbox_export.h" - -// The sandbox::bpf_dsl namespace provides a domain-specific language -// to make writing BPF policies more expressive. In general, the -// object types all have value semantics (i.e., they can be copied -// around, returned from or passed to function calls, etc. without any -// surprising side effects), though not all support assignment. -// -// An idiomatic and demonstrative (albeit silly) example of this API -// would be: -// -// #include "sandbox/linux/bpf_dsl/bpf_dsl.h" -// -// using namespace sandbox::bpf_dsl; -// -// class SillyPolicy : public Policy { -// public: -// SillyPolicy() {} -// ~SillyPolicy() override {} -// ResultExpr EvaluateSyscall(int sysno) const override { -// if (sysno == __NR_fcntl) { -// Arg<int> fd(0), cmd(1); -// Arg<unsigned long> flags(2); -// const uint64_t kGoodFlags = O_ACCMODE | O_NONBLOCK; -// return If(AllOf(fd == 0, -// cmd == F_SETFL, -// (flags & ~kGoodFlags) == 0), -// Allow()) -// .ElseIf(AnyOf(cmd == F_DUPFD, cmd == F_DUPFD_CLOEXEC), -// Error(EMFILE)) -// .Else(Trap(SetFlagHandler, NULL)); -// } else { -// return Allow(); -// } -// } -// -// private: -// DISALLOW_COPY_AND_ASSIGN(SillyPolicy); -// }; -// -// More generally, the DSL currently supports the following grammar: -// -// result = Allow() | Error(errno) | Kill() | Trace(aux) -// | Trap(trap_func, aux) | UnsafeTrap(trap_func, aux) -// | If(bool, result)[.ElseIf(bool, result)].Else(result) -// | Switch(arg)[.Case(val, result)].Default(result) -// bool = BoolConst(boolean) | Not(bool) | AllOf(bool...) | AnyOf(bool...) -// | arg == val | arg != val -// arg = Arg<T>(num) | arg & mask -// -// The semantics of each function and operator are intended to be -// intuitive, but are described in more detail below. -// -// (Credit to Sean Parent's "Inheritance is the Base Class of Evil" -// talk at Going Native 2013 for promoting value semantics via shared -// pointers to immutable state.) - -namespace sandbox { -namespace bpf_dsl { - -template <typename T> -class Caser; - -class Elser; - -// ResultExpr is an opaque reference to an immutable result expression tree. -using ResultExpr = std::shared_ptr<const internal::ResultExprImpl>; - -// BoolExpr is an opaque reference to an immutable boolean expression tree. -using BoolExpr = std::shared_ptr<const internal::BoolExprImpl>; - -// Allow specifies a result that the system call should be allowed to -// execute normally. -SANDBOX_EXPORT ResultExpr Allow(); - -// Error specifies a result that the system call should fail with -// error number |err|. As a special case, Error(0) will result in the -// system call appearing to have succeeded, but without having any -// side effects. -SANDBOX_EXPORT ResultExpr Error(int err); - -// Kill specifies a result to kill the process (task) immediately. -SANDBOX_EXPORT ResultExpr Kill(); - -// Trace specifies a result to notify a tracing process via the -// PTRACE_EVENT_SECCOMP event and allow it to change or skip the system call. -// The value of |aux| will be available to the tracer via PTRACE_GETEVENTMSG. -SANDBOX_EXPORT ResultExpr Trace(uint16_t aux); - -// Trap specifies a result that the system call should be handled by -// trapping back into userspace and invoking |trap_func|, passing -// |aux| as the second parameter. -SANDBOX_EXPORT ResultExpr - Trap(TrapRegistry::TrapFnc trap_func, const void* aux); - -// UnsafeTrap is like Trap, except the policy is marked as "unsafe" -// and allowed to use SandboxSyscall to invoke any system call. -// -// NOTE: This feature, by definition, disables all security features of -// the sandbox. It should never be used in production, but it can be -// very useful to diagnose code that is incompatible with the sandbox. -// If even a single system call returns "UnsafeTrap", the security of -// entire sandbox should be considered compromised. -SANDBOX_EXPORT ResultExpr - UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux); - -// BoolConst converts a bool value into a BoolExpr. -SANDBOX_EXPORT BoolExpr BoolConst(bool value); - -// Not returns a BoolExpr representing the logical negation of |cond|. -SANDBOX_EXPORT BoolExpr Not(BoolExpr cond); - -// AllOf returns a BoolExpr representing the logical conjunction ("and") -// of zero or more BoolExprs. -SANDBOX_EXPORT BoolExpr AllOf(); -SANDBOX_EXPORT BoolExpr AllOf(BoolExpr lhs, BoolExpr rhs); -template <typename... Rest> -SANDBOX_EXPORT BoolExpr AllOf(BoolExpr first, Rest&&... rest); - -// AnyOf returns a BoolExpr representing the logical disjunction ("or") -// of zero or more BoolExprs. -SANDBOX_EXPORT BoolExpr AnyOf(); -SANDBOX_EXPORT BoolExpr AnyOf(BoolExpr lhs, BoolExpr rhs); -template <typename... Rest> -SANDBOX_EXPORT BoolExpr AnyOf(BoolExpr first, Rest&&... rest); - -template <typename T> -class SANDBOX_EXPORT Arg { - public: - // Initializes the Arg to represent the |num|th system call - // argument (indexed from 0), which is of type |T|. - explicit Arg(int num); - - Arg(const Arg& arg) : num_(arg.num_), mask_(arg.mask_) {} - - // Returns an Arg representing the current argument, but after - // bitwise-and'ing it with |rhs|. - friend Arg operator&(const Arg& lhs, uint64_t rhs) { - return Arg(lhs.num_, lhs.mask_ & rhs); - } - - // Returns a boolean expression comparing whether the system call argument - // (after applying any bitmasks, if appropriate) equals |rhs|. - friend BoolExpr operator==(const Arg& lhs, T rhs) { return lhs.EqualTo(rhs); } - - // Returns a boolean expression comparing whether the system call argument - // (after applying any bitmasks, if appropriate) does not equal |rhs|. - friend BoolExpr operator!=(const Arg& lhs, T rhs) { return Not(lhs == rhs); } - - private: - Arg(int num, uint64_t mask) : num_(num), mask_(mask) {} - - BoolExpr EqualTo(T val) const; - - int num_; - uint64_t mask_; - - DISALLOW_ASSIGN(Arg); -}; - -// If begins a conditional result expression predicated on the -// specified boolean expression. -SANDBOX_EXPORT Elser If(BoolExpr cond, ResultExpr then_result); - -class SANDBOX_EXPORT Elser { - public: - Elser(const Elser& elser); - ~Elser(); - - // ElseIf extends the conditional result expression with another - // "if then" clause, predicated on the specified boolean expression. - Elser ElseIf(BoolExpr cond, ResultExpr then_result) const; - - // Else terminates a conditional result expression using |else_result| as - // the default fallback result expression. - ResultExpr Else(ResultExpr else_result) const; - - private: - using Clause = std::pair<BoolExpr, ResultExpr>; - - explicit Elser(cons::List<Clause> clause_list); - - cons::List<Clause> clause_list_; - - friend Elser If(BoolExpr, ResultExpr); - template <typename T> - friend Caser<T> Switch(const Arg<T>&); - DISALLOW_ASSIGN(Elser); -}; - -// Switch begins a switch expression dispatched according to the -// specified argument value. -template <typename T> -SANDBOX_EXPORT Caser<T> Switch(const Arg<T>& arg); - -template <typename T> -class SANDBOX_EXPORT Caser { - public: - Caser(const Caser<T>& caser) : arg_(caser.arg_), elser_(caser.elser_) {} - ~Caser() {} - - // Case adds a single-value "case" clause to the switch. - Caser<T> Case(T value, ResultExpr result) const; - - // Cases adds a multiple-value "case" clause to the switch. - // See also the SANDBOX_BPF_DSL_CASES macro below for a more idiomatic way - // of using this function. - template <typename... Values> - Caser<T> CasesImpl(ResultExpr result, const Values&... values) const; - - // Terminate the switch with a "default" clause. - ResultExpr Default(ResultExpr result) const; - - private: - Caser(const Arg<T>& arg, Elser elser) : arg_(arg), elser_(elser) {} - - Arg<T> arg_; - Elser elser_; - - template <typename U> - friend Caser<U> Switch(const Arg<U>&); - DISALLOW_ASSIGN(Caser); -}; - -// Recommended usage is to put -// #define CASES SANDBOX_BPF_DSL_CASES -// near the top of the .cc file (e.g., nearby any "using" statements), then -// use like: -// Switch(arg).CASES((3, 5, 7), result)...; -#define SANDBOX_BPF_DSL_CASES(values, result) \ - CasesImpl(result, SANDBOX_BPF_DSL_CASES_HELPER values) - -// Helper macro to strip parentheses. -#define SANDBOX_BPF_DSL_CASES_HELPER(...) __VA_ARGS__ - -// ===================================================================== -// Official API ends here. -// ===================================================================== - -namespace internal { - -// Make argument-dependent lookup work. This is necessary because although -// BoolExpr is defined in bpf_dsl, since it's merely a typedef for -// scoped_refptr<const internal::BoolExplImpl>, argument-dependent lookup only -// searches the "internal" nested namespace. -using bpf_dsl::Not; -using bpf_dsl::AllOf; -using bpf_dsl::AnyOf; - -// Returns a boolean expression that represents whether system call -// argument |num| of size |size| is equal to |val|, when masked -// according to |mask|. Users should use the Arg template class below -// instead of using this API directly. -SANDBOX_EXPORT BoolExpr - ArgEq(int num, size_t size, uint64_t mask, uint64_t val); - -// Returns the default mask for a system call argument of the specified size. -SANDBOX_EXPORT uint64_t DefaultMask(size_t size); - -} // namespace internal - -template <typename T> -Arg<T>::Arg(int num) - : num_(num), mask_(internal::DefaultMask(sizeof(T))) { -} - -// Definition requires ArgEq to have been declared. Moved out-of-line -// to minimize how much internal clutter users have to ignore while -// reading the header documentation. -// -// Additionally, we use this helper member function to avoid linker errors -// caused by defining operator== out-of-line. For a more detailed explanation, -// see http://www.parashift.com/c++-faq-lite/template-friends.html. -template <typename T> -BoolExpr Arg<T>::EqualTo(T val) const { - if (sizeof(T) == 4) { - // Prevent sign-extension of negative int32_t values. - return internal::ArgEq(num_, sizeof(T), mask_, static_cast<uint32_t>(val)); - } - return internal::ArgEq(num_, sizeof(T), mask_, static_cast<uint64_t>(val)); -} - -template <typename T> -SANDBOX_EXPORT Caser<T> Switch(const Arg<T>& arg) { - return Caser<T>(arg, Elser(nullptr)); -} - -template <typename T> -Caser<T> Caser<T>::Case(T value, ResultExpr result) const { - return SANDBOX_BPF_DSL_CASES((value), std::move(result)); -} - -template <typename T> -template <typename... Values> -Caser<T> Caser<T>::CasesImpl(ResultExpr result, const Values&... values) const { - // Theoretically we could evaluate arg_ just once and emit a more efficient - // dispatch table, but for now we simply translate into an equivalent - // If/ElseIf/Else chain. - - return Caser<T>(arg_, - elser_.ElseIf(AnyOf((arg_ == values)...), std::move(result))); -} - -template <typename T> -ResultExpr Caser<T>::Default(ResultExpr result) const { - return elser_.Else(std::move(result)); -} - -template <typename... Rest> -BoolExpr AllOf(BoolExpr first, Rest&&... rest) { - return AllOf(std::move(first), AllOf(std::forward<Rest>(rest)...)); -} - -template <typename... Rest> -BoolExpr AnyOf(BoolExpr first, Rest&&... rest) { - return AnyOf(std::move(first), AnyOf(std::forward<Rest>(rest)...)); -} - -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ diff --git a/sandbox/linux/bpf_dsl/bpf_dsl_forward.h b/sandbox/linux/bpf_dsl/bpf_dsl_forward.h deleted file mode 100644 index af1b48b407..0000000000 --- a/sandbox/linux/bpf_dsl/bpf_dsl_forward.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 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_LINUX_BPF_DSL_BPF_DSL_FORWARD_H_ -#define SANDBOX_LINUX_BPF_DSL_BPF_DSL_FORWARD_H_ - -#include <memory> - -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace bpf_dsl { - -// The bpf_dsl_forward.h header provides forward declarations for the -// types defined in bpf_dsl.h. It's intended for use in user headers -// that need to reference bpf_dsl types, but don't require definitions. - -namespace internal { -class ResultExprImpl; -class BoolExprImpl; -} - -using ResultExpr = std::shared_ptr<const internal::ResultExprImpl>; -using BoolExpr = std::shared_ptr<const internal::BoolExprImpl>; - -} // namespace bpf_dsl -} // namespace sandbox - -namespace std { -extern template class SANDBOX_EXPORT - shared_ptr<const sandbox::bpf_dsl::internal::BoolExprImpl>; -extern template class SANDBOX_EXPORT - shared_ptr<const sandbox::bpf_dsl::internal::ResultExprImpl>; -} // namespace std - -#endif // SANDBOX_LINUX_BPF_DSL_BPF_DSL_FORWARD_H_ diff --git a/sandbox/linux/bpf_dsl/bpf_dsl_impl.h b/sandbox/linux/bpf_dsl/bpf_dsl_impl.h deleted file mode 100644 index f397321edd..0000000000 --- a/sandbox/linux/bpf_dsl/bpf_dsl_impl.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2014 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_LINUX_BPF_DSL_BPF_DSL_IMPL_H_ -#define SANDBOX_LINUX_BPF_DSL_BPF_DSL_IMPL_H_ - -#include <memory> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace bpf_dsl { -class PolicyCompiler; - -namespace internal { - -// Internal interface implemented by BoolExpr implementations. -class BoolExprImpl { - public: - // Compile uses |pc| to emit a CodeGen::Node that conditionally continues - // to either |then_node| or |false_node|, depending on whether the represented - // boolean expression is true or false. - virtual CodeGen::Node Compile(PolicyCompiler* pc, - CodeGen::Node then_node, - CodeGen::Node else_node) const = 0; - - protected: - BoolExprImpl() {} - virtual ~BoolExprImpl() {} - - private: - DISALLOW_COPY_AND_ASSIGN(BoolExprImpl); -}; - -// Internal interface implemented by ResultExpr implementations. -class ResultExprImpl { - public: - // Compile uses |pc| to emit a CodeGen::Node that executes the - // represented result expression. - virtual CodeGen::Node Compile(PolicyCompiler* pc) const = 0; - - // HasUnsafeTraps returns whether the result expression is or recursively - // contains an unsafe trap expression. - virtual bool HasUnsafeTraps() const; - - // IsAllow returns whether the result expression is an "allow" result. - virtual bool IsAllow() const; - - // IsAllow returns whether the result expression is a "deny" result. - virtual bool IsDeny() const; - - protected: - ResultExprImpl() {} - virtual ~ResultExprImpl() {} - - private: - DISALLOW_COPY_AND_ASSIGN(ResultExprImpl); -}; - -} // namespace internal -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_BPF_DSL_IMPL_H_ diff --git a/sandbox/linux/bpf_dsl/bpf_dsl_unittest.cc b/sandbox/linux/bpf_dsl/bpf_dsl_unittest.cc deleted file mode 100644 index 801deee3e7..0000000000 --- a/sandbox/linux/bpf_dsl/bpf_dsl_unittest.cc +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright 2014 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/linux/bpf_dsl/bpf_dsl.h" - -#include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <stdint.h> -#include <sys/socket.h> -#include <sys/syscall.h> -#include <sys/utsname.h> -#include <unistd.h> - -#include <map> -#include <utility> - -#include "base/files/scoped_file.h" -#include "base/macros.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/linux/bpf_dsl/dump_bpf.h" -#include "sandbox/linux/bpf_dsl/golden/golden_files.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/bpf_dsl/policy_compiler.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/bpf_dsl/test_trap_registry.h" -#include "sandbox/linux/bpf_dsl/verifier.h" -#include "sandbox/linux/system_headers/linux_filter.h" -#include "testing/gtest/include/gtest/gtest.h" - -#define CASES SANDBOX_BPF_DSL_CASES - -namespace sandbox { -namespace bpf_dsl { -namespace { - -// Helper function to construct fake arch_seccomp_data objects. -struct arch_seccomp_data FakeSyscall(int nr, - uintptr_t p0 = 0, - uintptr_t p1 = 0, - uintptr_t p2 = 0, - uintptr_t p3 = 0, - uintptr_t p4 = 0, - uintptr_t p5 = 0) { - // Made up program counter for syscall address. - const uint64_t kFakePC = 0x543210; - - struct arch_seccomp_data data = { - nr, - SECCOMP_ARCH, - kFakePC, - { - p0, p1, p2, p3, p4, p5, - }, - }; - - return data; -} - -class PolicyEmulator { - public: - PolicyEmulator(const golden::Golden& golden, const Policy& policy) - : program_() { - TestTrapRegistry traps; - program_ = PolicyCompiler(&policy, &traps).Compile(); - - // TODO(mdempsky): Generalize to more arches. - const char* expected = nullptr; -#if defined(ARCH_CPU_X86) - expected = golden.i386_dump; -#elif defined(ARCH_CPU_X86_64) - expected = golden.x86_64_dump; -#endif - - if (expected != nullptr) { - const std::string actual = DumpBPF::StringPrintProgram(program_); - EXPECT_EQ(expected, actual); - } else { - LOG(WARNING) << "Missing golden file data entry"; - } - } - - ~PolicyEmulator() {} - - void ExpectAllow(const struct arch_seccomp_data& data) const { - EXPECT_EQ(SECCOMP_RET_ALLOW, Emulate(data)); - } - - void ExpectErrno(uint16_t err, const struct arch_seccomp_data& data) const { - EXPECT_EQ(SECCOMP_RET_ERRNO | err, Emulate(data)); - } - - void ExpectKill(const struct arch_seccomp_data& data) const { - EXPECT_EQ(SECCOMP_RET_KILL, Emulate(data)); - } - - private: - uint32_t Emulate(const struct arch_seccomp_data& data) const { - const char* err = nullptr; - uint32_t res = Verifier::EvaluateBPF(program_, data, &err); - if (err) { - ADD_FAILURE() << err; - return 0; - } - return res; - } - - CodeGen::Program program_; - - DISALLOW_COPY_AND_ASSIGN(PolicyEmulator); -}; - -class BasicPolicy : public Policy { - public: - BasicPolicy() {} - ~BasicPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_getpgid) { - const Arg<pid_t> pid(0); - return If(pid == 0, Error(EPERM)).Else(Error(EINVAL)); - } - if (sysno == __NR_setuid) { - const Arg<uid_t> uid(0); - return If(uid != 42, Kill()).Else(Allow()); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(BasicPolicy); -}; - -TEST(BPFDSL, Basic) { - PolicyEmulator emulator(golden::kBasicPolicy, BasicPolicy()); - - emulator.ExpectErrno(EPERM, FakeSyscall(__NR_getpgid, 0)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_getpgid, 1)); - - emulator.ExpectAllow(FakeSyscall(__NR_setuid, 42)); - emulator.ExpectKill(FakeSyscall(__NR_setuid, 43)); -} - -/* On IA-32, socketpair() is implemented via socketcall(). :-( */ -#if !defined(ARCH_CPU_X86) -class BooleanLogicPolicy : public Policy { - public: - BooleanLogicPolicy() {} - ~BooleanLogicPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_socketpair) { - const Arg<int> domain(0), type(1), protocol(2); - return If(AllOf(domain == AF_UNIX, - AnyOf(type == SOCK_STREAM, type == SOCK_DGRAM), - protocol == 0), - Error(EPERM)) - .Else(Error(EINVAL)); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(BooleanLogicPolicy); -}; - -TEST(BPFDSL, BooleanLogic) { - PolicyEmulator emulator(golden::kBooleanLogicPolicy, BooleanLogicPolicy()); - - const intptr_t kFakeSV = 0x12345; - - // Acceptable combinations that should return EPERM. - emulator.ExpectErrno( - EPERM, FakeSyscall(__NR_socketpair, AF_UNIX, SOCK_STREAM, 0, kFakeSV)); - emulator.ExpectErrno( - EPERM, FakeSyscall(__NR_socketpair, AF_UNIX, SOCK_DGRAM, 0, kFakeSV)); - - // Combinations that are invalid for only one reason; should return EINVAL. - emulator.ExpectErrno( - EINVAL, FakeSyscall(__NR_socketpair, AF_INET, SOCK_STREAM, 0, kFakeSV)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_socketpair, AF_UNIX, - SOCK_SEQPACKET, 0, kFakeSV)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_socketpair, AF_UNIX, - SOCK_STREAM, IPPROTO_TCP, kFakeSV)); - - // Completely unacceptable combination; should also return EINVAL. - emulator.ExpectErrno( - EINVAL, FakeSyscall(__NR_socketpair, AF_INET, SOCK_SEQPACKET, IPPROTO_UDP, - kFakeSV)); -} -#endif // !ARCH_CPU_X86 - -class MoreBooleanLogicPolicy : public Policy { - public: - MoreBooleanLogicPolicy() {} - ~MoreBooleanLogicPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_setresuid) { - const Arg<uid_t> ruid(0), euid(1), suid(2); - return If(AnyOf(ruid == 0, euid == 0, suid == 0), Error(EPERM)) - .ElseIf(AllOf(ruid == 1, euid == 1, suid == 1), Error(EAGAIN)) - .Else(Error(EINVAL)); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(MoreBooleanLogicPolicy); -}; - -TEST(BPFDSL, MoreBooleanLogic) { - PolicyEmulator emulator(golden::kMoreBooleanLogicPolicy, - MoreBooleanLogicPolicy()); - - // Expect EPERM if any set to 0. - emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 0, 5, 5)); - emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 5, 0, 5)); - emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 5, 5, 0)); - - // Expect EAGAIN if all set to 1. - emulator.ExpectErrno(EAGAIN, FakeSyscall(__NR_setresuid, 1, 1, 1)); - - // Expect EINVAL for anything else. - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 5, 1, 1)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 1, 5, 1)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 1, 1, 5)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 3, 4, 5)); -} - -static const uintptr_t kDeadBeefAddr = - static_cast<uintptr_t>(0xdeadbeefdeadbeefULL); - -class ArgSizePolicy : public Policy { - public: - ArgSizePolicy() {} - ~ArgSizePolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_uname) { - const Arg<uintptr_t> addr(0); - return If(addr == kDeadBeefAddr, Error(EPERM)).Else(Allow()); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ArgSizePolicy); -}; - -TEST(BPFDSL, ArgSizeTest) { - PolicyEmulator emulator(golden::kArgSizePolicy, ArgSizePolicy()); - - emulator.ExpectAllow(FakeSyscall(__NR_uname, 0)); - emulator.ExpectErrno(EPERM, FakeSyscall(__NR_uname, kDeadBeefAddr)); -} - -class NegativeConstantsPolicy : public Policy { - public: - NegativeConstantsPolicy() {} - ~NegativeConstantsPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_fcntl) { - const Arg<int> fd(0); - return If(fd == -314, Error(EPERM)).Else(Allow()); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(NegativeConstantsPolicy); -}; - -TEST(BPFDSL, NegativeConstantsTest) { - PolicyEmulator emulator(golden::kNegativeConstantsPolicy, - NegativeConstantsPolicy()); - - emulator.ExpectAllow(FakeSyscall(__NR_fcntl, -5, F_DUPFD)); - emulator.ExpectAllow(FakeSyscall(__NR_fcntl, 20, F_DUPFD)); - emulator.ExpectErrno(EPERM, FakeSyscall(__NR_fcntl, -314, F_DUPFD)); -} - -#if 0 -// TODO(mdempsky): This is really an integration test. - -class TrappingPolicy : public Policy { - public: - TrappingPolicy() {} - ~TrappingPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_uname) { - return Trap(UnameTrap, &count_); - } - return Allow(); - } - - private: - static intptr_t count_; - - static intptr_t UnameTrap(const struct arch_seccomp_data& data, void* aux) { - BPF_ASSERT_EQ(&count_, aux); - return ++count_; - } - - DISALLOW_COPY_AND_ASSIGN(TrappingPolicy); -}; - -intptr_t TrappingPolicy::count_; - -BPF_TEST_C(BPFDSL, TrapTest, TrappingPolicy) { - ASSERT_SYSCALL_RESULT(1, uname, NULL); - ASSERT_SYSCALL_RESULT(2, uname, NULL); - ASSERT_SYSCALL_RESULT(3, uname, NULL); -} -#endif - -class MaskingPolicy : public Policy { - public: - MaskingPolicy() {} - ~MaskingPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_setuid) { - const Arg<uid_t> uid(0); - return If((uid & 0xf) == 0, Error(EINVAL)).Else(Error(EACCES)); - } - if (sysno == __NR_setgid) { - const Arg<gid_t> gid(0); - return If((gid & 0xf0) == 0xf0, Error(EINVAL)).Else(Error(EACCES)); - } - if (sysno == __NR_setpgid) { - const Arg<pid_t> pid(0); - return If((pid & 0xa5) == 0xa0, Error(EINVAL)).Else(Error(EACCES)); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(MaskingPolicy); -}; - -TEST(BPFDSL, MaskTest) { - PolicyEmulator emulator(golden::kMaskingPolicy, MaskingPolicy()); - - for (uid_t uid = 0; uid < 0x100; ++uid) { - const int expect_errno = (uid & 0xf) == 0 ? EINVAL : EACCES; - emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setuid, uid)); - } - - for (gid_t gid = 0; gid < 0x100; ++gid) { - const int expect_errno = (gid & 0xf0) == 0xf0 ? EINVAL : EACCES; - emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setgid, gid)); - } - - for (pid_t pid = 0; pid < 0x100; ++pid) { - const int expect_errno = (pid & 0xa5) == 0xa0 ? EINVAL : EACCES; - emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setpgid, pid, 0)); - } -} - -class ElseIfPolicy : public Policy { - public: - ElseIfPolicy() {} - ~ElseIfPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_setuid) { - const Arg<uid_t> uid(0); - return If((uid & 0xfff) == 0, Error(0)) - .ElseIf((uid & 0xff0) == 0, Error(EINVAL)) - .ElseIf((uid & 0xf00) == 0, Error(EEXIST)) - .Else(Error(EACCES)); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ElseIfPolicy); -}; - -TEST(BPFDSL, ElseIfTest) { - PolicyEmulator emulator(golden::kElseIfPolicy, ElseIfPolicy()); - - emulator.ExpectErrno(0, FakeSyscall(__NR_setuid, 0)); - - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setuid, 0x0001)); - emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setuid, 0x0002)); - - emulator.ExpectErrno(EEXIST, FakeSyscall(__NR_setuid, 0x0011)); - emulator.ExpectErrno(EEXIST, FakeSyscall(__NR_setuid, 0x0022)); - - emulator.ExpectErrno(EACCES, FakeSyscall(__NR_setuid, 0x0111)); - emulator.ExpectErrno(EACCES, FakeSyscall(__NR_setuid, 0x0222)); -} - -class SwitchPolicy : public Policy { - public: - SwitchPolicy() {} - ~SwitchPolicy() override {} - ResultExpr EvaluateSyscall(int sysno) const override { - if (sysno == __NR_fcntl) { - const Arg<int> cmd(1); - const Arg<unsigned long> long_arg(2); - return Switch(cmd) - .CASES((F_GETFL, F_GETFD), Error(ENOENT)) - .Case(F_SETFD, If(long_arg == O_CLOEXEC, Allow()).Else(Error(EINVAL))) - .Case(F_SETFL, Error(EPERM)) - .Default(Error(EACCES)); - } - return Allow(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(SwitchPolicy); -}; - -TEST(BPFDSL, SwitchTest) { - PolicyEmulator emulator(golden::kSwitchPolicy, SwitchPolicy()); - - const int kFakeSockFD = 42; - - emulator.ExpectErrno(ENOENT, FakeSyscall(__NR_fcntl, kFakeSockFD, F_GETFD)); - emulator.ExpectErrno(ENOENT, FakeSyscall(__NR_fcntl, kFakeSockFD, F_GETFL)); - - emulator.ExpectAllow( - FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFD, O_CLOEXEC)); - emulator.ExpectErrno(EINVAL, - FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFD, 0)); - - emulator.ExpectErrno(EPERM, - FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFL, O_RDONLY)); - - emulator.ExpectErrno(EACCES, - FakeSyscall(__NR_fcntl, kFakeSockFD, F_DUPFD, 0)); -} - -static intptr_t DummyTrap(const struct arch_seccomp_data& data, void* aux) { - return 0; -} - -TEST(BPFDSL, IsAllowDeny) { - ResultExpr allow = Allow(); - EXPECT_TRUE(allow->IsAllow()); - EXPECT_FALSE(allow->IsDeny()); - - ResultExpr error = Error(ENOENT); - EXPECT_FALSE(error->IsAllow()); - EXPECT_TRUE(error->IsDeny()); - - ResultExpr trace = Trace(42); - EXPECT_FALSE(trace->IsAllow()); - EXPECT_FALSE(trace->IsDeny()); - - ResultExpr trap = Trap(DummyTrap, nullptr); - EXPECT_FALSE(trap->IsAllow()); - EXPECT_TRUE(trap->IsDeny()); - - const Arg<int> arg(0); - ResultExpr maybe = If(arg == 0, Allow()).Else(Error(EPERM)); - EXPECT_FALSE(maybe->IsAllow()); - EXPECT_FALSE(maybe->IsDeny()); -} - -TEST(BPFDSL, HasUnsafeTraps) { - ResultExpr allow = Allow(); - EXPECT_FALSE(allow->HasUnsafeTraps()); - - ResultExpr safe = Trap(DummyTrap, nullptr); - EXPECT_FALSE(safe->HasUnsafeTraps()); - - ResultExpr unsafe = UnsafeTrap(DummyTrap, nullptr); - EXPECT_TRUE(unsafe->HasUnsafeTraps()); - - const Arg<int> arg(0); - ResultExpr maybe = If(arg == 0, allow).Else(unsafe); - EXPECT_TRUE(maybe->HasUnsafeTraps()); -} - -} // namespace -} // namespace bpf_dsl -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/codegen.cc b/sandbox/linux/bpf_dsl/codegen.cc deleted file mode 100644 index d88bd531a2..0000000000 --- a/sandbox/linux/bpf_dsl/codegen.cc +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2012 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/linux/bpf_dsl/codegen.h" - -#include <stddef.h> -#include <stdint.h> - -#include <limits> -#include <utility> - -#include "base/logging.h" -#include "sandbox/linux/system_headers/linux_filter.h" - -// This CodeGen implementation strives for simplicity while still -// generating acceptable BPF programs under typical usage patterns -// (e.g., by PolicyCompiler). -// -// The key to its simplicity is that BPF programs only support forward -// jumps/branches, which allows constraining the DAG construction API -// to make instruction nodes immutable. Immutable nodes admits a -// simple greedy approach of emitting new instructions as needed and -// then reusing existing ones that have already been emitted. This -// cleanly avoids any need to compute basic blocks or apply -// topological sorting because the API effectively sorts instructions -// for us (e.g., before MakeInstruction() can be called to emit a -// branch instruction, it must have already been called for each -// branch path). -// -// This greedy algorithm is not without (theoretical) weakness though: -// -// 1. In the general case, we don't eliminate dead code. If needed, -// we could trace back through the program in Compile() and elide -// any unneeded instructions, but in practice we only emit live -// instructions anyway. -// -// 2. By not dividing instructions into basic blocks and sorting, we -// lose an opportunity to move non-branch/non-return instructions -// adjacent to their successor instructions, which means we might -// need to emit additional jumps. But in practice, they'll -// already be nearby as long as callers don't go out of their way -// to interleave MakeInstruction() calls for unrelated code -// sequences. - -namespace sandbox { - -// kBranchRange is the maximum value that can be stored in -// sock_filter's 8-bit jt and jf fields. -const size_t kBranchRange = std::numeric_limits<uint8_t>::max(); - -const CodeGen::Node CodeGen::kNullNode; - -CodeGen::CodeGen() : program_(), equivalent_(), memos_() { -} - -CodeGen::~CodeGen() { -} - -CodeGen::Program CodeGen::Compile(CodeGen::Node head) { - return Program(program_.rbegin() + Offset(head), program_.rend()); -} - -CodeGen::Node CodeGen::MakeInstruction(uint16_t code, - uint32_t k, - Node jt, - Node jf) { - // To avoid generating redundant code sequences, we memoize the - // results from AppendInstruction(). - auto res = memos_.insert(std::make_pair(MemoKey(code, k, jt, jf), kNullNode)); - CodeGen::Node* node = &res.first->second; - if (res.second) { // Newly inserted memo entry. - *node = AppendInstruction(code, k, jt, jf); - } - return *node; -} - -CodeGen::Node CodeGen::AppendInstruction(uint16_t code, - uint32_t k, - Node jt, - Node jf) { - if (BPF_CLASS(code) == BPF_JMP) { - CHECK_NE(BPF_JA, BPF_OP(code)) << "CodeGen inserts JAs as needed"; - - // Optimally adding jumps is rather tricky, so we use a quick - // approximation: by artificially reducing |jt|'s range, |jt| will - // stay within its true range even if we add a jump for |jf|. - jt = WithinRange(jt, kBranchRange - 1); - jf = WithinRange(jf, kBranchRange); - return Append(code, k, Offset(jt), Offset(jf)); - } - - CHECK_EQ(kNullNode, jf) << "Non-branch instructions shouldn't provide jf"; - if (BPF_CLASS(code) == BPF_RET) { - CHECK_EQ(kNullNode, jt) << "Return instructions shouldn't provide jt"; - } else { - // For non-branch/non-return instructions, execution always - // proceeds to the next instruction; so we need to arrange for - // that to be |jt|. - jt = WithinRange(jt, 0); - CHECK_EQ(0U, Offset(jt)) << "ICE: Failed to setup next instruction"; - } - return Append(code, k, 0, 0); -} - -CodeGen::Node CodeGen::WithinRange(Node target, size_t range) { - // Just use |target| if it's already within range. - if (Offset(target) <= range) { - return target; - } - - // Alternatively, look for an equivalent instruction within range. - if (Offset(equivalent_.at(target)) <= range) { - return equivalent_.at(target); - } - - // Otherwise, fall back to emitting a jump instruction. - Node jump = Append(BPF_JMP | BPF_JA, Offset(target), 0, 0); - equivalent_.at(target) = jump; - return jump; -} - -CodeGen::Node CodeGen::Append(uint16_t code, uint32_t k, size_t jt, size_t jf) { - if (BPF_CLASS(code) == BPF_JMP && BPF_OP(code) != BPF_JA) { - CHECK_LE(jt, kBranchRange); - CHECK_LE(jf, kBranchRange); - } else { - CHECK_EQ(0U, jt); - CHECK_EQ(0U, jf); - } - - CHECK_LT(program_.size(), static_cast<size_t>(BPF_MAXINSNS)); - CHECK_EQ(program_.size(), equivalent_.size()); - - Node res = program_.size(); - program_.push_back(sock_filter{ - code, static_cast<uint8_t>(jt), static_cast<uint8_t>(jf), k}); - equivalent_.push_back(res); - return res; -} - -size_t CodeGen::Offset(Node target) const { - CHECK_LT(target, program_.size()) << "Bogus offset target node"; - return (program_.size() - 1) - target; -} - -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/codegen.h b/sandbox/linux/bpf_dsl/codegen.h deleted file mode 100644 index 3fc3f35a0d..0000000000 --- a/sandbox/linux/bpf_dsl/codegen.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2012 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_LINUX_BPF_DSL_CODEGEN_H__ -#define SANDBOX_LINUX_BPF_DSL_CODEGEN_H__ - -#include <stddef.h> -#include <stdint.h> - -#include <map> -#include <tuple> -#include <vector> - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -struct sock_filter; - -namespace sandbox { - -// The code generator implements a basic assembler that can convert a -// graph of BPF instructions into a well-formed array of BPF -// instructions. Most notably, it ensures that jumps are always -// forward and don't exceed the limit of 255 instructions imposed by -// the instruction set. -// -// Callers would typically create a new CodeGen object and then use it -// to build a DAG of instruction nodes. They'll eventually call -// Compile() to convert this DAG to a Program. -// -// CodeGen gen; -// CodeGen::Node allow, branch, dag; -// -// allow = -// gen.MakeInstruction(BPF_RET+BPF_K, -// ErrorCode(ErrorCode::ERR_ALLOWED).err())); -// branch = -// gen.MakeInstruction(BPF_JMP+BPF_EQ+BPF_K, __NR_getpid, -// Trap(GetPidHandler, NULL), allow); -// dag = -// gen.MakeInstruction(BPF_LD+BPF_W+BPF_ABS, -// offsetof(struct arch_seccomp_data, nr), branch); -// -// // Simplified code follows; in practice, it is important to avoid calling -// // any C++ destructors after starting the sandbox. -// CodeGen::Program program = gen.Compile(dag); -// const struct sock_fprog prog = { -// static_cast<unsigned short>(program.size()), &program[0] }; -// prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); -// -class SANDBOX_EXPORT CodeGen { - public: - // A vector of BPF instructions that need to be installed as a filter - // program in the kernel. - typedef std::vector<struct sock_filter> Program; - - // Node represents a node within the instruction DAG being compiled. - using Node = Program::size_type; - - // kNullNode represents the "null" node; i.e., the reserved node - // value guaranteed to not equal any actual nodes. - static const Node kNullNode = -1; - - CodeGen(); - ~CodeGen(); - - // MakeInstruction creates a node representing the specified - // instruction, or returns and existing equivalent node if one - // exists. For details on the possible parameters refer to - // https://www.kernel.org/doc/Documentation/networking/filter.txt. - // TODO(mdempsky): Reconsider using default arguments here. - Node MakeInstruction(uint16_t code, - uint32_t k, - Node jt = kNullNode, - Node jf = kNullNode); - - // Compile linearizes the instruction DAG rooted at |head| into a - // program that can be executed by a BPF virtual machine. - Program Compile(Node head); - - private: - using MemoKey = std::tuple<uint16_t, uint32_t, Node, Node>; - - // AppendInstruction adds a new instruction, ensuring that |jt| and - // |jf| are within range as necessary for |code|. - Node AppendInstruction(uint16_t code, uint32_t k, Node jt, Node jf); - - // WithinRange returns a node equivalent to |next| that is at most - // |range| instructions away from the (logical) beginning of the - // program. - Node WithinRange(Node next, size_t range); - - // Append appends a new instruction to the physical end (i.e., - // logical beginning) of |program_|. - Node Append(uint16_t code, uint32_t k, size_t jt, size_t jf); - - // Offset returns how many instructions exist in |program_| after |target|. - size_t Offset(Node target) const; - - // NOTE: program_ is the compiled program in *reverse*, so that - // indices remain stable as we add instructions. - Program program_; - - // equivalent_ stores the most recent semantically-equivalent node for each - // instruction in program_. A node is defined as semantically-equivalent to N - // if it has the same instruction code and constant as N and its successor - // nodes (if any) are semantically-equivalent to N's successor nodes, or - // if it's an unconditional jump to a node semantically-equivalent to N. - std::vector<Node> equivalent_; - - std::map<MemoKey, Node> memos_; - - DISALLOW_COPY_AND_ASSIGN(CodeGen); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_CODEGEN_H__ diff --git a/sandbox/linux/bpf_dsl/codegen_unittest.cc b/sandbox/linux/bpf_dsl/codegen_unittest.cc deleted file mode 100644 index 56a0dd27e1..0000000000 --- a/sandbox/linux/bpf_dsl/codegen_unittest.cc +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (c) 2012 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/linux/bpf_dsl/codegen.h" - -#include <stddef.h> -#include <stdint.h> - -#include <map> -#include <utility> -#include <vector> - -#include "base/macros.h" -#include "base/md5.h" -#include "base/strings/string_piece.h" -#include "sandbox/linux/system_headers/linux_filter.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { -namespace { - -// Hash provides an abstraction for building "hash trees" from BPF -// control flow graphs, and efficiently identifying equivalent graphs. -// -// For simplicity, we use MD5, because base happens to provide a -// convenient API for its use. However, any collision-resistant hash -// should suffice. -class Hash { - public: - static const Hash kZero; - - Hash() : digest_() {} - - Hash(uint16_t code, - uint32_t k, - const Hash& jt = kZero, - const Hash& jf = kZero) - : digest_() { - base::MD5Context ctx; - base::MD5Init(&ctx); - HashValue(&ctx, code); - HashValue(&ctx, k); - HashValue(&ctx, jt); - HashValue(&ctx, jf); - base::MD5Final(&digest_, &ctx); - } - - Hash(const Hash& hash) = default; - Hash& operator=(const Hash& rhs) = default; - - friend bool operator==(const Hash& lhs, const Hash& rhs) { - return lhs.Base16() == rhs.Base16(); - } - friend bool operator!=(const Hash& lhs, const Hash& rhs) { - return !(lhs == rhs); - } - - private: - template <typename T> - void HashValue(base::MD5Context* ctx, const T& value) { - base::MD5Update(ctx, - base::StringPiece(reinterpret_cast<const char*>(&value), - sizeof(value))); - } - - std::string Base16() const { - return base::MD5DigestToBase16(digest_); - } - - base::MD5Digest digest_; -}; - -const Hash Hash::kZero; - -// Sanity check that equality and inequality work on Hash as required. -TEST(CodeGen, HashSanity) { - std::vector<Hash> hashes; - - // Push a bunch of logically distinct hashes. - hashes.push_back(Hash::kZero); - for (int i = 0; i < 4; ++i) { - hashes.push_back(Hash(i & 1, i & 2)); - } - for (int i = 0; i < 16; ++i) { - hashes.push_back(Hash(i & 1, i & 2, Hash(i & 4, i & 8))); - } - for (int i = 0; i < 64; ++i) { - hashes.push_back( - Hash(i & 1, i & 2, Hash(i & 4, i & 8), Hash(i & 16, i & 32))); - } - - for (const Hash& a : hashes) { - for (const Hash& b : hashes) { - // Hashes should equal themselves, but not equal all others. - if (&a == &b) { - EXPECT_EQ(a, b); - } else { - EXPECT_NE(a, b); - } - } - } -} - -// ProgramTest provides a fixture for writing compiling sample -// programs with CodeGen and verifying the linearized output matches -// the input DAG. -class ProgramTest : public ::testing::Test { - protected: - ProgramTest() : gen_(), node_hashes_() {} - - // MakeInstruction calls CodeGen::MakeInstruction() and associated - // the returned address with a hash of the instruction. - CodeGen::Node MakeInstruction(uint16_t code, - uint32_t k, - CodeGen::Node jt = CodeGen::kNullNode, - CodeGen::Node jf = CodeGen::kNullNode) { - CodeGen::Node res = gen_.MakeInstruction(code, k, jt, jf); - EXPECT_NE(CodeGen::kNullNode, res); - - Hash digest(code, k, Lookup(jt), Lookup(jf)); - auto it = node_hashes_.insert(std::make_pair(res, digest)); - EXPECT_EQ(digest, it.first->second); - - return res; - } - - // RunTest compiles the program and verifies that the output matches - // what is expected. It should be called at the end of each program - // test case. - void RunTest(CodeGen::Node head) { - // Compile the program - CodeGen::Program program = gen_.Compile(head); - - // Walk the program backwards, and compute the hash for each instruction. - std::vector<Hash> prog_hashes(program.size()); - for (size_t i = program.size(); i > 0; --i) { - const sock_filter& insn = program.at(i - 1); - Hash& hash = prog_hashes.at(i - 1); - - if (BPF_CLASS(insn.code) == BPF_JMP) { - if (BPF_OP(insn.code) == BPF_JA) { - // The compiler adds JA instructions as needed, so skip them. - hash = prog_hashes.at(i + insn.k); - } else { - hash = Hash(insn.code, insn.k, prog_hashes.at(i + insn.jt), - prog_hashes.at(i + insn.jf)); - } - } else if (BPF_CLASS(insn.code) == BPF_RET) { - hash = Hash(insn.code, insn.k); - } else { - hash = Hash(insn.code, insn.k, prog_hashes.at(i)); - } - } - - EXPECT_EQ(Lookup(head), prog_hashes.at(0)); - } - - private: - const Hash& Lookup(CodeGen::Node next) const { - if (next == CodeGen::kNullNode) { - return Hash::kZero; - } - auto it = node_hashes_.find(next); - if (it == node_hashes_.end()) { - ADD_FAILURE() << "No hash found for node " << next; - return Hash::kZero; - } - return it->second; - } - - CodeGen gen_; - std::map<CodeGen::Node, Hash> node_hashes_; - - DISALLOW_COPY_AND_ASSIGN(ProgramTest); -}; - -TEST_F(ProgramTest, OneInstruction) { - // Create the most basic valid BPF program: - // RET 0 - CodeGen::Node head = MakeInstruction(BPF_RET + BPF_K, 0); - RunTest(head); -} - -TEST_F(ProgramTest, SimpleBranch) { - // Create a program with a single branch: - // JUMP if eq 42 then $0 else $1 - // 0: RET 1 - // 1: RET 0 - CodeGen::Node head = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 42, - MakeInstruction(BPF_RET + BPF_K, 1), - MakeInstruction(BPF_RET + BPF_K, 0)); - RunTest(head); -} - -TEST_F(ProgramTest, AtypicalBranch) { - // Create a program with a single branch: - // JUMP if eq 42 then $0 else $0 - // 0: RET 0 - - CodeGen::Node ret = MakeInstruction(BPF_RET + BPF_K, 0); - CodeGen::Node head = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 42, ret, ret); - - // N.B.: As the instructions in both sides of the branch are already - // the same object, we do not actually have any "mergeable" branches. - // This needs to be reflected in our choice of "flags". - RunTest(head); -} - -TEST_F(ProgramTest, Complex) { - // Creates a basic BPF program that we'll use to test some of the code: - // JUMP if eq 42 the $0 else $1 (insn6) - // 0: LD 23 (insn5) - // 1: JUMP if eq 42 then $2 else $4 (insn4) - // 2: JUMP to $3 (insn2) - // 3: LD 42 (insn1) - // RET 42 (insn0) - // 4: LD 42 (insn3) - // RET 42 (insn3+) - CodeGen::Node insn0 = MakeInstruction(BPF_RET + BPF_K, 42); - CodeGen::Node insn1 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 42, insn0); - CodeGen::Node insn2 = insn1; // Implicit JUMP - - // We explicitly duplicate instructions to test that they're merged. - CodeGen::Node insn3 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 42, - MakeInstruction(BPF_RET + BPF_K, 42)); - EXPECT_EQ(insn2, insn3); - - CodeGen::Node insn4 = - MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 42, insn2, insn3); - CodeGen::Node insn5 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 23, insn4); - - // Force a basic block that ends in neither a jump instruction nor a return - // instruction. It only contains "insn5". This exercises one of the less - // common code paths in the topo-sort algorithm. - // This also gives us a diamond-shaped pattern in our graph, which stresses - // another aspect of the topo-sort algorithm (namely, the ability to - // correctly count the incoming branches for subtrees that are not disjunct). - CodeGen::Node insn6 = - MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 42, insn5, insn4); - - RunTest(insn6); -} - -TEST_F(ProgramTest, ConfusingTails) { - // This simple program demonstrates https://crbug.com/351103/ - // The two "LOAD 0" instructions are blocks of their own. MergeTails() could - // be tempted to merge them since they are the same. However, they are - // not mergeable because they fall-through to non semantically equivalent - // blocks. - // Without the fix for this bug, this program should trigger the check in - // CompileAndCompare: the serialized graphs from the program and its compiled - // version will differ. - // - // 0) LOAD 1 // ??? - // 1) if A == 0x1; then JMP 2 else JMP 3 - // 2) LOAD 0 // System call number - // 3) if A == 0x2; then JMP 4 else JMP 5 - // 4) LOAD 0 // System call number - // 5) if A == 0x1; then JMP 6 else JMP 7 - // 6) RET 0 - // 7) RET 1 - - CodeGen::Node i7 = MakeInstruction(BPF_RET + BPF_K, 1); - CodeGen::Node i6 = MakeInstruction(BPF_RET + BPF_K, 0); - CodeGen::Node i5 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i6, i7); - CodeGen::Node i4 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i5); - CodeGen::Node i3 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5); - CodeGen::Node i2 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i3); - CodeGen::Node i1 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3); - CodeGen::Node i0 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1); - - RunTest(i0); -} - -TEST_F(ProgramTest, ConfusingTailsBasic) { - // Without the fix for https://crbug.com/351103/, (see - // SampleProgramConfusingTails()), this would generate a cyclic graph and - // crash as the two "LOAD 0" instructions would get merged. - // - // 0) LOAD 1 // ??? - // 1) if A == 0x1; then JMP 2 else JMP 3 - // 2) LOAD 0 // System call number - // 3) if A == 0x2; then JMP 4 else JMP 5 - // 4) LOAD 0 // System call number - // 5) RET 1 - - CodeGen::Node i5 = MakeInstruction(BPF_RET + BPF_K, 1); - CodeGen::Node i4 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i5); - CodeGen::Node i3 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5); - CodeGen::Node i2 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i3); - CodeGen::Node i1 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3); - CodeGen::Node i0 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1); - - RunTest(i0); -} - -TEST_F(ProgramTest, ConfusingTailsMergeable) { - // This is similar to SampleProgramConfusingTails(), except that - // instructions 2 and 4 are now RET instructions. - // In PointerCompare(), this exercises the path where two blocks are of the - // same length and identical and the last instruction is a JMP or RET, so the - // following blocks don't need to be looked at and the blocks are mergeable. - // - // 0) LOAD 1 // ??? - // 1) if A == 0x1; then JMP 2 else JMP 3 - // 2) RET 42 - // 3) if A == 0x2; then JMP 4 else JMP 5 - // 4) RET 42 - // 5) if A == 0x1; then JMP 6 else JMP 7 - // 6) RET 0 - // 7) RET 1 - - CodeGen::Node i7 = MakeInstruction(BPF_RET + BPF_K, 1); - CodeGen::Node i6 = MakeInstruction(BPF_RET + BPF_K, 0); - CodeGen::Node i5 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i6, i7); - CodeGen::Node i4 = MakeInstruction(BPF_RET + BPF_K, 42); - CodeGen::Node i3 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5); - CodeGen::Node i2 = MakeInstruction(BPF_RET + BPF_K, 42); - CodeGen::Node i1 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3); - CodeGen::Node i0 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1); - - RunTest(i0); -} - -TEST_F(ProgramTest, InstructionFolding) { - // Check that simple instructions are folded as expected. - CodeGen::Node a = MakeInstruction(BPF_RET + BPF_K, 0); - EXPECT_EQ(a, MakeInstruction(BPF_RET + BPF_K, 0)); - CodeGen::Node b = MakeInstruction(BPF_RET + BPF_K, 1); - EXPECT_EQ(a, MakeInstruction(BPF_RET + BPF_K, 0)); - EXPECT_EQ(b, MakeInstruction(BPF_RET + BPF_K, 1)); - EXPECT_EQ(b, MakeInstruction(BPF_RET + BPF_K, 1)); - - // Check that complex sequences are folded too. - CodeGen::Node c = - MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, - MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, 0x100, a, b)); - EXPECT_EQ(c, MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, 0, - MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, 0x100, a, b))); - - RunTest(c); -} - -TEST_F(ProgramTest, FarBranches) { - // BPF instructions use 8-bit fields for branch offsets, which means - // branch targets must be within 255 instructions of the branch - // instruction. CodeGen abstracts away this detail by inserting jump - // instructions as needed, which we test here by generating programs - // that should trigger any interesting boundary conditions. - - // Populate with 260 initial instruction nodes. - std::vector<CodeGen::Node> nodes; - nodes.push_back(MakeInstruction(BPF_RET + BPF_K, 0)); - for (size_t i = 1; i < 260; ++i) { - nodes.push_back( - MakeInstruction(BPF_ALU + BPF_ADD + BPF_K, i, nodes.back())); - } - - // Exhaustively test branch offsets near BPF's limits. - for (size_t jt = 250; jt < 260; ++jt) { - for (size_t jf = 250; jf < 260; ++jf) { - nodes.push_back(MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 0, - nodes.rbegin()[jt], nodes.rbegin()[jf])); - RunTest(nodes.back()); - } - } -} - -TEST_F(ProgramTest, JumpReuse) { - // As a code size optimization, we try to reuse jumps when possible - // instead of emitting new ones. Here we make sure that optimization - // is working as intended. - // - // NOTE: To simplify testing, we rely on implementation details - // about what CodeGen::Node values indicate (i.e., vector indices), - // but CodeGen users should treat them as opaque values. - - // Populate with 260 initial instruction nodes. - std::vector<CodeGen::Node> nodes; - nodes.push_back(MakeInstruction(BPF_RET + BPF_K, 0)); - for (size_t i = 1; i < 260; ++i) { - nodes.push_back( - MakeInstruction(BPF_ALU + BPF_ADD + BPF_K, i, nodes.back())); - } - - // Branching to nodes[0] and nodes[1] should require 3 new - // instructions: two far jumps plus the branch itself. - CodeGen::Node one = - MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 0, nodes[0], nodes[1]); - EXPECT_EQ(nodes.back() + 3, one); // XXX: Implementation detail! - RunTest(one); - - // Branching again to the same target nodes should require only one - // new instruction, as we can reuse the previous branch's jumps. - CodeGen::Node two = - MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, nodes[0], nodes[1]); - EXPECT_EQ(one + 1, two); // XXX: Implementation detail! - RunTest(two); -} - -} // namespace -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/cons.h b/sandbox/linux/bpf_dsl/cons.h deleted file mode 100644 index 07ac3dfc23..0000000000 --- a/sandbox/linux/bpf_dsl/cons.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2014 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_LINUX_BPF_DSL_CONS_H_ -#define SANDBOX_LINUX_BPF_DSL_CONS_H_ - -#include <memory> - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace cons { - -// Namespace cons provides an abstraction for immutable "cons list" -// data structures as commonly provided in functional programming -// languages like Lisp or Haskell. -// -// A cons list is a linked list consisting of "cells", each of which -// have a "head" and a "tail" element. A cell's head element contains -// a user specified value, while the tail element contains a (possibly -// null) pointer to another cell. -// -// An empty list (idiomatically referred to as "nil") can be -// constructed as "cons::List<Foo>()" or simply as "nullptr" if Foo -// can be inferred from context (e.g., calling a function that has a -// "cons::List<Foo>" parameter). -// -// Existing lists (including empty lists) can be extended by -// prepending new values to the front using the "Cons(head, tail)" -// function, which will allocate a new cons cell. Notably, cons lists -// support creating multiple lists that share a common tail sequence. -// -// Lastly, lists support iteration via C++11's range-based for loop -// construct. -// -// Examples: -// -// // basic construction -// const cons::List<char> kNil = nullptr; -// cons::List<char> ba = Cons('b', Cons('a', kNil)); -// -// // common tail sequence -// cons::List<char> cba = Cons('c', ba); -// cons::List<char> dba = Cons('d', ba); -// -// // iteration -// for (const char& ch : cba) { -// // iterates 'c', 'b', 'a' -// } -// for (const char& ch : dba) { -// // iterates 'd', 'b', 'a' -// } - -// Forward declarations. -template <typename T> -class Cell; -template <typename T> -class ListIterator; - -// List represents a (possibly null) pointer to a cons cell. -template <typename T> -using List = std::shared_ptr<const Cell<T>>; - -// Cons extends a cons list by prepending a new value to the front. -template <typename T> -List<T> Cons(const T& head, List<T> tail) { - return std::make_shared<Cell<T>>(head, std::move(tail)); -} - -// Cell represents an individual "cons cell" within a cons list. -template <typename T> -class Cell { - public: - Cell(const T& head, List<T> tail) : head_(head), tail_(std::move(tail)) {} - - // Head returns this cell's head element. - const T& head() const { return head_; } - - // Tail returns this cell's tail element. - const List<T>& tail() const { return tail_; } - - private: - T head_; - List<T> tail_; - - DISALLOW_COPY_AND_ASSIGN(Cell); -}; - -// Begin returns a list iterator pointing to the first element of the -// cons list. It's provided to support range-based for loops. -template <typename T> -ListIterator<T> begin(const List<T>& list) { - return ListIterator<T>(list); -} - -// End returns a list iterator pointing to the "past-the-end" element -// of the cons list (i.e., nil). It's provided to support range-based -// for loops. -template <typename T> -ListIterator<T> end(const List<T>& list) { - return ListIterator<T>(); -} - -// ListIterator provides C++ forward iterator semantics for traversing -// a cons list. -template <typename T> -class ListIterator { - public: - ListIterator() : list_() {} - explicit ListIterator(const List<T>& list) : list_(list) {} - - const T& operator*() const { return list_->head(); } - - ListIterator& operator++() { - list_ = list_->tail(); - return *this; - } - - friend bool operator==(const ListIterator& lhs, const ListIterator& rhs) { - return lhs.list_ == rhs.list_; - } - - private: - List<T> list_; -}; - -template <typename T> -bool operator!=(const ListIterator<T>& lhs, const ListIterator<T>& rhs) { - return !(lhs == rhs); -} - -} // namespace cons -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_CONS_H_ diff --git a/sandbox/linux/bpf_dsl/dump_bpf.cc b/sandbox/linux/bpf_dsl/dump_bpf.cc deleted file mode 100644 index 2edf592f68..0000000000 --- a/sandbox/linux/bpf_dsl/dump_bpf.cc +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2014 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/linux/bpf_dsl/dump_bpf.h" - -#include <inttypes.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> - -#include <string> - -#include "base/strings/stringprintf.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/bpf_dsl/trap_registry.h" -#include "sandbox/linux/system_headers/linux_filter.h" -#include "sandbox/linux/system_headers/linux_seccomp.h" - -namespace sandbox { -namespace bpf_dsl { - -namespace { - -const char* AluOpToken(uint32_t code) { - switch (BPF_OP(code)) { - case BPF_ADD: - return "+"; - case BPF_SUB: - return "-"; - case BPF_MUL: - return "*"; - case BPF_DIV: - return "/"; - case BPF_MOD: - return "%"; - case BPF_OR: - return "|"; - case BPF_XOR: - return "^"; - case BPF_AND: - return "&"; - case BPF_LSH: - return "<<"; - case BPF_RSH: - return ">>"; - default: - return "???"; - } -} - -const char* JmpOpToken(uint32_t code) { - switch (BPF_OP(code)) { - case BPF_JSET: - return "&"; - case BPF_JEQ: - return "=="; - case BPF_JGE: - return ">="; - default: - return "???"; - } -} - -const char* DataOffsetName(size_t off) { - switch (off) { - case SECCOMP_NR_IDX: - return "System call number"; - case SECCOMP_ARCH_IDX: - return "Architecture"; - case SECCOMP_IP_LSB_IDX: - return "Instruction pointer (LSB)"; - case SECCOMP_IP_MSB_IDX: - return "Instruction pointer (MSB)"; - default: - return "???"; - } -} - -void AppendInstruction(std::string* dst, size_t pc, const sock_filter& insn) { - base::StringAppendF(dst, "%3zu) ", pc); - switch (BPF_CLASS(insn.code)) { - case BPF_LD: - if (insn.code == BPF_LD + BPF_W + BPF_ABS) { - base::StringAppendF(dst, "LOAD %" PRIu32 " // ", insn.k); - size_t maybe_argno = - (insn.k - offsetof(struct arch_seccomp_data, args)) / - sizeof(uint64_t); - if (maybe_argno < 6 && insn.k == SECCOMP_ARG_LSB_IDX(maybe_argno)) { - base::StringAppendF(dst, "Argument %zu (LSB)\n", maybe_argno); - } else if (maybe_argno < 6 && - insn.k == SECCOMP_ARG_MSB_IDX(maybe_argno)) { - base::StringAppendF(dst, "Argument %zu (MSB)\n", maybe_argno); - } else { - base::StringAppendF(dst, "%s\n", DataOffsetName(insn.k)); - } - } else { - base::StringAppendF(dst, "Load ???\n"); - } - break; - case BPF_JMP: - if (BPF_OP(insn.code) == BPF_JA) { - base::StringAppendF(dst, "JMP %zu\n", pc + insn.k + 1); - } else { - base::StringAppendF( - dst, "if A %s 0x%" PRIx32 "; then JMP %zu else JMP %zu\n", - JmpOpToken(insn.code), insn.k, pc + insn.jt + 1, pc + insn.jf + 1); - } - break; - case BPF_RET: - base::StringAppendF(dst, "RET 0x%" PRIx32 " // ", insn.k); - if ((insn.k & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP) { - base::StringAppendF(dst, "Trap #%" PRIu32 "\n", - insn.k & SECCOMP_RET_DATA); - } else if ((insn.k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) { - base::StringAppendF(dst, "errno = %" PRIu32 "\n", - insn.k & SECCOMP_RET_DATA); - } else if ((insn.k & SECCOMP_RET_ACTION) == SECCOMP_RET_TRACE) { - base::StringAppendF(dst, "Trace #%" PRIu32 "\n", - insn.k & SECCOMP_RET_DATA); - } else if (insn.k == SECCOMP_RET_ALLOW) { - base::StringAppendF(dst, "Allowed\n"); - } else if (insn.k == SECCOMP_RET_KILL) { - base::StringAppendF(dst, "Kill\n"); - } else { - base::StringAppendF(dst, "???\n"); - } - break; - case BPF_ALU: - if (BPF_OP(insn.code) == BPF_NEG) { - base::StringAppendF(dst, "A := -A\n"); - } else { - base::StringAppendF(dst, "A := A %s 0x%" PRIx32 "\n", - AluOpToken(insn.code), insn.k); - } - break; - default: - base::StringAppendF(dst, "???\n"); - break; - } -} - -} // namespace - -void DumpBPF::PrintProgram(const CodeGen::Program& program) { - fputs(StringPrintProgram(program).c_str(), stderr); -} - -std::string DumpBPF::StringPrintProgram(const CodeGen::Program& program) { - std::string res; - for (size_t i = 0; i < program.size(); i++) { - AppendInstruction(&res, i + 1, program[i]); - } - return res; -} - -} // namespace bpf_dsl -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/dump_bpf.h b/sandbox/linux/bpf_dsl/dump_bpf.h deleted file mode 100644 index a7db58981b..0000000000 --- a/sandbox/linux/bpf_dsl/dump_bpf.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2014 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 <string> - -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace bpf_dsl { - -class SANDBOX_EXPORT DumpBPF { - public: - // PrintProgram writes |program| in a human-readable format to stderr. - static void PrintProgram(const CodeGen::Program& program); - - // StringPrintProgram writes |program| in a human-readable format to - // a std::string. - static std::string StringPrintProgram(const CodeGen::Program& program); -}; - -} // namespace bpf_dsl -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/errorcode.h b/sandbox/linux/bpf_dsl/errorcode.h deleted file mode 100644 index 611c27dd80..0000000000 --- a/sandbox/linux/bpf_dsl/errorcode.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2012 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_LINUX_BPF_DSL_ERRORCODE_H__ -#define SANDBOX_LINUX_BPF_DSL_ERRORCODE_H__ - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace bpf_dsl { - -// TODO(mdempsky): Find a proper home for ERR_{MIN,MAX}_ERRNO and -// remove this header. -class SANDBOX_EXPORT ErrorCode { - public: - enum { - ERR_MIN_ERRNO = 0, -#if defined(__mips__) - // MIPS only supports errno up to 1133 - ERR_MAX_ERRNO = 1133, -#else - // TODO(markus): Android only supports errno up to 255 - // (crbug.com/181647). - ERR_MAX_ERRNO = 4095, -#endif - }; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(ErrorCode); -}; - -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_ERRORCODE_H__ diff --git a/sandbox/linux/bpf_dsl/linux_syscall_ranges.h b/sandbox/linux/bpf_dsl/linux_syscall_ranges.h deleted file mode 100644 index a747770c78..0000000000 --- a/sandbox/linux/bpf_dsl/linux_syscall_ranges.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015 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_LINUX_BPF_DSL_LINUX_SYSCALL_RANGES_H_ -#define SANDBOX_LINUX_BPF_DSL_LINUX_SYSCALL_RANGES_H_ - -#if defined(__x86_64__) - -#define MIN_SYSCALL 0u -#define MAX_PUBLIC_SYSCALL 1024u -#define MAX_SYSCALL MAX_PUBLIC_SYSCALL - -#elif defined(__i386__) - -#define MIN_SYSCALL 0u -#define MAX_PUBLIC_SYSCALL 1024u -#define MAX_SYSCALL MAX_PUBLIC_SYSCALL - -#elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) - -// ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|, -// and a "ghost syscall private to the kernel", cmpxchg, -// at |__ARM_NR_BASE+0x00fff0|. -// See </arch/arm/include/asm/unistd.h> in the Linux kernel. - -// __NR_SYSCALL_BASE is 0 in thumb and ARM EABI. -#define MIN_SYSCALL 0u -#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + 1024u) -// __ARM_NR_BASE is __NR_SYSCALL_BASE + 0xf0000u -#define MIN_PRIVATE_SYSCALL 0xf0000u -#define MAX_PRIVATE_SYSCALL (MIN_PRIVATE_SYSCALL + 16u) -#define MIN_GHOST_SYSCALL (MIN_PRIVATE_SYSCALL + 0xfff0u) -#define MAX_SYSCALL (MIN_GHOST_SYSCALL + 4u) - -#elif defined(__mips__) && (_MIPS_SIM == _ABIO32) - -#include <asm/unistd.h> // for __NR_O32_Linux and __NR_Linux_syscalls -#define MIN_SYSCALL __NR_O32_Linux -#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + __NR_Linux_syscalls) -#define MAX_SYSCALL MAX_PUBLIC_SYSCALL - -#elif defined(__mips__) && (_MIPS_SIM == _ABI64) - -#error "Add support to header file" - -#elif defined(__aarch64__) - -#define MIN_SYSCALL 0u -#define MAX_PUBLIC_SYSCALL 279u -#define MAX_SYSCALL MAX_PUBLIC_SYSCALL - -#else -#error "Unsupported architecture" -#endif - -#endif // SANDBOX_LINUX_BPF_DSL_LINUX_SYSCALL_RANGES_H_ diff --git a/sandbox/linux/bpf_dsl/policy.cc b/sandbox/linux/bpf_dsl/policy.cc deleted file mode 100644 index c20edc6da8..0000000000 --- a/sandbox/linux/bpf_dsl/policy.cc +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2014 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/linux/bpf_dsl/policy.h" - -#include <errno.h> - -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" - -namespace sandbox { -namespace bpf_dsl { - -ResultExpr Policy::InvalidSyscall() const { - return Error(ENOSYS); -} - -} // namespace bpf_dsl -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/policy.h b/sandbox/linux/bpf_dsl/policy.h deleted file mode 100644 index 6c67589456..0000000000 --- a/sandbox/linux/bpf_dsl/policy.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 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_LINUX_BPF_DSL_POLICY_H_ -#define SANDBOX_LINUX_BPF_DSL_POLICY_H_ - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace bpf_dsl { - -// Interface to implement to define a BPF sandbox policy. -class SANDBOX_EXPORT Policy { - public: - Policy() {} - virtual ~Policy() {} - - // User extension point for writing custom sandbox policies. - // The returned ResultExpr will control how the kernel responds to the - // specified system call number. - virtual ResultExpr EvaluateSyscall(int sysno) const = 0; - - // Optional overload for specifying alternate behavior for invalid - // system calls. The default is to return ENOSYS. - virtual ResultExpr InvalidSyscall() const; - - private: - DISALLOW_COPY_AND_ASSIGN(Policy); -}; - -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_POLICY_H_ diff --git a/sandbox/linux/bpf_dsl/policy_compiler.cc b/sandbox/linux/bpf_dsl/policy_compiler.cc deleted file mode 100644 index 7ce517a5d5..0000000000 --- a/sandbox/linux/bpf_dsl/policy_compiler.cc +++ /dev/null @@ -1,466 +0,0 @@ -// Copyright (c) 2012 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/linux/bpf_dsl/policy_compiler.h" - -#include <errno.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/syscall.h> - -#include <limits> - -#include "base/logging.h" -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/bpf_dsl/syscall_set.h" -#include "sandbox/linux/system_headers/linux_filter.h" -#include "sandbox/linux/system_headers/linux_seccomp.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -namespace sandbox { -namespace bpf_dsl { - -namespace { - -#if defined(__i386__) || defined(__x86_64__) -const bool kIsIntel = true; -#else -const bool kIsIntel = false; -#endif -#if defined(__x86_64__) && defined(__ILP32__) -const bool kIsX32 = true; -#else -const bool kIsX32 = false; -#endif - -const int kSyscallsRequiredForUnsafeTraps[] = { - __NR_rt_sigprocmask, - __NR_rt_sigreturn, -#if defined(__NR_sigprocmask) - __NR_sigprocmask, -#endif -#if defined(__NR_sigreturn) - __NR_sigreturn, -#endif -}; - -bool HasExactlyOneBit(uint64_t x) { - // Common trick; e.g., see http://stackoverflow.com/a/108329. - return x != 0 && (x & (x - 1)) == 0; -} - -ResultExpr DefaultPanic(const char* error) { - return Kill(); -} - -// A Trap() handler that returns an "errno" value. The value is encoded -// in the "aux" parameter. -intptr_t ReturnErrno(const struct arch_seccomp_data&, void* aux) { - // TrapFnc functions report error by following the native kernel convention - // of returning an exit code in the range of -1..-4096. They do not try to - // set errno themselves. The glibc wrapper that triggered the SIGSYS will - // ultimately do so for us. - int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA; - return -err; -} - -bool HasUnsafeTraps(const Policy* policy) { - DCHECK(policy); - for (uint32_t sysnum : SyscallSet::ValidOnly()) { - if (policy->EvaluateSyscall(sysnum)->HasUnsafeTraps()) { - return true; - } - } - return policy->InvalidSyscall()->HasUnsafeTraps(); -} - -} // namespace - -struct PolicyCompiler::Range { - uint32_t from; - CodeGen::Node node; -}; - -PolicyCompiler::PolicyCompiler(const Policy* policy, TrapRegistry* registry) - : policy_(policy), - registry_(registry), - escapepc_(0), - panic_func_(DefaultPanic), - gen_(), - has_unsafe_traps_(HasUnsafeTraps(policy_)) { - DCHECK(policy); -} - -PolicyCompiler::~PolicyCompiler() { -} - -CodeGen::Program PolicyCompiler::Compile() { - CHECK(policy_->InvalidSyscall()->IsDeny()) - << "Policies should deny invalid system calls"; - - // If our BPF program has unsafe traps, enable support for them. - if (has_unsafe_traps_) { - CHECK_NE(0U, escapepc_) << "UnsafeTrap() requires a valid escape PC"; - - for (int sysnum : kSyscallsRequiredForUnsafeTraps) { - CHECK(policy_->EvaluateSyscall(sysnum)->IsAllow()) - << "Policies that use UnsafeTrap() must unconditionally allow all " - "required system calls"; - } - - CHECK(registry_->EnableUnsafeTraps()) - << "We'd rather die than enable unsafe traps"; - } - - // Assemble the BPF filter program. - return gen_.Compile(AssemblePolicy()); -} - -void PolicyCompiler::DangerousSetEscapePC(uint64_t escapepc) { - escapepc_ = escapepc; -} - -void PolicyCompiler::SetPanicFunc(PanicFunc panic_func) { - panic_func_ = panic_func; -} - -CodeGen::Node PolicyCompiler::AssemblePolicy() { - // A compiled policy consists of three logical parts: - // 1. Check that the "arch" field matches the expected architecture. - // 2. If the policy involves unsafe traps, check if the syscall was - // invoked by Syscall::Call, and then allow it unconditionally. - // 3. Check the system call number and jump to the appropriate compiled - // system call policy number. - return CheckArch(MaybeAddEscapeHatch(DispatchSyscall())); -} - -CodeGen::Node PolicyCompiler::CheckArch(CodeGen::Node passed) { - // If the architecture doesn't match SECCOMP_ARCH, disallow the - // system call. - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARCH_IDX, - gen_.MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, SECCOMP_ARCH, passed, - CompileResult(panic_func_( - "Invalid audit architecture in BPF filter")))); -} - -CodeGen::Node PolicyCompiler::MaybeAddEscapeHatch(CodeGen::Node rest) { - // If no unsafe traps, then simply return |rest|. - if (!has_unsafe_traps_) { - return rest; - } - - // We already enabled unsafe traps in Compile, but enable them again to give - // the trap registry a second chance to complain before we add the backdoor. - CHECK(registry_->EnableUnsafeTraps()); - - // Allow system calls, if they originate from our magic return address. - const uint32_t lopc = static_cast<uint32_t>(escapepc_); - const uint32_t hipc = static_cast<uint32_t>(escapepc_ >> 32); - - // BPF cannot do native 64-bit comparisons, so we have to compare - // both 32-bit halves of the instruction pointer. If they match what - // we expect, we return ERR_ALLOWED. If either or both don't match, - // we continue evalutating the rest of the sandbox policy. - // - // For simplicity, we check the full 64-bit instruction pointer even - // on 32-bit architectures. - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, SECCOMP_IP_LSB_IDX, - gen_.MakeInstruction( - BPF_JMP + BPF_JEQ + BPF_K, lopc, - gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, SECCOMP_IP_MSB_IDX, - gen_.MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, hipc, - CompileResult(Allow()), rest)), - rest)); -} - -CodeGen::Node PolicyCompiler::DispatchSyscall() { - // Evaluate all possible system calls and group their Nodes into - // ranges of identical codes. - Ranges ranges; - FindRanges(&ranges); - - // Compile the system call ranges to an optimized BPF jumptable - CodeGen::Node jumptable = AssembleJumpTable(ranges.begin(), ranges.end()); - - // Grab the system call number, so that we can check it and then - // execute the jump table. - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, SECCOMP_NR_IDX, CheckSyscallNumber(jumptable)); -} - -CodeGen::Node PolicyCompiler::CheckSyscallNumber(CodeGen::Node passed) { - if (kIsIntel) { - // On Intel architectures, verify that system call numbers are in the - // expected number range. - CodeGen::Node invalidX32 = - CompileResult(panic_func_("Illegal mixing of system call ABIs")); - if (kIsX32) { - // The newer x32 API always sets bit 30. - return gen_.MakeInstruction( - BPF_JMP + BPF_JSET + BPF_K, 0x40000000, passed, invalidX32); - } else { - // The older i386 and x86-64 APIs clear bit 30 on all system calls. - return gen_.MakeInstruction( - BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, passed); - } - } - - // TODO(mdempsky): Similar validation for other architectures? - return passed; -} - -void PolicyCompiler::FindRanges(Ranges* ranges) { - // Please note that "struct seccomp_data" defines system calls as a signed - // int32_t, but BPF instructions always operate on unsigned quantities. We - // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL, - // and then verifying that the rest of the number range (both positive and - // negative) all return the same Node. - const CodeGen::Node invalid_node = CompileResult(policy_->InvalidSyscall()); - uint32_t old_sysnum = 0; - CodeGen::Node old_node = - SyscallSet::IsValid(old_sysnum) - ? CompileResult(policy_->EvaluateSyscall(old_sysnum)) - : invalid_node; - - for (uint32_t sysnum : SyscallSet::All()) { - CodeGen::Node node = - SyscallSet::IsValid(sysnum) - ? CompileResult(policy_->EvaluateSyscall(static_cast<int>(sysnum))) - : invalid_node; - // N.B., here we rely on CodeGen folding (i.e., returning the same - // node value for) identical code sequences, otherwise our jump - // table will blow up in size. - if (node != old_node) { - ranges->push_back(Range{old_sysnum, old_node}); - old_sysnum = sysnum; - old_node = node; - } - } - ranges->push_back(Range{old_sysnum, old_node}); -} - -CodeGen::Node PolicyCompiler::AssembleJumpTable(Ranges::const_iterator start, - Ranges::const_iterator stop) { - // We convert the list of system call ranges into jump table that performs - // a binary search over the ranges. - // As a sanity check, we need to have at least one distinct ranges for us - // to be able to build a jump table. - CHECK(start < stop) << "Invalid iterator range"; - const auto n = stop - start; - if (n == 1) { - // If we have narrowed things down to a single range object, we can - // return from the BPF filter program. - return start->node; - } - - // Pick the range object that is located at the mid point of our list. - // We compare our system call number against the lowest valid system call - // number in this range object. If our number is lower, it is outside of - // this range object. If it is greater or equal, it might be inside. - Ranges::const_iterator mid = start + n / 2; - - // Sub-divide the list of ranges and continue recursively. - CodeGen::Node jf = AssembleJumpTable(start, mid); - CodeGen::Node jt = AssembleJumpTable(mid, stop); - return gen_.MakeInstruction(BPF_JMP + BPF_JGE + BPF_K, mid->from, jt, jf); -} - -CodeGen::Node PolicyCompiler::CompileResult(const ResultExpr& res) { - return res->Compile(this); -} - -CodeGen::Node PolicyCompiler::MaskedEqual(int argno, - size_t width, - uint64_t mask, - uint64_t value, - CodeGen::Node passed, - CodeGen::Node failed) { - // Sanity check that arguments make sense. - CHECK(argno >= 0 && argno < 6) << "Invalid argument number " << argno; - CHECK(width == 4 || width == 8) << "Invalid argument width " << width; - CHECK_NE(0U, mask) << "Zero mask is invalid"; - CHECK_EQ(value, value & mask) << "Value contains masked out bits"; - if (sizeof(void*) == 4) { - CHECK_EQ(4U, width) << "Invalid width on 32-bit platform"; - } - if (width == 4) { - CHECK_EQ(0U, mask >> 32) << "Mask exceeds argument size"; - CHECK_EQ(0U, value >> 32) << "Value exceeds argument size"; - } - - // We want to emit code to check "(arg & mask) == value" where arg, mask, and - // value are 64-bit values, but the BPF machine is only 32-bit. We implement - // this by independently testing the upper and lower 32-bits and continuing to - // |passed| if both evaluate true, or to |failed| if either evaluate false. - return MaskedEqualHalf(argno, width, mask, value, ArgHalf::UPPER, - MaskedEqualHalf(argno, width, mask, value, - ArgHalf::LOWER, passed, failed), - failed); -} - -CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno, - size_t width, - uint64_t full_mask, - uint64_t full_value, - ArgHalf half, - CodeGen::Node passed, - CodeGen::Node failed) { - if (width == 4 && half == ArgHalf::UPPER) { - // Special logic for sanity checking the upper 32-bits of 32-bit system - // call arguments. - - // TODO(mdempsky): Compile Unexpected64bitArgument() just per program. - CodeGen::Node invalid_64bit = Unexpected64bitArgument(); - - const uint32_t upper = SECCOMP_ARG_MSB_IDX(argno); - const uint32_t lower = SECCOMP_ARG_LSB_IDX(argno); - - if (sizeof(void*) == 4) { - // On 32-bit platforms, the upper 32-bits should always be 0: - // LDW [upper] - // JEQ 0, passed, invalid - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - upper, - gen_.MakeInstruction( - BPF_JMP + BPF_JEQ + BPF_K, 0, passed, invalid_64bit)); - } - - // On 64-bit platforms, the upper 32-bits may be 0 or ~0; but we only allow - // ~0 if the sign bit of the lower 32-bits is set too: - // LDW [upper] - // JEQ 0, passed, (next) - // JEQ ~0, (next), invalid - // LDW [lower] - // JSET (1<<31), passed, invalid - // - // TODO(mdempsky): The JSET instruction could perhaps jump to passed->next - // instead, as the first instruction of passed should be "LDW [lower]". - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - upper, - gen_.MakeInstruction( - BPF_JMP + BPF_JEQ + BPF_K, - 0, - passed, - gen_.MakeInstruction( - BPF_JMP + BPF_JEQ + BPF_K, - std::numeric_limits<uint32_t>::max(), - gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - lower, - gen_.MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, - 1U << 31, - passed, - invalid_64bit)), - invalid_64bit))); - } - - const uint32_t idx = (half == ArgHalf::UPPER) ? SECCOMP_ARG_MSB_IDX(argno) - : SECCOMP_ARG_LSB_IDX(argno); - const uint32_t mask = (half == ArgHalf::UPPER) ? full_mask >> 32 : full_mask; - const uint32_t value = - (half == ArgHalf::UPPER) ? full_value >> 32 : full_value; - - // Emit a suitable instruction sequence for (arg & mask) == value. - - // For (arg & 0) == 0, just return passed. - if (mask == 0) { - CHECK_EQ(0U, value); - return passed; - } - - // For (arg & ~0) == value, emit: - // LDW [idx] - // JEQ value, passed, failed - if (mask == std::numeric_limits<uint32_t>::max()) { - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - idx, - gen_.MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)); - } - - // For (arg & mask) == 0, emit: - // LDW [idx] - // JSET mask, failed, passed - // (Note: failed and passed are intentionally swapped.) - if (value == 0) { - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - idx, - gen_.MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, failed, passed)); - } - - // For (arg & x) == x where x is a single-bit value, emit: - // LDW [idx] - // JSET mask, passed, failed - if (mask == value && HasExactlyOneBit(mask)) { - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - idx, - gen_.MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, passed, failed)); - } - - // Generic fallback: - // LDW [idx] - // AND mask - // JEQ value, passed, failed - return gen_.MakeInstruction( - BPF_LD + BPF_W + BPF_ABS, - idx, - gen_.MakeInstruction( - BPF_ALU + BPF_AND + BPF_K, - mask, - gen_.MakeInstruction( - BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed))); -} - -CodeGen::Node PolicyCompiler::Unexpected64bitArgument() { - return CompileResult(panic_func_("Unexpected 64bit argument detected")); -} - -CodeGen::Node PolicyCompiler::Return(uint32_t ret) { - if (has_unsafe_traps_ && (ret & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) { - // When inside an UnsafeTrap() callback, we want to allow all system calls. - // This means, we must conditionally disable the sandbox -- and that's not - // something that kernel-side BPF filters can do, as they cannot inspect - // any state other than the syscall arguments. - // But if we redirect all error handlers to user-space, then we can easily - // make this decision. - // The performance penalty for this extra round-trip to user-space is not - // actually that bad, as we only ever pay it for denied system calls; and a - // typical program has very few of these. - return Trap(ReturnErrno, reinterpret_cast<void*>(ret & SECCOMP_RET_DATA), - true); - } - - return gen_.MakeInstruction(BPF_RET + BPF_K, ret); -} - -CodeGen::Node PolicyCompiler::Trap(TrapRegistry::TrapFnc fnc, - const void* aux, - bool safe) { - uint16_t trap_id = registry_->Add(fnc, aux, safe); - return gen_.MakeInstruction(BPF_RET + BPF_K, SECCOMP_RET_TRAP + trap_id); -} - -bool PolicyCompiler::IsRequiredForUnsafeTrap(int sysno) { - for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) { - if (sysno == kSyscallsRequiredForUnsafeTraps[i]) { - return true; - } - } - return false; -} - -} // namespace bpf_dsl -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/policy_compiler.h b/sandbox/linux/bpf_dsl/policy_compiler.h deleted file mode 100644 index 48b1d780d9..0000000000 --- a/sandbox/linux/bpf_dsl/policy_compiler.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2012 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_LINUX_BPF_DSL_POLICY_COMPILER_H_ -#define SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <vector> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/linux/bpf_dsl/trap_registry.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -namespace bpf_dsl { -class Policy; - -// PolicyCompiler implements the bpf_dsl compiler, allowing users to -// transform bpf_dsl policies into BPF programs to be executed by the -// Linux kernel. -class SANDBOX_EXPORT PolicyCompiler { - public: - using PanicFunc = bpf_dsl::ResultExpr (*)(const char* error); - - PolicyCompiler(const Policy* policy, TrapRegistry* registry); - ~PolicyCompiler(); - - // Compile registers any trap handlers needed by the policy and - // compiles the policy to a BPF program, which it returns. - CodeGen::Program Compile(); - - // DangerousSetEscapePC sets the "escape PC" that is allowed to issue any - // system calls, regardless of policy. - void DangerousSetEscapePC(uint64_t escapepc); - - // SetPanicFunc sets the callback function used for handling faulty - // system call conditions. The default behavior is to immediately kill - // the process. - // TODO(mdempsky): Move this into Policy? - void SetPanicFunc(PanicFunc panic_func); - - // UnsafeTraps require some syscalls to always be allowed. - // This helper function returns true for these calls. - static bool IsRequiredForUnsafeTrap(int sysno); - - // Functions below are meant for use within bpf_dsl itself. - - // Return returns a CodeGen::Node that returns the specified seccomp - // return value. - CodeGen::Node Return(uint32_t ret); - - // Trap returns a CodeGen::Node to indicate the system call should - // instead invoke a trap handler. - CodeGen::Node Trap(TrapRegistry::TrapFnc fnc, const void* aux, bool safe); - - // MaskedEqual returns a CodeGen::Node that represents a conditional branch. - // Argument "argno" (1..6) will be bitwise-AND'd with "mask" and compared - // to "value"; if equal, then "passed" will be executed, otherwise "failed". - // If "width" is 4, the argument must in the range of 0x0..(1u << 32 - 1) - // If it is outside this range, the sandbox treats the system call just - // the same as any other ABI violation (i.e., it panics). - CodeGen::Node MaskedEqual(int argno, - size_t width, - uint64_t mask, - uint64_t value, - CodeGen::Node passed, - CodeGen::Node failed); - - private: - struct Range; - typedef std::vector<Range> Ranges; - - // Used by MaskedEqualHalf to track which half of the argument it's - // emitting instructions for. - enum class ArgHalf { - LOWER, - UPPER, - }; - - // Compile the configured policy into a complete instruction sequence. - CodeGen::Node AssemblePolicy(); - - // Return an instruction sequence that checks the - // arch_seccomp_data's "arch" field is valid, and then passes - // control to |passed| if so. - CodeGen::Node CheckArch(CodeGen::Node passed); - - // If |has_unsafe_traps_| is true, returns an instruction sequence - // that allows all system calls from |escapepc_|, and otherwise - // passes control to |rest|. Otherwise, simply returns |rest|. - CodeGen::Node MaybeAddEscapeHatch(CodeGen::Node rest); - - // Return an instruction sequence that loads and checks the system - // call number, performs a binary search, and then dispatches to an - // appropriate instruction sequence compiled from the current - // policy. - CodeGen::Node DispatchSyscall(); - - // Return an instruction sequence that checks the system call number - // (expected to be loaded in register A) and if valid, passes - // control to |passed| (with register A still valid). - CodeGen::Node CheckSyscallNumber(CodeGen::Node passed); - - // Finds all the ranges of system calls that need to be handled. Ranges are - // sorted in ascending order of system call numbers. There are no gaps in the - // ranges. System calls with identical CodeGen::Nodes are coalesced into a - // single - // range. - void FindRanges(Ranges* ranges); - - // Returns a BPF program snippet that implements a jump table for the - // given range of system call numbers. This function runs recursively. - CodeGen::Node AssembleJumpTable(Ranges::const_iterator start, - Ranges::const_iterator stop); - - // CompileResult compiles an individual result expression into a - // CodeGen node. - CodeGen::Node CompileResult(const ResultExpr& res); - - // Returns a BPF program that evaluates half of a conditional expression; - // it should only ever be called from CondExpression(). - CodeGen::Node MaskedEqualHalf(int argno, - size_t width, - uint64_t full_mask, - uint64_t full_value, - ArgHalf half, - CodeGen::Node passed, - CodeGen::Node failed); - - // Returns the fatal CodeGen::Node that is used to indicate that somebody - // attempted to pass a 64bit value in a 32bit system call argument. - CodeGen::Node Unexpected64bitArgument(); - - const Policy* policy_; - TrapRegistry* registry_; - uint64_t escapepc_; - PanicFunc panic_func_; - - CodeGen gen_; - bool has_unsafe_traps_; - - DISALLOW_COPY_AND_ASSIGN(PolicyCompiler); -}; - -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ diff --git a/sandbox/linux/bpf_dsl/seccomp_macros.h b/sandbox/linux/bpf_dsl/seccomp_macros.h deleted file mode 100644 index af70f21cd7..0000000000 --- a/sandbox/linux/bpf_dsl/seccomp_macros.h +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright (c) 2012 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_LINUX_BPF_DSL_SECCOMP_MACROS_H_ -#define SANDBOX_LINUX_BPF_DSL_SECCOMP_MACROS_H_ - -#include <sys/types.h> // For __BIONIC__. -// Old Bionic versions do not have sys/user.h. The if can be removed once we no -// longer need to support these old Bionic versions. -// All x86_64 builds use a new enough bionic to have sys/user.h. -#if !defined(__BIONIC__) || defined(__x86_64__) -#if !defined(__native_client_nonsfi__) -#include <sys/user.h> -#endif -#if defined(__mips__) -// sys/user.h in eglibc misses size_t definition -#include <stddef.h> -#endif -#endif - -#include "sandbox/linux/system_headers/linux_seccomp.h" // For AUDIT_ARCH_* - -// Impose some reasonable maximum BPF program size. Realistically, the -// kernel probably has much lower limits. But by limiting to less than -// 30 bits, we can ease requirements on some of our data types. -#define SECCOMP_MAX_PROGRAM_SIZE (1<<30) - -#if defined(__i386__) -#define SECCOMP_ARCH AUDIT_ARCH_I386 - -#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) -#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) -#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) -#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) -#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) -#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) -#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) -#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) -#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) -#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) -#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) -#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) -#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 4) -#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 0) -#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 4) -#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 0) - - -#if defined(__BIONIC__) || defined(__native_client_nonsfi__) -// Old Bionic versions and PNaCl toolchain don't have sys/user.h, so we just -// define regs_struct directly. This can be removed once we no longer need to -// support these old Bionic versions and PNaCl toolchain. -struct regs_struct { - long int ebx; - long int ecx; - long int edx; - long int esi; - long int edi; - long int ebp; - long int eax; - long int xds; - long int xes; - long int xfs; - long int xgs; - long int orig_eax; - long int eip; - long int xcs; - long int eflags; - long int esp; - long int xss; -}; -#else -typedef user_regs_struct regs_struct; -#endif - -#define SECCOMP_PT_RESULT(_regs) (_regs).eax -#define SECCOMP_PT_SYSCALL(_regs) (_regs).orig_eax -#define SECCOMP_PT_IP(_regs) (_regs).eip -#define SECCOMP_PT_PARM1(_regs) (_regs).ebx -#define SECCOMP_PT_PARM2(_regs) (_regs).ecx -#define SECCOMP_PT_PARM3(_regs) (_regs).edx -#define SECCOMP_PT_PARM4(_regs) (_regs).esi -#define SECCOMP_PT_PARM5(_regs) (_regs).edi -#define SECCOMP_PT_PARM6(_regs) (_regs).ebp - -#elif defined(__x86_64__) -#define SECCOMP_ARCH AUDIT_ARCH_X86_64 - -#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) -#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) -#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) -#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) -#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) -#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) -#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) -#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) -#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) -#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) -#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) -#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) -#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 4) -#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 0) -#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 4) -#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 0) - -typedef user_regs_struct regs_struct; -#define SECCOMP_PT_RESULT(_regs) (_regs).rax -#define SECCOMP_PT_SYSCALL(_regs) (_regs).orig_rax -#define SECCOMP_PT_IP(_regs) (_regs).rip -#define SECCOMP_PT_PARM1(_regs) (_regs).rdi -#define SECCOMP_PT_PARM2(_regs) (_regs).rsi -#define SECCOMP_PT_PARM3(_regs) (_regs).rdx -#define SECCOMP_PT_PARM4(_regs) (_regs).r10 -#define SECCOMP_PT_PARM5(_regs) (_regs).r8 -#define SECCOMP_PT_PARM6(_regs) (_regs).r9 - -#elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) -#define SECCOMP_ARCH AUDIT_ARCH_ARM - -// ARM sigcontext_t is different from i386/x86_64. -// See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. -#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) -// ARM EABI syscall convention. -#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) -#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) -#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) -#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) -#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) -#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) -#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) -#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) -#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) -#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) -#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) -#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 4) -#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 0) -#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 4) -#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 0) - -#if defined(__BIONIC__) || defined(__native_client_nonsfi__) -// Old Bionic versions and PNaCl toolchain don't have sys/user.h, so we just -// define regs_struct directly. This can be removed once we no longer need to -// support these old Bionic versions and PNaCl toolchain. -struct regs_struct { - unsigned long uregs[18]; -}; -#else -typedef user_regs regs_struct; -#endif - -#define REG_cpsr uregs[16] -#define REG_pc uregs[15] -#define REG_lr uregs[14] -#define REG_sp uregs[13] -#define REG_ip uregs[12] -#define REG_fp uregs[11] -#define REG_r10 uregs[10] -#define REG_r9 uregs[9] -#define REG_r8 uregs[8] -#define REG_r7 uregs[7] -#define REG_r6 uregs[6] -#define REG_r5 uregs[5] -#define REG_r4 uregs[4] -#define REG_r3 uregs[3] -#define REG_r2 uregs[2] -#define REG_r1 uregs[1] -#define REG_r0 uregs[0] -#define REG_ORIG_r0 uregs[17] - -#define SECCOMP_PT_RESULT(_regs) (_regs).REG_r0 -#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_r7 -#define SECCOMP_PT_IP(_regs) (_regs).REG_pc -#define SECCOMP_PT_PARM1(_regs) (_regs).REG_r0 -#define SECCOMP_PT_PARM2(_regs) (_regs).REG_r1 -#define SECCOMP_PT_PARM3(_regs) (_regs).REG_r2 -#define SECCOMP_PT_PARM4(_regs) (_regs).REG_r3 -#define SECCOMP_PT_PARM5(_regs) (_regs).REG_r4 -#define SECCOMP_PT_PARM6(_regs) (_regs).REG_r5 - -#elif defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) -#define SECCOMP_ARCH AUDIT_ARCH_MIPSEL -#define SYSCALL_EIGHT_ARGS -// MIPS sigcontext_t is different from i386/x86_64 and ARM. -// See </arch/mips/include/uapi/asm/sigcontext.h> in the Linux kernel. -#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[_reg]) -// Based on MIPS o32 ABI syscall convention. -// On MIPS, when indirect syscall is being made (syscall(__NR_foo)), -// real identificator (__NR_foo) is not in v0, but in a0 -#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 2) -#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 2) -#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc -#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 4) -#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 5) -#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 6) -#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 7) -// Only the first 4 arguments of syscall are in registers. -// The rest are on the stack. -#define SECCOMP_STACKPARM(_ctx, n) (((long *)SECCOMP_REG(_ctx, 29))[(n)]) -#define SECCOMP_PARM5(_ctx) SECCOMP_STACKPARM(_ctx, 4) -#define SECCOMP_PARM6(_ctx) SECCOMP_STACKPARM(_ctx, 5) -#define SECCOMP_PARM7(_ctx) SECCOMP_STACKPARM(_ctx, 6) -#define SECCOMP_PARM8(_ctx) SECCOMP_STACKPARM(_ctx, 7) -#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) -#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) -#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 4) -#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ - instruction_pointer) + 0) -#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 4) -#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ - 8*(nr) + 0) - -// On Mips we don't have structures like user_regs or user_regs_struct in -// sys/user.h that we could use, so we just define regs_struct directly. -struct regs_struct { - unsigned long long regs[32]; -}; - -#define REG_a3 regs[7] -#define REG_a2 regs[6] -#define REG_a1 regs[5] -#define REG_a0 regs[4] -#define REG_v1 regs[3] -#define REG_v0 regs[2] - -#define SECCOMP_PT_RESULT(_regs) (_regs).REG_v0 -#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_v0 -#define SECCOMP_PT_PARM1(_regs) (_regs).REG_a0 -#define SECCOMP_PT_PARM2(_regs) (_regs).REG_a1 -#define SECCOMP_PT_PARM3(_regs) (_regs).REG_a2 -#define SECCOMP_PT_PARM4(_regs) (_regs).REG_a3 - -#elif defined(__aarch64__) -struct regs_struct { - unsigned long long regs[31]; - unsigned long long sp; - unsigned long long pc; - unsigned long long pstate; -}; - -#define SECCOMP_ARCH AUDIT_ARCH_AARCH64 - -#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.regs[_reg]) - -#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 0) -#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 8) -#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc -#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 0) -#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 1) -#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 2) -#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 3) -#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, 4) -#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, 5) - -#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) -#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) -#define SECCOMP_IP_MSB_IDX \ - (offsetof(struct arch_seccomp_data, instruction_pointer) + 4) -#define SECCOMP_IP_LSB_IDX \ - (offsetof(struct arch_seccomp_data, instruction_pointer) + 0) -#define SECCOMP_ARG_MSB_IDX(nr) \ - (offsetof(struct arch_seccomp_data, args) + 8 * (nr) + 4) -#define SECCOMP_ARG_LSB_IDX(nr) \ - (offsetof(struct arch_seccomp_data, args) + 8 * (nr) + 0) - -#define SECCOMP_PT_RESULT(_regs) (_regs).regs[0] -#define SECCOMP_PT_SYSCALL(_regs) (_regs).regs[8] -#define SECCOMP_PT_IP(_regs) (_regs).pc -#define SECCOMP_PT_PARM1(_regs) (_regs).regs[0] -#define SECCOMP_PT_PARM2(_regs) (_regs).regs[1] -#define SECCOMP_PT_PARM3(_regs) (_regs).regs[2] -#define SECCOMP_PT_PARM4(_regs) (_regs).regs[3] -#define SECCOMP_PT_PARM5(_regs) (_regs).regs[4] -#define SECCOMP_PT_PARM6(_regs) (_regs).regs[5] -#else -#error Unsupported target platform - -#endif - -#endif // SANDBOX_LINUX_BPF_DSL_SECCOMP_MACROS_H_ diff --git a/sandbox/linux/bpf_dsl/syscall_set.cc b/sandbox/linux/bpf_dsl/syscall_set.cc deleted file mode 100644 index 3d61fa31fd..0000000000 --- a/sandbox/linux/bpf_dsl/syscall_set.cc +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) 2012 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/linux/bpf_dsl/syscall_set.h" - -#include <stdint.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/linux_syscall_ranges.h" - -namespace sandbox { - -namespace { - -#if defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) -// This is true for Mips O32 ABI. -static_assert(MIN_SYSCALL == __NR_Linux, "min syscall number should be 4000"); -#else -// This true for supported architectures (Intel and ARM EABI). -static_assert(MIN_SYSCALL == 0u, - "min syscall should always be zero"); -#endif - -// SyscallRange represents an inclusive range of system call numbers. -struct SyscallRange { - uint32_t first; - uint32_t last; -}; - -const SyscallRange kValidSyscallRanges[] = { - // First we iterate up to MAX_PUBLIC_SYSCALL, which is equal to MAX_SYSCALL - // on Intel architectures, but leaves room for private syscalls on ARM. - {MIN_SYSCALL, MAX_PUBLIC_SYSCALL}, -#if defined(__arm__) - // ARM EABI includes "ARM private" system calls starting at - // MIN_PRIVATE_SYSCALL, and a "ghost syscall private to the kernel" at - // MIN_GHOST_SYSCALL. - {MIN_PRIVATE_SYSCALL, MAX_PRIVATE_SYSCALL}, - {MIN_GHOST_SYSCALL, MAX_SYSCALL}, -#endif -}; - -} // namespace - -SyscallSet::Iterator SyscallSet::begin() const { - return Iterator(set_, false); -} - -SyscallSet::Iterator SyscallSet::end() const { - return Iterator(set_, true); -} - -bool SyscallSet::IsValid(uint32_t num) { - for (const SyscallRange& range : kValidSyscallRanges) { - if (num >= range.first && num <= range.last) { - return true; - } - } - return false; -} - -bool operator==(const SyscallSet& lhs, const SyscallSet& rhs) { - return (lhs.set_ == rhs.set_); -} - -SyscallSet::Iterator::Iterator(Set set, bool done) - : set_(set), done_(done), num_(0) { - // If the set doesn't contain 0, we need to skip to the next element. - if (!done && set_ == (IsValid(num_) ? Set::INVALID_ONLY : Set::VALID_ONLY)) { - ++*this; - } -} - -uint32_t SyscallSet::Iterator::operator*() const { - DCHECK(!done_); - return num_; -} - -SyscallSet::Iterator& SyscallSet::Iterator::operator++() { - DCHECK(!done_); - - num_ = NextSyscall(); - if (num_ == 0) { - done_ = true; - } - - return *this; -} - -// NextSyscall returns the next system call in the iterated system -// call set after |num_|, or 0 if no such system call exists. -uint32_t SyscallSet::Iterator::NextSyscall() const { - const bool want_valid = (set_ != Set::INVALID_ONLY); - const bool want_invalid = (set_ != Set::VALID_ONLY); - - for (const SyscallRange& range : kValidSyscallRanges) { - if (want_invalid && range.first > 0 && num_ < range.first - 1) { - // Even when iterating invalid syscalls, we only include the end points; - // so skip directly to just before the next (valid) range. - return range.first - 1; - } - if (want_valid && num_ < range.first) { - return range.first; - } - if (want_valid && num_ < range.last) { - return num_ + 1; - } - if (want_invalid && num_ <= range.last) { - return range.last + 1; - } - } - - if (want_invalid) { - // BPF programs only ever operate on unsigned quantities. So, - // that's how we iterate; we return values from - // 0..0xFFFFFFFFu. But there are places, where the kernel might - // interpret system call numbers as signed quantities, so the - // boundaries between signed and unsigned values are potential - // problem cases. We want to explicitly return these values from - // our iterator. - if (num_ < 0x7FFFFFFFu) - return 0x7FFFFFFFu; - if (num_ < 0x80000000u) - return 0x80000000u; - - if (num_ < 0xFFFFFFFFu) - return 0xFFFFFFFFu; - } - - return 0; -} - -bool operator==(const SyscallSet::Iterator& lhs, - const SyscallSet::Iterator& rhs) { - DCHECK(lhs.set_ == rhs.set_); - return (lhs.done_ == rhs.done_) && (lhs.num_ == rhs.num_); -} - -bool operator!=(const SyscallSet::Iterator& lhs, - const SyscallSet::Iterator& rhs) { - return !(lhs == rhs); -} - -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/syscall_set.h b/sandbox/linux/bpf_dsl/syscall_set.h deleted file mode 100644 index b9f076d932..0000000000 --- a/sandbox/linux/bpf_dsl/syscall_set.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2012 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_LINUX_BPF_DSL_SYSCALL_SET_H__ -#define SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ - -#include <stdint.h> - -#include <iterator> - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// Iterates over the entire system call range from 0..0xFFFFFFFFu. This -// iterator is aware of how system calls look like and will skip quickly -// over ranges that can't contain system calls. It iterates more slowly -// whenever it reaches a range that is potentially problematic, returning -// the last invalid value before a valid range of system calls, and the -// first invalid value after a valid range of syscalls. It iterates over -// individual values whenever it is in the normal range for system calls -// (typically MIN_SYSCALL..MAX_SYSCALL). -// -// Example usage: -// for (uint32_t sysnum : SyscallSet::All()) { -// // Do something with sysnum. -// } -class SANDBOX_EXPORT SyscallSet { - public: - class Iterator; - - SyscallSet(const SyscallSet& ss) : set_(ss.set_) {} - ~SyscallSet() {} - - Iterator begin() const; - Iterator end() const; - - // All returns a SyscallSet that contains both valid and invalid - // system call numbers. - static SyscallSet All() { return SyscallSet(Set::ALL); } - - // ValidOnly returns a SyscallSet that contains only valid system - // call numbers. - static SyscallSet ValidOnly() { return SyscallSet(Set::VALID_ONLY); } - - // InvalidOnly returns a SyscallSet that contains only invalid - // system call numbers, but still omits numbers in the middle of a - // range of invalid system call numbers. - static SyscallSet InvalidOnly() { return SyscallSet(Set::INVALID_ONLY); } - - // IsValid returns whether |num| specifies a valid system call - // number. - static bool IsValid(uint32_t num); - - private: - enum class Set { ALL, VALID_ONLY, INVALID_ONLY }; - - explicit SyscallSet(Set set) : set_(set) {} - - Set set_; - - friend bool operator==(const SyscallSet&, const SyscallSet&); - DISALLOW_ASSIGN(SyscallSet); -}; - -SANDBOX_EXPORT bool operator==(const SyscallSet& lhs, const SyscallSet& rhs); - -// Iterator provides C++ input iterator semantics for traversing a -// SyscallSet. -class SyscallSet::Iterator - : public std::iterator<std::input_iterator_tag, uint32_t> { - public: - Iterator(const Iterator& it) - : set_(it.set_), done_(it.done_), num_(it.num_) {} - ~Iterator() {} - - uint32_t operator*() const; - Iterator& operator++(); - - private: - Iterator(Set set, bool done); - - uint32_t NextSyscall() const; - - Set set_; - bool done_; - uint32_t num_; - - friend SyscallSet; - friend bool operator==(const Iterator&, const Iterator&); - DISALLOW_ASSIGN(Iterator); -}; - -SANDBOX_EXPORT bool operator==(const SyscallSet::Iterator& lhs, - const SyscallSet::Iterator& rhs); -SANDBOX_EXPORT bool operator!=(const SyscallSet::Iterator& lhs, - const SyscallSet::Iterator& rhs); - -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ diff --git a/sandbox/linux/bpf_dsl/syscall_set_unittest.cc b/sandbox/linux/bpf_dsl/syscall_set_unittest.cc deleted file mode 100644 index 5069e8e431..0000000000 --- a/sandbox/linux/bpf_dsl/syscall_set_unittest.cc +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2012 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/linux/bpf_dsl/syscall_set.h" - -#include <stddef.h> -#include <stdint.h> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/linux_syscall_ranges.h" -#include "sandbox/linux/tests/unit_tests.h" - -namespace sandbox { - -namespace { - -const SyscallSet kSyscallSets[] = { - SyscallSet::All(), - SyscallSet::InvalidOnly(), -}; - -SANDBOX_TEST(SyscallSet, Monotonous) { - for (const SyscallSet& set : kSyscallSets) { - uint32_t prev = 0; - bool have_prev = false; - for (uint32_t sysnum : set) { - if (have_prev) { - SANDBOX_ASSERT(sysnum > prev); - } else if (set == SyscallSet::All()) { - // The iterator should start at 0. - SANDBOX_ASSERT(sysnum == 0); - } - - prev = sysnum; - have_prev = true; - } - - // The iterator should always return 0xFFFFFFFFu as the last value. - SANDBOX_ASSERT(have_prev); - SANDBOX_ASSERT(prev == 0xFFFFFFFFu); - } -} - -// AssertRange checks that SyscallIterator produces all system call -// numbers in the inclusive range [min, max]. -void AssertRange(uint32_t min, uint32_t max) { - SANDBOX_ASSERT(min < max); - uint32_t prev = min - 1; - for (uint32_t sysnum : SyscallSet::All()) { - if (sysnum >= min && sysnum <= max) { - SANDBOX_ASSERT(prev == sysnum - 1); - prev = sysnum; - } - } - SANDBOX_ASSERT(prev == max); -} - -SANDBOX_TEST(SyscallSet, ValidSyscallRanges) { - AssertRange(MIN_SYSCALL, MAX_PUBLIC_SYSCALL); -#if defined(__arm__) - AssertRange(MIN_PRIVATE_SYSCALL, MAX_PRIVATE_SYSCALL); - AssertRange(MIN_GHOST_SYSCALL, MAX_SYSCALL); -#endif -} - -SANDBOX_TEST(SyscallSet, InvalidSyscalls) { - static const uint32_t kExpected[] = { -#if defined(__mips__) - 0, - MIN_SYSCALL - 1, -#endif - MAX_PUBLIC_SYSCALL + 1, -#if defined(__arm__) - MIN_PRIVATE_SYSCALL - 1, - MAX_PRIVATE_SYSCALL + 1, - MIN_GHOST_SYSCALL - 1, - MAX_SYSCALL + 1, -#endif - 0x7FFFFFFFu, - 0x80000000u, - 0xFFFFFFFFu, - }; - - for (const SyscallSet& set : kSyscallSets) { - size_t i = 0; - for (uint32_t sysnum : set) { - if (!SyscallSet::IsValid(sysnum)) { - SANDBOX_ASSERT(i < arraysize(kExpected)); - SANDBOX_ASSERT(kExpected[i] == sysnum); - ++i; - } - } - SANDBOX_ASSERT(i == arraysize(kExpected)); - } -} - -SANDBOX_TEST(SyscallSet, ValidOnlyIsOnlyValid) { - for (uint32_t sysnum : SyscallSet::ValidOnly()) { - SANDBOX_ASSERT(SyscallSet::IsValid(sysnum)); - } -} - -SANDBOX_TEST(SyscallSet, InvalidOnlyIsOnlyInvalid) { - for (uint32_t sysnum : SyscallSet::InvalidOnly()) { - SANDBOX_ASSERT(!SyscallSet::IsValid(sysnum)); - } -} - -SANDBOX_TEST(SyscallSet, AllIsValidOnlyPlusInvalidOnly) { - std::vector<uint32_t> merged; - const SyscallSet valid_only = SyscallSet::ValidOnly(); - const SyscallSet invalid_only = SyscallSet::InvalidOnly(); - std::merge(valid_only.begin(), - valid_only.end(), - invalid_only.begin(), - invalid_only.end(), - std::back_inserter(merged)); - - const SyscallSet all = SyscallSet::All(); - SANDBOX_ASSERT(merged == std::vector<uint32_t>(all.begin(), all.end())); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/trap_registry.h b/sandbox/linux/bpf_dsl/trap_registry.h deleted file mode 100644 index 0a5d2f14cc..0000000000 --- a/sandbox/linux/bpf_dsl/trap_registry.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2014 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_LINUX_BPF_DSL_TRAP_REGISTRY_H_ -#define SANDBOX_LINUX_BPF_DSL_TRAP_REGISTRY_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// This must match the kernel's seccomp_data structure. -struct arch_seccomp_data { - int nr; - uint32_t arch; - uint64_t instruction_pointer; - uint64_t args[6]; -}; - -namespace bpf_dsl { - -// TrapRegistry provides an interface for registering "trap handlers" -// by associating them with non-zero 16-bit trap IDs. Trap IDs should -// remain valid for the lifetime of the trap registry. -class SANDBOX_EXPORT TrapRegistry { - public: - // TrapFnc is a pointer to a function that fulfills the trap handler - // function signature. - // - // Trap handlers follow the calling convention of native system - // calls; e.g., to report an error, they return an exit code in the - // range -1..-4096 instead of directly modifying errno. However, - // modifying errno is harmless, as the original value will be - // restored afterwards. - // - // Trap handlers are executed from signal context and possibly an - // async-signal context, so they must be async-signal safe: - // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html - typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void* aux); - - // Add registers the specified trap handler tuple and returns a - // non-zero trap ID that uniquely identifies the tuple for the life - // time of the trap registry. If the same tuple is registered - // multiple times, the same value will be returned each time. - virtual uint16_t Add(TrapFnc fnc, const void* aux, bool safe) = 0; - - // EnableUnsafeTraps tries to enable unsafe traps and returns - // whether it was successful. This is a one-way operation. - // - // CAUTION: Enabling unsafe traps effectively defeats the security - // guarantees provided by the sandbox policy. TrapRegistry - // implementations should ensure unsafe traps are only enabled - // during testing. - virtual bool EnableUnsafeTraps() = 0; - - protected: - TrapRegistry() {} - - // TrapRegistry's destructor is intentionally non-virtual so that - // implementations can omit their destructor. Instead we protect against - // misuse by marking it protected. - ~TrapRegistry() {} - - DISALLOW_COPY_AND_ASSIGN(TrapRegistry); -}; - -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_TRAP_REGISTRY_H_ diff --git a/sandbox/linux/bpf_dsl/verifier.cc b/sandbox/linux/bpf_dsl/verifier.cc deleted file mode 100644 index b5383e5d04..0000000000 --- a/sandbox/linux/bpf_dsl/verifier.cc +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2012 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/linux/bpf_dsl/verifier.h" - -#include <stdint.h> -#include <string.h> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/bpf_dsl/trap_registry.h" -#include "sandbox/linux/system_headers/linux_filter.h" -#include "sandbox/linux/system_headers/linux_seccomp.h" - -namespace sandbox { -namespace bpf_dsl { - -namespace { - -struct State { - State(const std::vector<struct sock_filter>& p, - const struct arch_seccomp_data& d) - : program(p), data(d), ip(0), accumulator(0), acc_is_valid(false) {} - const std::vector<struct sock_filter>& program; - const struct arch_seccomp_data& data; - unsigned int ip; - uint32_t accumulator; - bool acc_is_valid; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(State); -}; - -void Ld(State* state, const struct sock_filter& insn, const char** err) { - if (BPF_SIZE(insn.code) != BPF_W || BPF_MODE(insn.code) != BPF_ABS || - insn.jt != 0 || insn.jf != 0) { - *err = "Invalid BPF_LD instruction"; - return; - } - if (insn.k < sizeof(struct arch_seccomp_data) && (insn.k & 3) == 0) { - // We only allow loading of properly aligned 32bit quantities. - memcpy(&state->accumulator, - reinterpret_cast<const char*>(&state->data) + insn.k, 4); - } else { - *err = "Invalid operand in BPF_LD instruction"; - return; - } - state->acc_is_valid = true; - return; -} - -void Jmp(State* state, const struct sock_filter& insn, const char** err) { - if (BPF_OP(insn.code) == BPF_JA) { - if (state->ip + insn.k + 1 >= state->program.size() || - state->ip + insn.k + 1 <= state->ip) { - compilation_failure: - *err = "Invalid BPF_JMP instruction"; - return; - } - state->ip += insn.k; - } else { - if (BPF_SRC(insn.code) != BPF_K || !state->acc_is_valid || - state->ip + insn.jt + 1 >= state->program.size() || - state->ip + insn.jf + 1 >= state->program.size()) { - goto compilation_failure; - } - switch (BPF_OP(insn.code)) { - case BPF_JEQ: - if (state->accumulator == insn.k) { - state->ip += insn.jt; - } else { - state->ip += insn.jf; - } - break; - case BPF_JGT: - if (state->accumulator > insn.k) { - state->ip += insn.jt; - } else { - state->ip += insn.jf; - } - break; - case BPF_JGE: - if (state->accumulator >= insn.k) { - state->ip += insn.jt; - } else { - state->ip += insn.jf; - } - break; - case BPF_JSET: - if (state->accumulator & insn.k) { - state->ip += insn.jt; - } else { - state->ip += insn.jf; - } - break; - default: - goto compilation_failure; - } - } -} - -uint32_t Ret(State*, const struct sock_filter& insn, const char** err) { - if (BPF_SRC(insn.code) != BPF_K) { - *err = "Invalid BPF_RET instruction"; - return 0; - } - return insn.k; -} - -void Alu(State* state, const struct sock_filter& insn, const char** err) { - if (BPF_OP(insn.code) == BPF_NEG) { - state->accumulator = -state->accumulator; - return; - } else { - if (BPF_SRC(insn.code) != BPF_K) { - *err = "Unexpected source operand in arithmetic operation"; - return; - } - switch (BPF_OP(insn.code)) { - case BPF_ADD: - state->accumulator += insn.k; - break; - case BPF_SUB: - state->accumulator -= insn.k; - break; - case BPF_MUL: - state->accumulator *= insn.k; - break; - case BPF_DIV: - if (!insn.k) { - *err = "Illegal division by zero"; - break; - } - state->accumulator /= insn.k; - break; - case BPF_MOD: - if (!insn.k) { - *err = "Illegal division by zero"; - break; - } - state->accumulator %= insn.k; - break; - case BPF_OR: - state->accumulator |= insn.k; - break; - case BPF_XOR: - state->accumulator ^= insn.k; - break; - case BPF_AND: - state->accumulator &= insn.k; - break; - case BPF_LSH: - if (insn.k > 32) { - *err = "Illegal shift operation"; - break; - } - state->accumulator <<= insn.k; - break; - case BPF_RSH: - if (insn.k > 32) { - *err = "Illegal shift operation"; - break; - } - state->accumulator >>= insn.k; - break; - default: - *err = "Invalid operator in arithmetic operation"; - break; - } - } -} - -} // namespace - -uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program, - const struct arch_seccomp_data& data, - const char** err) { - *err = NULL; - if (program.size() < 1 || program.size() >= SECCOMP_MAX_PROGRAM_SIZE) { - *err = "Invalid program length"; - return 0; - } - for (State state(program, data); !*err; ++state.ip) { - if (state.ip >= program.size()) { - *err = "Invalid instruction pointer in BPF program"; - break; - } - const struct sock_filter& insn = program[state.ip]; - switch (BPF_CLASS(insn.code)) { - case BPF_LD: - Ld(&state, insn, err); - break; - case BPF_JMP: - Jmp(&state, insn, err); - break; - case BPF_RET: { - uint32_t r = Ret(&state, insn, err); - switch (r & SECCOMP_RET_ACTION) { - case SECCOMP_RET_ALLOW: - case SECCOMP_RET_ERRNO: - case SECCOMP_RET_KILL: - case SECCOMP_RET_TRACE: - case SECCOMP_RET_TRAP: - break; - case SECCOMP_RET_INVALID: // Should never show up in BPF program - default: - *err = "Unexpected return code found in BPF program"; - return 0; - } - return r; - } - case BPF_ALU: - Alu(&state, insn, err); - break; - default: - *err = "Unexpected instruction in BPF program"; - break; - } - } - return 0; -} - -} // namespace bpf_dsl -} // namespace sandbox diff --git a/sandbox/linux/bpf_dsl/verifier.h b/sandbox/linux/bpf_dsl/verifier.h deleted file mode 100644 index 9b25ab1d71..0000000000 --- a/sandbox/linux/bpf_dsl/verifier.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2012 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_LINUX_BPF_DSL_VERIFIER_H__ -#define SANDBOX_LINUX_BPF_DSL_VERIFIER_H__ - -#include <stdint.h> - -#include <vector> - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -struct sock_filter; - -namespace sandbox { -struct arch_seccomp_data; - -namespace bpf_dsl { - -// TODO(mdempsky): This class doesn't perform any verification any more, so it -// deserves a new name. -class SANDBOX_EXPORT Verifier { - public: - // Evaluate a given BPF program for a particular set of system call - // parameters. If evaluation failed for any reason, "err" will be set to - // a non-NULL error string. Otherwise, the BPF program's result will be - // returned by the function and "err" is NULL. - // We do not actually implement the full BPF state machine, but only the - // parts that can actually be generated by our BPF compiler. If this code - // is used for purposes other than verifying the output of the sandbox's - // BPF compiler, we might have to extend this BPF interpreter. - static uint32_t EvaluateBPF(const std::vector<struct sock_filter>& program, - const struct arch_seccomp_data& data, - const char** err); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(Verifier); -}; - -} // namespace bpf_dsl -} // namespace sandbox - -#endif // SANDBOX_LINUX_BPF_DSL_VERIFIER_H__ diff --git a/sandbox/linux/integration_tests/DEPS b/sandbox/linux/integration_tests/DEPS deleted file mode 100644 index d50729cea3..0000000000 --- a/sandbox/linux/integration_tests/DEPS +++ /dev/null @@ -1,7 +0,0 @@ -include_rules = [ - "+sandbox/linux/bpf_dsl", - "+sandbox/linux/seccomp-bpf", - "+sandbox/linux/services", - "+sandbox/linux/syscall_broker", - "+sandbox/linux/system_headers", -] diff --git a/sandbox/linux/seccomp-bpf-helpers/DEPS b/sandbox/linux/seccomp-bpf-helpers/DEPS deleted file mode 100644 index 4419fd1da3..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/DEPS +++ /dev/null @@ -1,7 +0,0 @@ -include_rules = [ - "+sandbox/linux/bpf_dsl", - "+sandbox/linux/seccomp-bpf", - "+sandbox/linux/services", - "+sandbox/linux/system_headers", - "+third_party/lss/linux_syscall_support.h", -] diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc deleted file mode 100644 index 88a932607c..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright (c) 2013 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/linux/seccomp-bpf-helpers/baseline_policy.h" - -#include <errno.h> -#include <sys/mman.h> -#include <sys/socket.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/logging.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" -#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" -#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -#if !defined(SO_PEEK_OFF) -#define SO_PEEK_OFF 42 -#endif - -// Changing this implementation will have an effect on *all* policies. -// Currently this means: Renderer/Worker, GPU, Flash and NaCl. - -using sandbox::bpf_dsl::Allow; -using sandbox::bpf_dsl::Arg; -using sandbox::bpf_dsl::Error; -using sandbox::bpf_dsl::If; -using sandbox::bpf_dsl::ResultExpr; - -namespace sandbox { - -namespace { - -bool IsBaselinePolicyAllowed(int sysno) { - return SyscallSets::IsAllowedAddressSpaceAccess(sysno) || - SyscallSets::IsAllowedBasicScheduler(sysno) || - SyscallSets::IsAllowedEpoll(sysno) || - SyscallSets::IsAllowedFileSystemAccessViaFd(sysno) || - SyscallSets::IsAllowedFutex(sysno) || - SyscallSets::IsAllowedGeneralIo(sysno) || - SyscallSets::IsAllowedGetOrModifySocket(sysno) || - SyscallSets::IsAllowedGettime(sysno) || - SyscallSets::IsAllowedProcessStartOrDeath(sysno) || - SyscallSets::IsAllowedSignalHandling(sysno) || - SyscallSets::IsGetSimpleId(sysno) || - SyscallSets::IsKernelInternalApi(sysno) || -#if defined(__arm__) - SyscallSets::IsArmPrivate(sysno) || -#endif -#if defined(__mips__) - SyscallSets::IsMipsPrivate(sysno) || -#endif - SyscallSets::IsAllowedOperationOnFd(sysno); -} - -// System calls that will trigger the crashing SIGSYS handler. -bool IsBaselinePolicyWatched(int sysno) { - return SyscallSets::IsAdminOperation(sysno) || - SyscallSets::IsAdvancedScheduler(sysno) || - SyscallSets::IsAdvancedTimer(sysno) || - SyscallSets::IsAsyncIo(sysno) || - SyscallSets::IsDebug(sysno) || - SyscallSets::IsEventFd(sysno) || - SyscallSets::IsExtendedAttributes(sysno) || - SyscallSets::IsFaNotify(sysno) || - SyscallSets::IsFsControl(sysno) || - SyscallSets::IsGlobalFSViewChange(sysno) || - SyscallSets::IsGlobalProcessEnvironment(sysno) || - SyscallSets::IsGlobalSystemStatus(sysno) || - SyscallSets::IsInotify(sysno) || - SyscallSets::IsKernelModule(sysno) || - SyscallSets::IsKeyManagement(sysno) || - SyscallSets::IsKill(sysno) || - SyscallSets::IsMessageQueue(sysno) || - SyscallSets::IsMisc(sysno) || -#if defined(__x86_64__) - SyscallSets::IsNetworkSocketInformation(sysno) || -#endif - SyscallSets::IsNuma(sysno) || - SyscallSets::IsPrctl(sysno) || - SyscallSets::IsProcessGroupOrSession(sysno) || -#if defined(__i386__) || defined(__mips__) - SyscallSets::IsSocketCall(sysno) || -#endif -#if defined(__arm__) - SyscallSets::IsArmPciConfig(sysno) || -#endif -#if defined(__mips__) - SyscallSets::IsMipsMisc(sysno) || -#endif - SyscallSets::IsTimer(sysno); -} - -// |fs_denied_errno| is the errno return for denied filesystem access. -ResultExpr EvaluateSyscallImpl(int fs_denied_errno, - pid_t current_pid, - int sysno) { -#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \ - defined(MEMORY_SANITIZER) - // TCGETS is required by the sanitizers on failure. - if (sysno == __NR_ioctl) { - return RestrictIoctl(); - } - - if (sysno == __NR_sched_getaffinity) { - return Allow(); - } - - // Used when RSS limiting is enabled in sanitizers. - if (sysno == __NR_getrusage) { - return RestrictGetrusage(); - } - - if (sysno == __NR_sigaltstack) { - // Required for better stack overflow detection in ASan. Disallowed in - // non-ASan builds. - return Allow(); - } -#endif // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || - // defined(MEMORY_SANITIZER) - - if (IsBaselinePolicyAllowed(sysno)) { - return Allow(); - } - -#if defined(OS_ANDROID) - // Needed for thread creation. - if (sysno == __NR_sigaltstack) - return Allow(); -#endif - - if (sysno == __NR_clock_gettime) { - return RestrictClockID(); - } - - if (sysno == __NR_clone) { - return RestrictCloneToThreadsAndEPERMFork(); - } - - if (sysno == __NR_fcntl) - return RestrictFcntlCommands(); - -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - if (sysno == __NR_fcntl64) - return RestrictFcntlCommands(); -#endif - -#if !defined(__aarch64__) - // fork() is never used as a system call (clone() is used instead), but we - // have seen it in fallback code on Android. - if (sysno == __NR_fork) { - return Error(EPERM); - } -#endif - - if (sysno == __NR_futex) - return RestrictFutex(); - - if (sysno == __NR_set_robust_list) - return Error(EPERM); - - if (sysno == __NR_getpriority || sysno ==__NR_setpriority) - return RestrictGetSetpriority(current_pid); - - if (sysno == __NR_getrandom) { - return RestrictGetRandom(); - } - - if (sysno == __NR_madvise) { - // Only allow MADV_DONTNEED and MADV_FREE. - const Arg<int> advice(2); - return If(AnyOf(advice == MADV_DONTNEED -#if defined(MADV_FREE) - // MADV_FREE was introduced in Linux 4.5 and started being - // defined in glibc 2.24. - , advice == MADV_FREE -#endif - ), Allow()).Else(Error(EPERM)); - } - -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__) - if (sysno == __NR_mmap) - return RestrictMmapFlags(); -#endif - -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - if (sysno == __NR_mmap2) - return RestrictMmapFlags(); -#endif - - if (sysno == __NR_mprotect) - return RestrictMprotectFlags(); - - if (sysno == __NR_prctl) - return RestrictPrctl(); - -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - if (sysno == __NR_socketpair) { - // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. - static_assert(AF_UNIX == PF_UNIX, - "af_unix and pf_unix should not be different"); - const Arg<int> domain(0); - return If(domain == AF_UNIX, Allow()).Else(CrashSIGSYS()); - } -#endif - - if (SyscallSets::IsKill(sysno)) { - return RestrictKillTarget(current_pid, sysno); - } - - if (SyscallSets::IsFileSystem(sysno) || - SyscallSets::IsCurrentDirectory(sysno)) { - return Error(fs_denied_errno); - } - - if (SyscallSets::IsSeccomp(sysno)) - return Error(EPERM); - - if (SyscallSets::IsAnySystemV(sysno)) { - return Error(EPERM); - } - - if (SyscallSets::IsUmask(sysno) || - SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) || - SyscallSets::IsDeniedGetOrModifySocket(sysno) || - SyscallSets::IsProcessPrivilegeChange(sysno)) { - return Error(EPERM); - } - -#if defined(__i386__) || defined(__mips__) - if (SyscallSets::IsSocketCall(sysno)) - return RestrictSocketcallCommand(); -#endif - -#if !defined(__i386__) - if (sysno == __NR_getsockopt || sysno ==__NR_setsockopt) { - // Used by Mojo EDK to catch a message pipe being sent over itself. - const Arg<int> level(1); - const Arg<int> optname(2); - return If(AllOf(level == SOL_SOCKET, optname == SO_PEEK_OFF), Allow()) - .Else(CrashSIGSYS()); - } -#endif - - if (IsBaselinePolicyWatched(sysno)) { - // Previously unseen syscalls. TODO(jln): some of these should - // be denied gracefully right away. - return CrashSIGSYS(); - } - - // In any other case crash the program with our SIGSYS handler. - return CrashSIGSYS(); -} - -} // namespace. - -// Unfortunately C++03 doesn't allow delegated constructors. -// Call other constructor when C++11 lands. -BaselinePolicy::BaselinePolicy() : BaselinePolicy(EPERM) {} - -BaselinePolicy::BaselinePolicy(int fs_denied_errno) - : fs_denied_errno_(fs_denied_errno), policy_pid_(sys_getpid()) { -} - -BaselinePolicy::~BaselinePolicy() { - // Make sure that this policy is created, used and destroyed by a single - // process. - DCHECK_EQ(sys_getpid(), policy_pid_); -} - -ResultExpr BaselinePolicy::EvaluateSyscall(int sysno) const { - // Sanity check that we're only called with valid syscall numbers. - DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); - // Make sure that this policy is used in the creating process. - if (1 == sysno) { - DCHECK_EQ(sys_getpid(), policy_pid_); - } - return EvaluateSyscallImpl(fs_denied_errno_, policy_pid_, sysno); -} - -ResultExpr BaselinePolicy::InvalidSyscall() const { - return CrashSIGSYS(); -} - -} // namespace sandbox. diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h deleted file mode 100644 index fa40e72a0f..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2013 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_LINUX_SECCOMP_BPF_HELPERS_BASELINE_POLICY_H_ -#define SANDBOX_LINUX_SECCOMP_BPF_HELPERS_BASELINE_POLICY_H_ - -#include <sys/types.h> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// This is a helper to build seccomp-bpf policies, i.e. policies for a sandbox -// that reduces the Linux kernel's attack surface. Given its nature, it doesn't -// have a clear semantics and is mostly "implementation-defined". -// -// This class implements the Policy interface with a "baseline" -// policy for use within Chromium. -// The "baseline" policy is somewhat arbitrary. All Chromium policies are an -// alteration of it, and it represents a reasonable common ground to run most -// code in a sandboxed environment. -// A baseline policy is only valid for the process for which this object was -// instantiated (so do not fork() and use it in a child). -class SANDBOX_EXPORT BaselinePolicy : public bpf_dsl::Policy { - public: - BaselinePolicy(); - // |fs_denied_errno| is the errno returned when a filesystem access system - // call is denied. - explicit BaselinePolicy(int fs_denied_errno); - ~BaselinePolicy() override; - - bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; - bpf_dsl::ResultExpr InvalidSyscall() const override; - pid_t policy_pid() const { return policy_pid_; } - - private: - int fs_denied_errno_; - - // The PID that the policy applies to (should be equal to the current pid). - pid_t policy_pid_; - - DISALLOW_COPY_AND_ASSIGN(BaselinePolicy); -}; - -} // namespace sandbox. - -#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_BASELINE_POLICY_H_ diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc deleted file mode 100644 index ca812d8a1e..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright 2014 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/linux/seccomp-bpf-helpers/baseline_policy.h" - -#include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <sched.h> -#include <signal.h> -#include <stddef.h> -#include <string.h> -#include <sys/prctl.h> -#include <sys/resource.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <time.h> -#include <unistd.h> - -#include "base/files/scoped_file.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/threading/thread.h" -#include "build/build_config.h" -#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" -#include "sandbox/linux/seccomp-bpf/bpf_tests.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/services/thread_helpers.h" -#include "sandbox/linux/system_headers/linux_futex.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" -#include "sandbox/linux/tests/test_utils.h" -#include "sandbox/linux/tests/unit_tests.h" - -#if !defined(SO_PEEK_OFF) -#define SO_PEEK_OFF 42 -#endif - -namespace sandbox { - -namespace { - -// This also tests that read(), write() and fstat() are allowed. -void TestPipeOrSocketPair(base::ScopedFD read_end, base::ScopedFD write_end) { - BPF_ASSERT_LE(0, read_end.get()); - BPF_ASSERT_LE(0, write_end.get()); - struct stat stat_buf; - int sys_ret = fstat(read_end.get(), &stat_buf); - BPF_ASSERT_EQ(0, sys_ret); - BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); - - const ssize_t kTestTransferSize = 4; - static const char kTestString[kTestTransferSize] = {'T', 'E', 'S', 'T'}; - ssize_t transfered = 0; - - transfered = - HANDLE_EINTR(write(write_end.get(), kTestString, kTestTransferSize)); - BPF_ASSERT_EQ(kTestTransferSize, transfered); - char read_buf[kTestTransferSize + 1] = {0}; - transfered = HANDLE_EINTR(read(read_end.get(), read_buf, sizeof(read_buf))); - BPF_ASSERT_EQ(kTestTransferSize, transfered); - BPF_ASSERT_EQ(0, memcmp(kTestString, read_buf, kTestTransferSize)); -} - -// Test that a few easy-to-test system calls are allowed. -BPF_TEST_C(BaselinePolicy, BaselinePolicyBasicAllowed, BaselinePolicy) { - BPF_ASSERT_EQ(0, sched_yield()); - - int pipefd[2]; - int sys_ret = pipe(pipefd); - BPF_ASSERT_EQ(0, sys_ret); - TestPipeOrSocketPair(base::ScopedFD(pipefd[0]), base::ScopedFD(pipefd[1])); - - BPF_ASSERT_LE(1, getpid()); - BPF_ASSERT_LE(0, getuid()); -} - -BPF_TEST_C(BaselinePolicy, FchmodErrno, BaselinePolicy) { - int ret = fchmod(-1, 07777); - BPF_ASSERT_EQ(-1, ret); - // Without the sandbox, this would EBADF instead. - BPF_ASSERT_EQ(EPERM, errno); -} - -BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) { - errno = 0; - pid_t pid = fork(); - const int fork_errno = errno; - TestUtils::HandlePostForkReturn(pid); - - BPF_ASSERT_EQ(-1, pid); - BPF_ASSERT_EQ(EPERM, fork_errno); -} - -pid_t ForkX86Glibc() { - static pid_t ptid; - return sys_clone(CLONE_PARENT_SETTID | SIGCHLD, nullptr, &ptid, nullptr, - nullptr); -} - -BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) { - errno = 0; - pid_t pid = ForkX86Glibc(); - const int fork_errno = errno; - TestUtils::HandlePostForkReturn(pid); - - BPF_ASSERT_EQ(-1, pid); - BPF_ASSERT_EQ(EPERM, fork_errno); -} - -pid_t ForkARMGlibc() { - static pid_t ctid; - return sys_clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, nullptr, - nullptr, &ctid, nullptr); -} - -BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) { - errno = 0; - pid_t pid = ForkARMGlibc(); - const int fork_errno = errno; - TestUtils::HandlePostForkReturn(pid); - - BPF_ASSERT_EQ(-1, pid); - BPF_ASSERT_EQ(EPERM, fork_errno); -} - -BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) { - base::Thread thread("sandbox_tests"); - BPF_ASSERT(thread.Start()); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - DisallowedCloneFlagCrashes, - DEATH_SEGV_MESSAGE(GetCloneErrorMessageContentForTests()), - BaselinePolicy) { - pid_t pid = sys_clone(CLONE_THREAD | SIGCHLD); - TestUtils::HandlePostForkReturn(pid); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - DisallowedKillCrashes, - DEATH_SEGV_MESSAGE(GetKillErrorMessageContentForTests()), - BaselinePolicy) { - BPF_ASSERT_NE(1, getpid()); - kill(1, 0); - _exit(0); -} - -BPF_TEST_C(BaselinePolicy, CanKillSelf, BaselinePolicy) { - int sys_ret = kill(getpid(), 0); - BPF_ASSERT_EQ(0, sys_ret); -} - -BPF_TEST_C(BaselinePolicy, Socketpair, BaselinePolicy) { - int sv[2]; - int sys_ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv); - BPF_ASSERT_EQ(0, sys_ret); - TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1])); - - sys_ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv); - BPF_ASSERT_EQ(0, sys_ret); - TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1])); -} - -#if !defined(GRND_NONBLOCK) -#define GRND_NONBLOCK 1 -#endif - -BPF_TEST_C(BaselinePolicy, GetRandom, BaselinePolicy) { - char buf[1]; - - // Many systems do not yet support getrandom(2) so ENOSYS is a valid result - // here. - int ret = HANDLE_EINTR(syscall(__NR_getrandom, buf, sizeof(buf), 0)); - BPF_ASSERT((ret == -1 && errno == ENOSYS) || ret == 1); - ret = HANDLE_EINTR(syscall(__NR_getrandom, buf, sizeof(buf), GRND_NONBLOCK)); - BPF_ASSERT((ret == -1 && (errno == ENOSYS || errno == EAGAIN)) || ret == 1); -} - -// Not all architectures can restrict the domain for socketpair(). -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -BPF_DEATH_TEST_C(BaselinePolicy, - SocketpairWrongDomain, - DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), - BaselinePolicy) { - int sv[2]; - ignore_result(socketpair(AF_INET, SOCK_STREAM, 0, sv)); - _exit(1); -} -#endif // defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) - -BPF_TEST_C(BaselinePolicy, EPERM_open, BaselinePolicy) { - errno = 0; - int sys_ret = open("/proc/cpuinfo", O_RDONLY); - BPF_ASSERT_EQ(-1, sys_ret); - BPF_ASSERT_EQ(EPERM, errno); -} - -BPF_TEST_C(BaselinePolicy, EPERM_access, BaselinePolicy) { - errno = 0; - int sys_ret = access("/proc/cpuinfo", R_OK); - BPF_ASSERT_EQ(-1, sys_ret); - BPF_ASSERT_EQ(EPERM, errno); -} - -BPF_TEST_C(BaselinePolicy, EPERM_getcwd, BaselinePolicy) { - errno = 0; - char buf[1024]; - char* cwd = getcwd(buf, sizeof(buf)); - BPF_ASSERT_EQ(NULL, cwd); - BPF_ASSERT_EQ(EPERM, errno); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - SIGSYS_InvalidSyscall, - DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), - BaselinePolicy) { - Syscall::InvalidCall(); -} - -// A failing test using this macro could be problematic since we perform -// system calls by passing "0" as every argument. -// The kernel could SIGSEGV the process or the system call itself could reboot -// the machine. Some thoughts have been given when hand-picking the system -// calls below to limit any potential side effects outside of the current -// process. -#define TEST_BASELINE_SIGSYS(sysno) \ - BPF_DEATH_TEST_C(BaselinePolicy, \ - SIGSYS_##sysno, \ - DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), \ - BaselinePolicy) { \ - syscall(sysno, 0, 0, 0, 0, 0, 0); \ - _exit(1); \ - } - -TEST_BASELINE_SIGSYS(__NR_acct); -TEST_BASELINE_SIGSYS(__NR_chroot); -TEST_BASELINE_SIGSYS(__NR_fanotify_init); -TEST_BASELINE_SIGSYS(__NR_fgetxattr); -TEST_BASELINE_SIGSYS(__NR_getcpu); -TEST_BASELINE_SIGSYS(__NR_getitimer); -TEST_BASELINE_SIGSYS(__NR_init_module); -TEST_BASELINE_SIGSYS(__NR_io_cancel); -TEST_BASELINE_SIGSYS(__NR_keyctl); -TEST_BASELINE_SIGSYS(__NR_mq_open); -TEST_BASELINE_SIGSYS(__NR_ptrace); -TEST_BASELINE_SIGSYS(__NR_sched_setaffinity); -TEST_BASELINE_SIGSYS(__NR_setpgid); -TEST_BASELINE_SIGSYS(__NR_swapon); -TEST_BASELINE_SIGSYS(__NR_sysinfo); -TEST_BASELINE_SIGSYS(__NR_syslog); -TEST_BASELINE_SIGSYS(__NR_timer_create); - -#if !defined(__aarch64__) -TEST_BASELINE_SIGSYS(__NR_eventfd); -TEST_BASELINE_SIGSYS(__NR_inotify_init); -TEST_BASELINE_SIGSYS(__NR_vserver); -#endif - -#if defined(LIBC_GLIBC) && !defined(OS_CHROMEOS) -BPF_TEST_C(BaselinePolicy, FutexEINVAL, BaselinePolicy) { - int ops[] = { - FUTEX_CMP_REQUEUE_PI, FUTEX_CMP_REQUEUE_PI_PRIVATE, - FUTEX_UNLOCK_PI_PRIVATE, - }; - - for (int op : ops) { - BPF_ASSERT_EQ(-1, syscall(__NR_futex, NULL, op, 0, NULL, NULL, 0)); - BPF_ASSERT_EQ(EINVAL, errno); - } -} -#else -BPF_DEATH_TEST_C(BaselinePolicy, - FutexWithRequeuePriorityInheritence, - DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()), - BaselinePolicy) { - syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI, 0, NULL, NULL, 0); - _exit(1); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - FutexWithRequeuePriorityInheritencePrivate, - DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()), - BaselinePolicy) { - syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI_PRIVATE, 0, NULL, NULL, 0); - _exit(1); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - FutexWithUnlockPIPrivate, - DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()), - BaselinePolicy) { - syscall(__NR_futex, NULL, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); - _exit(1); -} -#endif // defined(LIBC_GLIBC) && !defined(OS_CHROMEOS) - -BPF_TEST_C(BaselinePolicy, PrctlDumpable, BaselinePolicy) { - const int is_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); - BPF_ASSERT(is_dumpable == 1 || is_dumpable == 0); - const int prctl_ret = prctl(PR_SET_DUMPABLE, is_dumpable, 0, 0, 0, 0); - BPF_ASSERT_EQ(0, prctl_ret); -} - -// Workaround incomplete Android headers. -#if !defined(PR_CAPBSET_READ) -#define PR_CAPBSET_READ 23 -#endif - -BPF_DEATH_TEST_C(BaselinePolicy, - PrctlSigsys, - DEATH_SEGV_MESSAGE(GetPrctlErrorMessageContentForTests()), - BaselinePolicy) { - prctl(PR_CAPBSET_READ, 0, 0, 0, 0); - _exit(1); -} - -BPF_TEST_C(BaselinePolicy, GetOrSetPriority, BaselinePolicy) { - errno = 0; - const int original_prio = getpriority(PRIO_PROCESS, 0); - // Check errno instead of the return value since this system call can return - // -1 as a valid value. - BPF_ASSERT_EQ(0, errno); - - errno = 0; - int rc = getpriority(PRIO_PROCESS, getpid()); - BPF_ASSERT_EQ(0, errno); - - rc = getpriority(PRIO_PROCESS, getpid() + 1); - BPF_ASSERT_EQ(-1, rc); - BPF_ASSERT_EQ(EPERM, errno); - - rc = setpriority(PRIO_PROCESS, 0, original_prio); - BPF_ASSERT_EQ(0, rc); - - rc = setpriority(PRIO_PROCESS, getpid(), original_prio); - BPF_ASSERT_EQ(0, rc); - - errno = 0; - rc = setpriority(PRIO_PROCESS, getpid() + 1, original_prio); - BPF_ASSERT_EQ(-1, rc); - BPF_ASSERT_EQ(EPERM, errno); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - GetPrioritySigsys, - DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), - BaselinePolicy) { - getpriority(PRIO_USER, 0); - _exit(1); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - ClockGettimeWithDisallowedClockCrashes, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - BaselinePolicy) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); -} - -#if !defined(GRND_RANDOM) -#define GRND_RANDOM 2 -#endif - -BPF_DEATH_TEST_C(BaselinePolicy, - GetRandomOfDevRandomCrashes, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - BaselinePolicy) { - syscall(__NR_getrandom, NULL, 0, GRND_RANDOM); -} - -#if !defined(__i386__) -BPF_DEATH_TEST_C(BaselinePolicy, - GetSockOptWrongLevelSigsys, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - BaselinePolicy) { - int fds[2]; - PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); - int id; - socklen_t peek_off_size = sizeof(id); - getsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, &peek_off_size); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - GetSockOptWrongOptionSigsys, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - BaselinePolicy) { - int fds[2]; - PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); - int id; - socklen_t peek_off_size = sizeof(id); - getsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, &peek_off_size); -} - -BPF_DEATH_TEST_C(BaselinePolicy, - SetSockOptWrongLevelSigsys, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - BaselinePolicy) { - int fds[2]; - PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); - int id; - setsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, sizeof(id)); -} - - -BPF_DEATH_TEST_C(BaselinePolicy, - SetSockOptWrongOptionSigsys, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - BaselinePolicy) { - int fds[2]; - PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); - int id; - setsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, sizeof(id)); -} -#endif - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc deleted file mode 100644 index e6c64defad..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (c) 2013 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. - -// Note: any code in this file MUST be async-signal safe. - -#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" - -#include <stddef.h> -#include <stdint.h> -#include <sys/syscall.h> -#include <unistd.h> - -#include "base/debug/crash_logging.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -#if defined(__mips__) -// __NR_Linux, is defined in <asm/unistd.h>. -#include <asm/unistd.h> -#endif - -#define SECCOMP_MESSAGE_COMMON_CONTENT "seccomp-bpf failure" -#define SECCOMP_MESSAGE_CLONE_CONTENT "clone() failure" -#define SECCOMP_MESSAGE_PRCTL_CONTENT "prctl() failure" -#define SECCOMP_MESSAGE_IOCTL_CONTENT "ioctl() failure" -#define SECCOMP_MESSAGE_KILL_CONTENT "(tg)kill() failure" -#define SECCOMP_MESSAGE_FUTEX_CONTENT "futex() failure" - -namespace { - -inline bool IsArchitectureX86_64() { -#if defined(__x86_64__) - return true; -#else - return false; -#endif -} - -// Write |error_message| to stderr. Similar to RawLog(), but a bit more careful -// about async-signal safety. |size| is the size to write and should typically -// not include a terminating \0. -void WriteToStdErr(const char* error_message, size_t size) { - while (size > 0) { - // TODO(jln): query the current policy to check if send() is available and - // use it to perform a non-blocking write. - const int ret = HANDLE_EINTR( - sandbox::sys_write(STDERR_FILENO, error_message, size)); - // We can't handle any type of error here. - if (ret <= 0 || static_cast<size_t>(ret) > size) break; - size -= ret; - error_message += ret; - } -} - -// Invalid syscall values are truncated to zero. -// On architectures where base value is zero (Intel and Arm), -// syscall number is the same as offset from base. -// This function returns values between 0 and 1023 on all architectures. -// On architectures where base value is different than zero (currently only -// Mips), we are truncating valid syscall values to offset from base. -uint32_t SyscallNumberToOffsetFromBase(uint32_t sysno) { -#if defined(__mips__) - // On MIPS syscall numbers are in different range than on x86 and ARM. - // Valid MIPS O32 ABI syscall __NR_syscall will be truncated to zero for - // simplicity. - sysno = sysno - __NR_Linux; -#endif - - if (sysno >= 1024) - sysno = 0; - - return sysno; -} - -// Print a seccomp-bpf failure to handle |sysno| to stderr in an -// async-signal safe way. -void PrintSyscallError(uint32_t sysno) { - if (sysno >= 1024) - sysno = 0; - // TODO(markus): replace with async-signal safe snprintf when available. - const size_t kNumDigits = 4; - char sysno_base10[kNumDigits]; - uint32_t rem = sysno; - uint32_t mod = 0; - for (int i = kNumDigits - 1; i >= 0; i--) { - mod = rem % 10; - rem /= 10; - sysno_base10[i] = '0' + mod; - } - -#if defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) - static const char kSeccompErrorPrefix[] = __FILE__ - ":**CRASHING**:" SECCOMP_MESSAGE_COMMON_CONTENT " in syscall 4000 + "; -#else - static const char kSeccompErrorPrefix[] = - __FILE__":**CRASHING**:" SECCOMP_MESSAGE_COMMON_CONTENT " in syscall "; -#endif - static const char kSeccompErrorPostfix[] = "\n"; - WriteToStdErr(kSeccompErrorPrefix, sizeof(kSeccompErrorPrefix) - 1); - WriteToStdErr(sysno_base10, sizeof(sysno_base10)); - WriteToStdErr(kSeccompErrorPostfix, sizeof(kSeccompErrorPostfix) - 1); -} - -// Helper to convert a number of type T to a hexadecimal string using -// stack-allocated storage. -template <typename T> -class NumberToHex { - public: - explicit NumberToHex(T value) { - static const char kHexChars[] = "0123456789abcdef"; - - memset(str_, '0', sizeof(str_)); - str_[1] = 'x'; - str_[sizeof(str_) - 1] = '\0'; - - T rem = value; - T mod = 0; - for (size_t i = sizeof(str_) - 2; i >= 2; --i) { - mod = rem % 16; - rem /= 16; - str_[i] = kHexChars[mod]; - } - } - - const char* str() const { return str_; } - - static size_t length() { return sizeof(str_) - 1; } - - private: - // HEX uses two characters per byte, with a leading '0x', and a trailing NUL. - char str_[sizeof(T) * 2 + 3]; -}; - -// Records the syscall number and first four arguments in a crash key, to help -// debug the failure. -void SetSeccompCrashKey(const struct sandbox::arch_seccomp_data& args) { -#if !defined(OS_NACL_NONSFI) - NumberToHex<int> nr(args.nr); - NumberToHex<uint64_t> arg1(args.args[0]); - NumberToHex<uint64_t> arg2(args.args[1]); - NumberToHex<uint64_t> arg3(args.args[2]); - NumberToHex<uint64_t> arg4(args.args[3]); - - // In order to avoid calling into libc sprintf functions from an unsafe signal - // context, manually construct the crash key string. - const char* const prefixes[] = { - "nr=", - " arg1=", - " arg2=", - " arg3=", - " arg4=", - }; - const char* const values[] = { - nr.str(), - arg1.str(), - arg2.str(), - arg3.str(), - arg4.str(), - }; - - size_t crash_key_length = nr.length() + arg1.length() + arg2.length() + - arg3.length() + arg4.length(); - for (auto* prefix : prefixes) { - crash_key_length += strlen(prefix); - } - ++crash_key_length; // For the trailing NUL byte. - - char crash_key[crash_key_length]; - memset(crash_key, '\0', crash_key_length); - - size_t offset = 0; - for (size_t i = 0; i < arraysize(values); ++i) { - const char* strings[2] = { prefixes[i], values[i] }; - for (auto* string : strings) { - size_t string_len = strlen(string); - memmove(&crash_key[offset], string, string_len); - offset += string_len; - } - } - - base::debug::SetCrashKeyValue("seccomp-sigsys", crash_key); -#endif -} - -} // namespace - -namespace sandbox { - -intptr_t CrashSIGSYS_Handler(const struct arch_seccomp_data& args, void* aux) { - uint32_t syscall = SyscallNumberToOffsetFromBase(args.nr); - - PrintSyscallError(syscall); - SetSeccompCrashKey(args); - - // Encode 8-bits of the 1st two arguments too, so we can discern which socket - // type, which fcntl, ... etc., without being likely to hit a mapped - // address. - // Do not encode more bits here without thinking about increasing the - // likelihood of collision with mapped pages. - syscall |= ((args.args[0] & 0xffUL) << 12); - syscall |= ((args.args[1] & 0xffUL) << 20); - // Purposefully dereference the syscall as an address so it'll show up very - // clearly and easily in crash dumps. - volatile char* addr = reinterpret_cast<volatile char*>(syscall); - *addr = '\0'; - // In case we hit a mapped address, hit the null page with just the syscall, - // for paranoia. - syscall &= 0xfffUL; - addr = reinterpret_cast<volatile char*>(syscall); - *addr = '\0'; - for (;;) - _exit(1); -} - -// TODO(jln): refactor the reporting functions. - -intptr_t SIGSYSCloneFailure(const struct arch_seccomp_data& args, void* aux) { - static const char kSeccompCloneError[] = - __FILE__":**CRASHING**:" SECCOMP_MESSAGE_CLONE_CONTENT "\n"; - WriteToStdErr(kSeccompCloneError, sizeof(kSeccompCloneError) - 1); - SetSeccompCrashKey(args); - // "flags" is the first argument in the kernel's clone(). - // Mark as volatile to be able to find the value on the stack in a minidump. - volatile uint64_t clone_flags = args.args[0]; - volatile char* addr; - if (IsArchitectureX86_64()) { - addr = reinterpret_cast<volatile char*>(clone_flags & 0xFFFFFF); - *addr = '\0'; - } - // Hit the NULL page if this fails to fault. - addr = reinterpret_cast<volatile char*>(clone_flags & 0xFFF); - *addr = '\0'; - for (;;) - _exit(1); -} - -intptr_t SIGSYSPrctlFailure(const struct arch_seccomp_data& args, - void* /* aux */) { - static const char kSeccompPrctlError[] = - __FILE__":**CRASHING**:" SECCOMP_MESSAGE_PRCTL_CONTENT "\n"; - WriteToStdErr(kSeccompPrctlError, sizeof(kSeccompPrctlError) - 1); - SetSeccompCrashKey(args); - // Mark as volatile to be able to find the value on the stack in a minidump. - volatile uint64_t option = args.args[0]; - volatile char* addr = - reinterpret_cast<volatile char*>(option & 0xFFF); - *addr = '\0'; - for (;;) - _exit(1); -} - -intptr_t SIGSYSIoctlFailure(const struct arch_seccomp_data& args, - void* /* aux */) { - static const char kSeccompIoctlError[] = - __FILE__":**CRASHING**:" SECCOMP_MESSAGE_IOCTL_CONTENT "\n"; - WriteToStdErr(kSeccompIoctlError, sizeof(kSeccompIoctlError) - 1); - SetSeccompCrashKey(args); - // Make "request" volatile so that we can see it on the stack in a minidump. - volatile uint64_t request = args.args[1]; - volatile char* addr = reinterpret_cast<volatile char*>(request & 0xFFFF); - *addr = '\0'; - // Hit the NULL page if this fails. - addr = reinterpret_cast<volatile char*>(request & 0xFFF); - *addr = '\0'; - for (;;) - _exit(1); -} - -intptr_t SIGSYSKillFailure(const struct arch_seccomp_data& args, - void* /* aux */) { - static const char kSeccompKillError[] = - __FILE__":**CRASHING**:" SECCOMP_MESSAGE_KILL_CONTENT "\n"; - WriteToStdErr(kSeccompKillError, sizeof(kSeccompKillError) - 1); - SetSeccompCrashKey(args); - // Make "pid" volatile so that we can see it on the stack in a minidump. - volatile uint64_t my_pid = sys_getpid(); - volatile char* addr = reinterpret_cast<volatile char*>(my_pid & 0xFFF); - *addr = '\0'; - for (;;) - _exit(1); -} - -intptr_t SIGSYSFutexFailure(const struct arch_seccomp_data& args, - void* /* aux */) { - static const char kSeccompFutexError[] = - __FILE__ ":**CRASHING**:" SECCOMP_MESSAGE_FUTEX_CONTENT "\n"; - WriteToStdErr(kSeccompFutexError, sizeof(kSeccompFutexError) - 1); - SetSeccompCrashKey(args); - volatile int futex_op = args.args[1]; - volatile char* addr = reinterpret_cast<volatile char*>(futex_op & 0xFFF); - *addr = '\0'; - for (;;) - _exit(1); -} - -intptr_t SIGSYSSchedHandler(const struct arch_seccomp_data& args, - void* aux) { - switch (args.nr) { - case __NR_sched_getaffinity: - case __NR_sched_getattr: - case __NR_sched_getparam: - case __NR_sched_getscheduler: - case __NR_sched_rr_get_interval: - case __NR_sched_setaffinity: - case __NR_sched_setattr: - case __NR_sched_setparam: - case __NR_sched_setscheduler: - const pid_t tid = sys_gettid(); - // The first argument is the pid. If is our thread id, then replace it - // with 0, which is equivalent and allowed by the policy. - if (args.args[0] == static_cast<uint64_t>(tid)) { - return Syscall::Call(args.nr, - 0, - static_cast<intptr_t>(args.args[1]), - static_cast<intptr_t>(args.args[2]), - static_cast<intptr_t>(args.args[3]), - static_cast<intptr_t>(args.args[4]), - static_cast<intptr_t>(args.args[5])); - } - break; - } - - CrashSIGSYS_Handler(args, aux); - - // Should never be reached. - RAW_CHECK(false); - return -ENOSYS; -} - -bpf_dsl::ResultExpr CrashSIGSYS() { - return bpf_dsl::Trap(CrashSIGSYS_Handler, NULL); -} - -bpf_dsl::ResultExpr CrashSIGSYSClone() { - return bpf_dsl::Trap(SIGSYSCloneFailure, NULL); -} - -bpf_dsl::ResultExpr CrashSIGSYSPrctl() { - return bpf_dsl::Trap(SIGSYSPrctlFailure, NULL); -} - -bpf_dsl::ResultExpr CrashSIGSYSIoctl() { - return bpf_dsl::Trap(SIGSYSIoctlFailure, NULL); -} - -bpf_dsl::ResultExpr CrashSIGSYSKill() { - return bpf_dsl::Trap(SIGSYSKillFailure, NULL); -} - -bpf_dsl::ResultExpr CrashSIGSYSFutex() { - return bpf_dsl::Trap(SIGSYSFutexFailure, NULL); -} - -bpf_dsl::ResultExpr RewriteSchedSIGSYS() { - return bpf_dsl::Trap(SIGSYSSchedHandler, NULL); -} - -const char* GetErrorMessageContentForTests() { - return SECCOMP_MESSAGE_COMMON_CONTENT; -} - -const char* GetCloneErrorMessageContentForTests() { - return SECCOMP_MESSAGE_CLONE_CONTENT; -} - -const char* GetPrctlErrorMessageContentForTests() { - return SECCOMP_MESSAGE_PRCTL_CONTENT; -} - -const char* GetIoctlErrorMessageContentForTests() { - return SECCOMP_MESSAGE_IOCTL_CONTENT; -} - -const char* GetKillErrorMessageContentForTests() { - return SECCOMP_MESSAGE_KILL_CONTENT; -} - -const char* GetFutexErrorMessageContentForTests() { - return SECCOMP_MESSAGE_FUTEX_CONTENT; -} - -} // namespace sandbox. diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h deleted file mode 100644 index c64e994172..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2013 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_LINUX_SECCOMP_BPF_HELPERS_SIGSYS_HANDLERS_H_ -#define SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SIGSYS_HANDLERS_H_ - -#include <stdint.h> - -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/sandbox_export.h" - -// The handlers are suitable for use in Trap() error codes. They are -// guaranteed to be async-signal safe. -// See sandbox/linux/seccomp-bpf/trap.h to see how they work. - -namespace sandbox { - -struct arch_seccomp_data; - -// This handler will crash the currently running process. The crashing address -// will be the number of the current system call, extracted from |args|. -// This handler will also print to stderr the number of the crashing syscall. -SANDBOX_EXPORT intptr_t - CrashSIGSYS_Handler(const struct arch_seccomp_data& args, void* aux); - -// The following three handlers are suitable to report failures with the -// clone(), prctl() and ioctl() system calls respectively. - -// The crashing address will be (clone_flags & 0xFFFFFF), where clone_flags is -// the clone(2) argument, extracted from |args|. -SANDBOX_EXPORT intptr_t - SIGSYSCloneFailure(const struct arch_seccomp_data& args, void* aux); -// The crashing address will be (option & 0xFFF), where option is the prctl(2) -// argument. -SANDBOX_EXPORT intptr_t - SIGSYSPrctlFailure(const struct arch_seccomp_data& args, void* aux); -// The crashing address will be request & 0xFFFF, where request is the ioctl(2) -// argument. -SANDBOX_EXPORT intptr_t - SIGSYSIoctlFailure(const struct arch_seccomp_data& args, void* aux); -// The crashing address will be (pid & 0xFFF), where pid is the first -// argument (and can be a tid). -SANDBOX_EXPORT intptr_t - SIGSYSKillFailure(const struct arch_seccomp_data& args, void* aux); -// The crashing address will be (op & 0xFFF), where op is the second -// argument. -SANDBOX_EXPORT intptr_t - SIGSYSFutexFailure(const struct arch_seccomp_data& args, void* aux); -// If the syscall is not being called on the current tid, crashes in the same -// way as CrashSIGSYS_Handler. Otherwise, returns the result of calling the -// syscall with the pid argument set to 0 (which for these calls means the -// current thread). The following syscalls are supported: -// -// sched_getaffinity(), sched_getattr(), sched_getparam(), sched_getscheduler(), -// sched_rr_get_interval(), sched_setaffinity(), sched_setattr(), -// sched_setparam(), sched_setscheduler() -SANDBOX_EXPORT intptr_t - SIGSYSSchedHandler(const struct arch_seccomp_data& args, void* aux); - -// Variants of the above functions for use with bpf_dsl. -SANDBOX_EXPORT bpf_dsl::ResultExpr CrashSIGSYS(); -SANDBOX_EXPORT bpf_dsl::ResultExpr CrashSIGSYSClone(); -SANDBOX_EXPORT bpf_dsl::ResultExpr CrashSIGSYSPrctl(); -SANDBOX_EXPORT bpf_dsl::ResultExpr CrashSIGSYSIoctl(); -SANDBOX_EXPORT bpf_dsl::ResultExpr CrashSIGSYSKill(); -SANDBOX_EXPORT bpf_dsl::ResultExpr CrashSIGSYSFutex(); -SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteSchedSIGSYS(); - -// Following four functions return substrings of error messages used -// in the above four functions. They are useful in death tests. -SANDBOX_EXPORT const char* GetErrorMessageContentForTests(); -SANDBOX_EXPORT const char* GetCloneErrorMessageContentForTests(); -SANDBOX_EXPORT const char* GetPrctlErrorMessageContentForTests(); -SANDBOX_EXPORT const char* GetIoctlErrorMessageContentForTests(); -SANDBOX_EXPORT const char* GetKillErrorMessageContentForTests(); -SANDBOX_EXPORT const char* GetFutexErrorMessageContentForTests(); - -} // namespace sandbox. - -#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SIGSYS_HANDLERS_H_ diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc deleted file mode 100644 index 061bfb4803..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright (c) 2013 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/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" - -#include <errno.h> -#include <fcntl.h> -#include <fcntl.h> -#include <linux/net.h> -#include <sched.h> -#include <signal.h> -#include <stdint.h> -#include <sys/mman.h> -#include <sys/prctl.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <time.h> -#include <unistd.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/system_headers/linux_futex.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" -#include "sandbox/linux/system_headers/linux_time.h" - -// PNaCl toolchain does not provide sys/ioctl.h header. -#if !defined(OS_NACL_NONSFI) -#include <sys/ioctl.h> -#endif - -#if defined(OS_ANDROID) - -#if !defined(F_DUPFD_CLOEXEC) -#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6) -#endif - -// https://android.googlesource.com/platform/bionic/+/lollipop-release/libc/private/bionic_prctl.h -#if !defined(PR_SET_VMA) -#define PR_SET_VMA 0x53564d41 -#endif - -#ifndef PR_SET_PTRACER -#define PR_SET_PTRACER 0x59616d61 -#endif - -#endif // defined(OS_ANDROID) - -#if defined(__arm__) && !defined(MAP_STACK) -#define MAP_STACK 0x20000 // Daisy build environment has old headers. -#endif - -#if defined(__mips__) && !defined(MAP_STACK) -#define MAP_STACK 0x40000 -#endif -namespace { - -inline bool IsArchitectureX86_64() { -#if defined(__x86_64__) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureI386() { -#if defined(__i386__) - return true; -#else - return false; -#endif -} - -inline bool IsAndroid() { -#if defined(OS_ANDROID) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureMips() { -#if defined(__mips__) - return true; -#else - return false; -#endif -} - -// Ubuntu's version of glibc has a race condition in sem_post that can cause -// it to call futex(2) with bogus op arguments. To workaround this, we need -// to allow those futex(2) calls to fail with EINVAL, instead of crashing the -// process. See crbug.com/598471. -inline bool IsBuggyGlibcSemPost() { -#if defined(LIBC_GLIBC) && !defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - -} // namespace. - -#define CASES SANDBOX_BPF_DSL_CASES - -using sandbox::bpf_dsl::Allow; -using sandbox::bpf_dsl::Arg; -using sandbox::bpf_dsl::BoolExpr; -using sandbox::bpf_dsl::Error; -using sandbox::bpf_dsl::If; -using sandbox::bpf_dsl::ResultExpr; - -namespace sandbox { - -#if !defined(OS_NACL_NONSFI) -// Allow Glibc's and Android pthread creation flags, crash on any other -// thread creation attempts and EPERM attempts to use neither -// CLONE_VM, nor CLONE_THREAD, which includes all fork() implementations. -ResultExpr RestrictCloneToThreadsAndEPERMFork() { - const Arg<unsigned long> flags(0); - - // TODO(mdempsky): Extend DSL to support (flags & ~mask1) == mask2. - const uint64_t kAndroidCloneMask = CLONE_VM | CLONE_FS | CLONE_FILES | - CLONE_SIGHAND | CLONE_THREAD | - CLONE_SYSVSEM; - const uint64_t kObsoleteAndroidCloneMask = kAndroidCloneMask | CLONE_DETACHED; - - const uint64_t kGlibcPthreadFlags = - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | - CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; - const BoolExpr glibc_test = flags == kGlibcPthreadFlags; - - const BoolExpr android_test = - AnyOf(flags == kAndroidCloneMask, flags == kObsoleteAndroidCloneMask, - flags == kGlibcPthreadFlags); - - return If(IsAndroid() ? android_test : glibc_test, Allow()) - .ElseIf((flags & (CLONE_VM | CLONE_THREAD)) == 0, Error(EPERM)) - .Else(CrashSIGSYSClone()); -} - -ResultExpr RestrictPrctl() { - // Will need to add seccomp compositing in the future. PR_SET_PTRACER is - // used by breakpad but not needed anymore. - const Arg<int> option(0); - return Switch(option) - .CASES((PR_GET_NAME, PR_SET_NAME, PR_GET_DUMPABLE, PR_SET_DUMPABLE -#if defined(OS_ANDROID) - , PR_SET_VMA, PR_SET_PTRACER - -// Enable PR_SET_TIMERSLACK_PID, an Android custom prctl which is used in: -// https://android.googlesource.com/platform/system/core/+/lollipop-release/libcutils/sched_policy.c. -// Depending on the Android kernel version, this prctl may have different -// values. Since we don't know the correct value for the running kernel, we must -// allow them all. -// -// The effect is: -// On 3.14 kernels, this allows PR_SET_TIMERSLACK_PID and 43 and 127 (invalid -// prctls which will return EINVAL) -// On 3.18 kernels, this allows PR_SET_TIMERSLACK_PID, PR_SET_THP_DISABLE, and -// 127 (invalid). -// On 4.1 kernels and up, this allows PR_SET_TIMERSLACK_PID, PR_SET_THP_DISABLE, -// and PR_MPX_ENABLE_MANAGEMENT. - -// https://android.googlesource.com/kernel/common/+/android-3.14/include/uapi/linux/prctl.h -#define PR_SET_TIMERSLACK_PID_1 41 - -// https://android.googlesource.com/kernel/common/+/android-3.18/include/uapi/linux/prctl.h -#define PR_SET_TIMERSLACK_PID_2 43 - -// https://android.googlesource.com/kernel/common/+/android-4.1/include/uapi/linux/prctl.h and up -#define PR_SET_TIMERSLACK_PID_3 127 - - , PR_SET_TIMERSLACK_PID_1 - , PR_SET_TIMERSLACK_PID_2 - , PR_SET_TIMERSLACK_PID_3 -#endif // defined(OS_ANDROID) - ), - Allow()) - .Default(CrashSIGSYSPrctl()); -} - -ResultExpr RestrictIoctl() { - const Arg<int> request(1); - return Switch(request).CASES((TCGETS, FIONREAD), Allow()).Default( - CrashSIGSYSIoctl()); -} - -ResultExpr RestrictMmapFlags() { - // The flags you see are actually the allowed ones, and the variable is a - // "denied" mask because of the negation operator. - // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as - // MAP_POPULATE. - // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries. - const uint64_t kAllowedMask = MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | - MAP_STACK | MAP_NORESERVE | MAP_FIXED | - MAP_DENYWRITE; - const Arg<int> flags(3); - return If((flags & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); -} - -ResultExpr RestrictMprotectFlags() { - // The flags you see are actually the allowed ones, and the variable is a - // "denied" mask because of the negation operator. - // Significantly, we don't permit weird undocumented flags such as - // PROT_GROWSDOWN. - const uint64_t kAllowedMask = PROT_READ | PROT_WRITE | PROT_EXEC; - const Arg<int> prot(2); - return If((prot & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); -} - -ResultExpr RestrictFcntlCommands() { - // We also restrict the flags in F_SETFL. We don't want to permit flags with - // a history of trouble such as O_DIRECT. The flags you see are actually the - // allowed ones, and the variable is a "denied" mask because of the negation - // operator. - // Glibc overrides the kernel's O_LARGEFILE value. Account for this. - uint64_t kOLargeFileFlag = O_LARGEFILE; - if (IsArchitectureX86_64() || IsArchitectureI386() || IsArchitectureMips()) - kOLargeFileFlag = 0100000; - - const Arg<int> cmd(1); - const Arg<long> long_arg(2); - - const uint64_t kAllowedMask = O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC | - kOLargeFileFlag | O_CLOEXEC | O_NOATIME; - return Switch(cmd) - .CASES((F_GETFL, - F_GETFD, - F_SETFD, - F_SETLK, - F_SETLKW, - F_GETLK, - F_DUPFD, - F_DUPFD_CLOEXEC), - Allow()) - .Case(F_SETFL, - If((long_arg & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS())) - .Default(CrashSIGSYS()); -} - -#if defined(__i386__) || defined(__mips__) -ResultExpr RestrictSocketcallCommand() { - // Unfortunately, we are unable to restrict the first parameter to - // socketpair(2). Whilst initially sounding bad, it's noteworthy that very - // few protocols actually support socketpair(2). The scary call that we're - // worried about, socket(2), remains blocked. - const Arg<int> call(0); - return Switch(call) - .CASES((SYS_SOCKETPAIR, - SYS_SHUTDOWN, - SYS_RECV, - SYS_SEND, - SYS_RECVFROM, - SYS_SENDTO, - SYS_RECVMSG, - SYS_SENDMSG), - Allow()) - .Default(Error(EPERM)); -} -#endif - -ResultExpr RestrictKillTarget(pid_t target_pid, int sysno) { - switch (sysno) { - case __NR_kill: - case __NR_tgkill: { - const Arg<pid_t> pid(0); - return If(pid == target_pid, Allow()).Else(CrashSIGSYSKill()); - } - case __NR_tkill: - return CrashSIGSYSKill(); - default: - NOTREACHED(); - return CrashSIGSYS(); - } -} - -ResultExpr RestrictFutex() { - const uint64_t kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; - const Arg<int> op(1); - return Switch(op & ~kAllowedFutexFlags) - .CASES((FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, - FUTEX_WAKE_OP, FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET), - Allow()) - .Default(IsBuggyGlibcSemPost() ? Error(EINVAL) : CrashSIGSYSFutex()); -} - -ResultExpr RestrictGetSetpriority(pid_t target_pid) { - const Arg<int> which(0); - const Arg<int> who(1); - return If(which == PRIO_PROCESS, - Switch(who).CASES((0, target_pid), Allow()).Default(Error(EPERM))) - .Else(CrashSIGSYS()); -} - -ResultExpr RestrictSchedTarget(pid_t target_pid, int sysno) { - switch (sysno) { - case __NR_sched_getaffinity: - case __NR_sched_getattr: - case __NR_sched_getparam: - case __NR_sched_getscheduler: - case __NR_sched_rr_get_interval: - case __NR_sched_setaffinity: - case __NR_sched_setattr: - case __NR_sched_setparam: - case __NR_sched_setscheduler: { - const Arg<pid_t> pid(0); - return Switch(pid) - .CASES((0, target_pid), Allow()) - .Default(RewriteSchedSIGSYS()); - } - default: - NOTREACHED(); - return CrashSIGSYS(); - } -} - -ResultExpr RestrictPrlimit64(pid_t target_pid) { - const Arg<pid_t> pid(0); - return Switch(pid).CASES((0, target_pid), Allow()).Default(CrashSIGSYS()); -} - -ResultExpr RestrictGetrusage() { - const Arg<int> who(0); - return If(who == RUSAGE_SELF, Allow()).Else(CrashSIGSYS()); -} -#endif // !defined(OS_NACL_NONSFI) - -ResultExpr RestrictClockID() { - static_assert(4 == sizeof(clockid_t), "clockid_t is not 32bit"); - const Arg<clockid_t> clockid(0); - return Switch(clockid) - .CASES(( -#if defined(OS_ANDROID) - CLOCK_BOOTTIME, -#endif - CLOCK_MONOTONIC, - CLOCK_MONOTONIC_COARSE, - CLOCK_PROCESS_CPUTIME_ID, - CLOCK_REALTIME, - CLOCK_REALTIME_COARSE, - CLOCK_THREAD_CPUTIME_ID), - Allow()) - .Default(CrashSIGSYS()); -} - -#if !defined(GRND_NONBLOCK) -#define GRND_NONBLOCK 1 -#endif - -ResultExpr RestrictGetRandom() { - const Arg<unsigned int> flags(2); - const unsigned int kGoodFlags = GRND_NONBLOCK; - return If((flags & ~kGoodFlags) == 0, Allow()).Else(CrashSIGSYS()); -} - -ResultExpr RestrictPrlimitToGetrlimit(pid_t target_pid) { - const Arg<pid_t> pid(0); - const Arg<uintptr_t> new_limit(2); - // Only allow 'get' operations, and only for the current process. - return If(AllOf(new_limit == 0, AnyOf(pid == 0, pid == target_pid)), Allow()) - .Else(Error(EPERM)); -} - -} // namespace sandbox. diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h deleted file mode 100644 index c4577dc97d..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2013 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_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_ -#define SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_ - -#include <unistd.h> - -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" -#include "sandbox/sandbox_export.h" - -// These are helpers to build seccomp-bpf policies, i.e. policies for a -// sandbox that reduces the Linux kernel's attack surface. They return a -// bpf_dsl::ResultExpr suitable to restrict certain system call parameters. - -namespace sandbox { - -// Allow clone(2) for threads. -// Reject fork(2) attempts with EPERM. -// Don't restrict on ASAN. -// Crash if anything else is attempted. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictCloneToThreadsAndEPERMFork(); - -// Allow PR_SET_NAME, PR_SET_DUMPABLE, PR_GET_DUMPABLE. -// Crash if anything else is attempted. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictPrctl(); - -// Allow TCGETS and FIONREAD. -// Crash if anything else is attempted. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictIoctl(); - -// Restrict the flags argument in mmap(2). -// Only allow: MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | -// MAP_STACK | MAP_NORESERVE | MAP_FIXED | MAP_DENYWRITE. -// Crash if any other flag is used. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMmapFlags(); - -// Restrict the prot argument in mprotect(2). -// Only allow: PROT_READ | PROT_WRITE | PROT_EXEC. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMprotectFlags(); - -// Restrict fcntl(2) cmd argument to: -// We allow F_GETFL, F_SETFL, F_GETFD, F_SETFD, F_DUPFD, F_DUPFD_CLOEXEC, -// F_SETLK, F_SETLKW and F_GETLK. -// Also, in F_SETFL, restrict the allowed flags to: O_ACCMODE | O_APPEND | -// O_NONBLOCK | O_SYNC | O_LARGEFILE | O_CLOEXEC | O_NOATIME. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictFcntlCommands(); - -#if defined(__i386__) || defined(__mips__) -// Restrict socketcall(2) to only allow socketpair(2), send(2), recv(2), -// sendto(2), recvfrom(2), shutdown(2), sendmsg(2) and recvmsg(2). -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictSocketcallCommand(); -#endif - -// Restrict |sysno| (which must be kill, tkill or tgkill) by allowing tgkill or -// kill iff the first parameter is |target_pid|, crashing otherwise or if -// |sysno| is tkill. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictKillTarget(pid_t target_pid, - int sysno); - -// Crash if FUTEX_CMP_REQUEUE_PI is used in the second argument of futex(2). -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictFutex(); - -// Crash if |which| is not PRIO_PROCESS. EPERM if |who| is not 0, neither -// |target_pid| while calling setpriority(2) / getpriority(2). -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictGetSetpriority(pid_t target_pid); - -// Restricts |pid| for sched_* syscalls which take a pid as the first argument. -// We only allow calling these syscalls if the pid argument is equal to the pid -// of the sandboxed process or 0 (indicating the current thread). The following -// syscalls are supported: -// -// sched_getaffinity(), sched_getattr(), sched_getparam(), sched_getscheduler(), -// sched_rr_get_interval(), sched_setaffinity(), sched_setattr(), -// sched_setparam(), sched_setscheduler() -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictSchedTarget(pid_t target_pid, - int sysno); - -// Restricts the |pid| argument of prlimit64 to 0 (meaning the calling process) -// or target_pid. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictPrlimit64(pid_t target_pid); - -// Restricts the |who| argument of getrusage to RUSAGE_SELF (meaning the calling -// process). -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictGetrusage(); - -// Restrict |clk_id| for clock_getres(), clock_gettime() and clock_settime(). -// We allow accessing only CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, -// CLOCK_REALTIME, and CLOCK_THREAD_CPUTIME_ID. In particular, this disallows -// access to arbitrary per-{process,thread} CPU-time clock IDs (such as those -// returned by {clock,pthread}_getcpuclockid), which can leak information -// about the state of the host OS. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictClockID(); - -// Restrict the flags argument to getrandom() to allow only no flags, or -// GRND_NONBLOCK. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictGetRandom(); - -// Restrict |new_limit| to NULL, and |pid| to the calling process (or 0) for -// prlimit64(). This allows only getting rlimits on the current process. -// Otherwise, fail gracefully; see crbug.com/160157. -SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictPrlimitToGetrlimit(pid_t target_pid); - -} // namespace sandbox. - -#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_ diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc deleted file mode 100644 index c068cd2d04..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright 2014 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/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" - -#include <errno.h> -#include <sched.h> -#include <sys/resource.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <time.h> -#include <unistd.h> - -#include "base/bind.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" -#include "base/sys_info.h" -#include "base/threading/thread.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" -#include "sandbox/linux/seccomp-bpf/bpf_tests.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" -#include "sandbox/linux/system_headers/linux_time.h" -#include "sandbox/linux/tests/unit_tests.h" - -#if !defined(OS_ANDROID) -#include "third_party/lss/linux_syscall_support.h" // for MAKE_PROCESS_CPUCLOCK -#endif - -namespace sandbox { - -namespace { - -// NOTE: most of the parameter restrictions are tested in -// baseline_policy_unittest.cc as a more end-to-end test. - -using sandbox::bpf_dsl::Allow; -using sandbox::bpf_dsl::ResultExpr; - -class RestrictClockIdPolicy : public bpf_dsl::Policy { - public: - RestrictClockIdPolicy() {} - ~RestrictClockIdPolicy() override {} - - ResultExpr EvaluateSyscall(int sysno) const override { - switch (sysno) { - case __NR_clock_gettime: - case __NR_clock_getres: - return RestrictClockID(); - default: - return Allow(); - } - } -}; - -void CheckClock(clockid_t clockid) { - struct timespec ts; - ts.tv_sec = -1; - ts.tv_nsec = -1; - BPF_ASSERT_EQ(0, clock_getres(clockid, &ts)); - BPF_ASSERT_EQ(0, ts.tv_sec); - BPF_ASSERT_LE(0, ts.tv_nsec); - ts.tv_sec = -1; - ts.tv_nsec = -1; - BPF_ASSERT_EQ(0, clock_gettime(clockid, &ts)); - BPF_ASSERT_LE(0, ts.tv_sec); - BPF_ASSERT_LE(0, ts.tv_nsec); -} - -BPF_TEST_C(ParameterRestrictions, - clock_gettime_allowed, - RestrictClockIdPolicy) { - CheckClock(CLOCK_MONOTONIC); - CheckClock(CLOCK_MONOTONIC_COARSE); - CheckClock(CLOCK_PROCESS_CPUTIME_ID); -#if defined(OS_ANDROID) - CheckClock(CLOCK_BOOTTIME); -#endif - CheckClock(CLOCK_REALTIME); - CheckClock(CLOCK_REALTIME_COARSE); - CheckClock(CLOCK_THREAD_CPUTIME_ID); -} - -BPF_DEATH_TEST_C(ParameterRestrictions, - clock_gettime_crash_monotonic_raw, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - RestrictClockIdPolicy) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); -} - -#if !defined(OS_ANDROID) -BPF_DEATH_TEST_C(ParameterRestrictions, - clock_gettime_crash_cpu_clock, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - RestrictClockIdPolicy) { - // We can't use clock_getcpuclockid() because it's not implemented in newlib, - // and it might not work inside the sandbox anyway. - const pid_t kInitPID = 1; - const clockid_t kInitCPUClockID = - MAKE_PROCESS_CPUCLOCK(kInitPID, CPUCLOCK_SCHED); - - struct timespec ts; - clock_gettime(kInitCPUClockID, &ts); -} -#endif // !defined(OS_ANDROID) - -class RestrictSchedPolicy : public bpf_dsl::Policy { - public: - RestrictSchedPolicy() {} - ~RestrictSchedPolicy() override {} - - ResultExpr EvaluateSyscall(int sysno) const override { - switch (sysno) { - case __NR_sched_getparam: - return RestrictSchedTarget(getpid(), sysno); - default: - return Allow(); - } - } -}; - -void CheckSchedGetParam(pid_t pid, struct sched_param* param) { - BPF_ASSERT_EQ(0, sched_getparam(pid, param)); -} - -void SchedGetParamThread(base::WaitableEvent* thread_run) { - const pid_t pid = getpid(); - const pid_t tid = sys_gettid(); - BPF_ASSERT_NE(pid, tid); - - struct sched_param current_pid_param; - CheckSchedGetParam(pid, ¤t_pid_param); - - struct sched_param zero_param; - CheckSchedGetParam(0, &zero_param); - - struct sched_param tid_param; - CheckSchedGetParam(tid, &tid_param); - - BPF_ASSERT_EQ(zero_param.sched_priority, tid_param.sched_priority); - - // Verify that the SIGSYS handler sets errno properly. - errno = 0; - BPF_ASSERT_EQ(-1, sched_getparam(tid, NULL)); - BPF_ASSERT_EQ(EINVAL, errno); - - thread_run->Signal(); -} - -BPF_TEST_C(ParameterRestrictions, - sched_getparam_allowed, - RestrictSchedPolicy) { - base::WaitableEvent thread_run( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - // Run the actual test in a new thread so that the current pid and tid are - // different. - base::Thread getparam_thread("sched_getparam_thread"); - BPF_ASSERT(getparam_thread.Start()); - getparam_thread.task_runner()->PostTask( - FROM_HERE, base::Bind(&SchedGetParamThread, &thread_run)); - BPF_ASSERT(thread_run.TimedWait(base::TimeDelta::FromMilliseconds(5000))); - getparam_thread.Stop(); -} - -BPF_DEATH_TEST_C(ParameterRestrictions, - sched_getparam_crash_non_zero, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - RestrictSchedPolicy) { - const pid_t kInitPID = 1; - struct sched_param param; - sched_getparam(kInitPID, ¶m); -} - -class RestrictPrlimit64Policy : public bpf_dsl::Policy { - public: - RestrictPrlimit64Policy() {} - ~RestrictPrlimit64Policy() override {} - - ResultExpr EvaluateSyscall(int sysno) const override { - switch (sysno) { - case __NR_prlimit64: - return RestrictPrlimit64(getpid()); - default: - return Allow(); - } - } -}; - -BPF_TEST_C(ParameterRestrictions, prlimit64_allowed, RestrictPrlimit64Policy) { - BPF_ASSERT_EQ(0, sys_prlimit64(0, RLIMIT_AS, NULL, NULL)); - BPF_ASSERT_EQ(0, sys_prlimit64(getpid(), RLIMIT_AS, NULL, NULL)); -} - -BPF_DEATH_TEST_C(ParameterRestrictions, - prlimit64_crash_not_self, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - RestrictPrlimit64Policy) { - const pid_t kInitPID = 1; - BPF_ASSERT_NE(kInitPID, getpid()); - sys_prlimit64(kInitPID, RLIMIT_AS, NULL, NULL); -} - -class RestrictGetrusagePolicy : public bpf_dsl::Policy { - public: - RestrictGetrusagePolicy() {} - ~RestrictGetrusagePolicy() override {} - - ResultExpr EvaluateSyscall(int sysno) const override { - switch (sysno) { - case __NR_getrusage: - return RestrictGetrusage(); - default: - return Allow(); - } - } -}; - -BPF_TEST_C(ParameterRestrictions, getrusage_allowed, RestrictGetrusagePolicy) { - struct rusage usage; - BPF_ASSERT_EQ(0, getrusage(RUSAGE_SELF, &usage)); -} - -BPF_DEATH_TEST_C(ParameterRestrictions, - getrusage_crash_not_self, - DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), - RestrictGetrusagePolicy) { - struct rusage usage; - getrusage(RUSAGE_CHILDREN, &usage); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc deleted file mode 100644 index 1d9f95cd64..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc +++ /dev/null @@ -1,1058 +0,0 @@ -// Copyright (c) 2013 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/linux/seccomp-bpf-helpers/syscall_sets.h" - -#include "build/build_config.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -namespace sandbox { - -// The functions below cover all existing i386, x86_64, and ARM system calls; -// excluding syscalls made obsolete in ARM EABI. -// The implicitly defined sets form a partition of the sets of -// system calls. - -bool SyscallSets::IsKill(int sysno) { - switch (sysno) { - case __NR_kill: - case __NR_tgkill: - case __NR_tkill: // Deprecated. - return true; - default: - return false; - } -} - -bool SyscallSets::IsAllowedGettime(int sysno) { - switch (sysno) { - case __NR_gettimeofday: -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_time: -#endif - return true; - case __NR_adjtimex: // Privileged. - case __NR_clock_adjtime: // Privileged. - case __NR_clock_getres: // Could be allowed. - case __NR_clock_gettime: - case __NR_clock_nanosleep: // Could be allowed. - case __NR_clock_settime: // Privileged. -#if defined(__i386__) || defined(__mips__) - case __NR_ftime: // Obsolete. -#endif - case __NR_settimeofday: // Privileged. -#if defined(__i386__) || defined(__mips__) - case __NR_stime: -#endif - default: - return false; - } -} - -bool SyscallSets::IsCurrentDirectory(int sysno) { - switch (sysno) { - case __NR_getcwd: - case __NR_chdir: - case __NR_fchdir: - return true; - default: - return false; - } -} - -bool SyscallSets::IsUmask(int sysno) { - switch (sysno) { - case __NR_umask: - return true; - default: - return false; - } -} - -// System calls that directly access the file system. They might acquire -// a new file descriptor or otherwise perform an operation directly -// via a path. -// Both EPERM and ENOENT are valid errno unless otherwise noted in comment. -bool SyscallSets::IsFileSystem(int sysno) { - switch (sysno) { -#if !defined(__aarch64__) - case __NR_access: // EPERM not a valid errno. - case __NR_chmod: - case __NR_chown: -#if defined(__i386__) || defined(__arm__) - case __NR_chown32: -#endif - case __NR_creat: - case __NR_futimesat: // Should be called utimesat ? - case __NR_lchown: - case __NR_link: - case __NR_lstat: // EPERM not a valid errno. - case __NR_mkdir: - case __NR_mknod: - case __NR_open: - case __NR_readlink: // EPERM not a valid errno. - case __NR_rename: - case __NR_rmdir: - case __NR_stat: // EPERM not a valid errno. - case __NR_symlink: - case __NR_unlink: - case __NR_uselib: // Neither EPERM, nor ENOENT are valid errno. - case __NR_ustat: // Same as above. Deprecated. - case __NR_utimes: -#endif // !defined(__aarch64__) - - case __NR_execve: - case __NR_faccessat: // EPERM not a valid errno. - case __NR_fchmodat: - case __NR_fchownat: // Should be called chownat ? -#if defined(__x86_64__) || defined(__aarch64__) - case __NR_newfstatat: // fstatat(). EPERM not a valid errno. -#elif defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_fstatat64: -#endif -#if defined(__i386__) || defined(__arm__) - case __NR_lchown32: -#endif - case __NR_linkat: - case __NR_lookup_dcookie: // ENOENT not a valid errno. - -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_lstat64: -#endif - case __NR_memfd_create: - case __NR_mkdirat: - case __NR_mknodat: -#if defined(__i386__) - case __NR_oldlstat: - case __NR_oldstat: -#endif - case __NR_openat: - case __NR_readlinkat: - case __NR_renameat: - case __NR_renameat2: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_stat64: -#endif - case __NR_statfs: // EPERM not a valid errno. -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_statfs64: -#endif - case __NR_symlinkat: - case __NR_truncate: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_truncate64: -#endif - case __NR_unlinkat: -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_utime: -#endif - case __NR_utimensat: // New. - return true; - default: - return false; - } -} - -bool SyscallSets::IsAllowedFileSystemAccessViaFd(int sysno) { - switch (sysno) { - case __NR_fstat: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_fstat64: -#endif - return true; -// TODO(jln): these should be denied gracefully as well (moved below). -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_fadvise64: // EPERM not a valid errno. -#endif -#if defined(__i386__) - case __NR_fadvise64_64: -#endif -#if defined(__arm__) - case __NR_arm_fadvise64_64: -#endif - case __NR_fdatasync: // EPERM not a valid errno. - case __NR_flock: // EPERM not a valid errno. - case __NR_fstatfs: // Give information about the whole filesystem. -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_fstatfs64: -#endif - case __NR_fsync: // EPERM not a valid errno. -#if defined(__i386__) - case __NR_oldfstat: -#endif -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_sync_file_range: // EPERM not a valid errno. -#elif defined(__arm__) - case __NR_arm_sync_file_range: // EPERM not a valid errno. -#endif - default: - return false; - } -} - -// EPERM is a good errno for any of these. -bool SyscallSets::IsDeniedFileSystemAccessViaFd(int sysno) { - switch (sysno) { - case __NR_fallocate: - case __NR_fchmod: - case __NR_fchown: - case __NR_ftruncate: -#if defined(__i386__) || defined(__arm__) - case __NR_fchown32: -#endif -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_ftruncate64: -#endif -#if !defined(__aarch64__) - case __NR_getdents: // EPERM not a valid errno. -#endif - case __NR_getdents64: // EPERM not a valid errno. -#if defined(__i386__) || defined(__mips__) - case __NR_readdir: -#endif - return true; - default: - return false; - } -} - -bool SyscallSets::IsGetSimpleId(int sysno) { - switch (sysno) { - case __NR_capget: - case __NR_getegid: - case __NR_geteuid: - case __NR_getgid: - case __NR_getgroups: - case __NR_getpid: - case __NR_getppid: - case __NR_getresgid: - case __NR_getsid: - case __NR_gettid: - case __NR_getuid: - case __NR_getresuid: -#if defined(__i386__) || defined(__arm__) - case __NR_getegid32: - case __NR_geteuid32: - case __NR_getgid32: - case __NR_getgroups32: - case __NR_getresgid32: - case __NR_getresuid32: - case __NR_getuid32: -#endif - return true; - default: - return false; - } -} - -bool SyscallSets::IsProcessPrivilegeChange(int sysno) { - switch (sysno) { - case __NR_capset: -#if defined(__i386__) || defined(__x86_64__) - case __NR_ioperm: // Intel privilege. - case __NR_iopl: // Intel privilege. -#endif - case __NR_setfsgid: - case __NR_setfsuid: - case __NR_setgid: - case __NR_setgroups: - case __NR_setregid: - case __NR_setresgid: - case __NR_setresuid: - case __NR_setreuid: - case __NR_setuid: -#if defined(__i386__) || defined(__arm__) - case __NR_setfsgid32: - case __NR_setfsuid32: - case __NR_setgid32: - case __NR_setgroups32: - case __NR_setregid32: - case __NR_setresgid32: - case __NR_setresuid32: - case __NR_setreuid32: - case __NR_setuid32: -#endif - return true; - default: - return false; - } -} - -bool SyscallSets::IsProcessGroupOrSession(int sysno) { - switch (sysno) { - case __NR_setpgid: -#if !defined(__aarch64__) - case __NR_getpgrp: -#endif - case __NR_setsid: - case __NR_getpgid: - return true; - default: - return false; - } -} - -bool SyscallSets::IsAllowedSignalHandling(int sysno) { - switch (sysno) { - case __NR_rt_sigaction: - case __NR_rt_sigprocmask: - case __NR_rt_sigreturn: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_sigaction: - case __NR_sigprocmask: - case __NR_sigreturn: -#endif - return true; - case __NR_rt_sigpending: - case __NR_rt_sigqueueinfo: - case __NR_rt_sigsuspend: - case __NR_rt_sigtimedwait: - case __NR_rt_tgsigqueueinfo: - case __NR_sigaltstack: -#if !defined(__aarch64__) - case __NR_signalfd: -#endif - case __NR_signalfd4: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_sigpending: - case __NR_sigsuspend: -#endif -#if defined(__i386__) || defined(__mips__) - case __NR_signal: - case __NR_sgetmask: // Obsolete. - case __NR_ssetmask: -#endif - default: - return false; - } -} - -bool SyscallSets::IsAllowedOperationOnFd(int sysno) { - switch (sysno) { - case __NR_close: - case __NR_dup: -#if !defined(__aarch64__) - case __NR_dup2: -#endif - case __NR_dup3: -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_shutdown: -#endif - return true; - case __NR_fcntl: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_fcntl64: -#endif - default: - return false; - } -} - -bool SyscallSets::IsKernelInternalApi(int sysno) { - switch (sysno) { - case __NR_restart_syscall: -#if defined(__arm__) - case __ARM_NR_cmpxchg: -#endif - return true; - default: - return false; - } -} - -// This should be thought through in conjunction with IsFutex(). -bool SyscallSets::IsAllowedProcessStartOrDeath(int sysno) { - switch (sysno) { - case __NR_exit: - case __NR_exit_group: - case __NR_wait4: - case __NR_waitid: -#if defined(__i386__) - case __NR_waitpid: -#endif - return true; - case __NR_clone: // Should be parameter-restricted. - case __NR_setns: // Privileged. -#if !defined(__aarch64__) - case __NR_fork: -#endif -#if defined(__i386__) || defined(__x86_64__) - case __NR_get_thread_area: -#endif -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_set_thread_area: -#endif - case __NR_set_tid_address: - case __NR_unshare: -#if !defined(__mips__) && !defined(__aarch64__) - case __NR_vfork: -#endif - default: - return false; - } -} - -// It's difficult to restrict those, but there is attack surface here. -bool SyscallSets::IsAllowedFutex(int sysno) { - switch (sysno) { - case __NR_get_robust_list: - case __NR_set_robust_list: - case __NR_futex: - default: - return false; - } -} - -bool SyscallSets::IsAllowedEpoll(int sysno) { - switch (sysno) { -#if !defined(__aarch64__) - case __NR_epoll_create: - case __NR_epoll_wait: -#endif - case __NR_epoll_pwait: - case __NR_epoll_create1: - case __NR_epoll_ctl: - return true; - default: -#if defined(__x86_64__) - case __NR_epoll_ctl_old: -#endif -#if defined(__x86_64__) - case __NR_epoll_wait_old: -#endif - return false; - } -} - -bool SyscallSets::IsAllowedGetOrModifySocket(int sysno) { - switch (sysno) { -#if !defined(__aarch64__) - case __NR_pipe: -#endif - case __NR_pipe2: - return true; - default: -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_socketpair: // We will want to inspect its argument. -#endif - return false; - } -} - -bool SyscallSets::IsDeniedGetOrModifySocket(int sysno) { - switch (sysno) { -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_accept: - case __NR_accept4: - case __NR_bind: - case __NR_connect: - case __NR_socket: - case __NR_listen: - return true; -#endif - default: - return false; - } -} - -#if defined(__i386__) || defined(__mips__) -// Big multiplexing system call for sockets. -bool SyscallSets::IsSocketCall(int sysno) { - switch (sysno) { - case __NR_socketcall: - return true; - default: - return false; - } -} -#endif - -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) -bool SyscallSets::IsNetworkSocketInformation(int sysno) { - switch (sysno) { - case __NR_getpeername: - case __NR_getsockname: - case __NR_getsockopt: - case __NR_setsockopt: - return true; - default: - return false; - } -} -#endif - -bool SyscallSets::IsAllowedAddressSpaceAccess(int sysno) { - switch (sysno) { - case __NR_brk: - case __NR_mlock: - case __NR_munlock: - case __NR_munmap: - return true; - case __NR_madvise: - case __NR_mincore: - case __NR_mlockall: -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_mmap: -#endif -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_mmap2: -#endif -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_modify_ldt: -#endif - case __NR_mprotect: - case __NR_mremap: - case __NR_msync: - case __NR_munlockall: - case __NR_readahead: - case __NR_remap_file_pages: -#if defined(__i386__) - case __NR_vm86: - case __NR_vm86old: -#endif - default: - return false; - } -} - -bool SyscallSets::IsAllowedGeneralIo(int sysno) { - switch (sysno) { - case __NR_lseek: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR__llseek: -#endif -#if !defined(__aarch64__) - case __NR_poll: -#endif - case __NR_ppoll: - case __NR_pselect6: - case __NR_read: - case __NR_readv: -#if defined(__arm__) || defined(__mips__) - case __NR_recv: -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_recvfrom: // Could specify source. - case __NR_recvmsg: // Could specify source. -#endif -#if defined(__i386__) || defined(__x86_64__) - case __NR_select: -#endif -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR__newselect: -#endif -#if defined(__arm__) || defined(__mips__) - case __NR_send: -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_sendmsg: // Could specify destination. - case __NR_sendto: // Could specify destination. -#endif - case __NR_write: - case __NR_writev: - return true; - case __NR_ioctl: // Can be very powerful. - case __NR_pread64: - case __NR_preadv: - case __NR_pwrite64: - case __NR_pwritev: - case __NR_recvmmsg: // Could specify source. - case __NR_sendfile: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_sendfile64: -#endif - case __NR_sendmmsg: // Could specify destination. - case __NR_splice: - case __NR_tee: - case __NR_vmsplice: - default: - return false; - } -} - -bool SyscallSets::IsPrctl(int sysno) { - switch (sysno) { -#if defined(__x86_64__) - case __NR_arch_prctl: -#endif - case __NR_prctl: - return true; - default: - return false; - } -} - -bool SyscallSets::IsSeccomp(int sysno) { - switch (sysno) { - case __NR_seccomp: - return true; - default: - return false; - } -} - -bool SyscallSets::IsAllowedBasicScheduler(int sysno) { - switch (sysno) { - case __NR_sched_yield: -#if !defined(__aarch64__) - case __NR_pause: -#endif - case __NR_nanosleep: - return true; - case __NR_getpriority: -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_nice: -#endif - case __NR_setpriority: - default: - return false; - } -} - -bool SyscallSets::IsAdminOperation(int sysno) { - switch (sysno) { -#if defined(__i386__) || defined(__arm__) || defined(__mips__) - case __NR_bdflush: -#endif - case __NR_kexec_load: - case __NR_reboot: - case __NR_setdomainname: - case __NR_sethostname: - case __NR_syslog: - return true; - default: - return false; - } -} - -bool SyscallSets::IsKernelModule(int sysno) { - switch (sysno) { -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_create_module: - case __NR_get_kernel_syms: // Should ENOSYS. - case __NR_query_module: -#endif - case __NR_delete_module: - case __NR_init_module: - case __NR_finit_module: - return true; - default: - return false; - } -} - -bool SyscallSets::IsGlobalFSViewChange(int sysno) { - switch (sysno) { - case __NR_pivot_root: - case __NR_chroot: - case __NR_sync: - return true; - default: - return false; - } -} - -bool SyscallSets::IsFsControl(int sysno) { - switch (sysno) { - case __NR_mount: - case __NR_nfsservctl: - case __NR_quotactl: - case __NR_swapoff: - case __NR_swapon: -#if defined(__i386__) || defined(__mips__) - case __NR_umount: -#endif - case __NR_umount2: - return true; - default: - return false; - } -} - -bool SyscallSets::IsNuma(int sysno) { - switch (sysno) { - case __NR_get_mempolicy: - case __NR_getcpu: - case __NR_mbind: -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_migrate_pages: -#endif - case __NR_move_pages: - case __NR_set_mempolicy: - return true; - default: - return false; - } -} - -bool SyscallSets::IsMessageQueue(int sysno) { - switch (sysno) { - case __NR_mq_getsetattr: - case __NR_mq_notify: - case __NR_mq_open: - case __NR_mq_timedreceive: - case __NR_mq_timedsend: - case __NR_mq_unlink: - return true; - default: - return false; - } -} - -bool SyscallSets::IsGlobalProcessEnvironment(int sysno) { - switch (sysno) { - case __NR_acct: // Privileged. -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__) - case __NR_getrlimit: -#endif -#if defined(__i386__) || defined(__arm__) - case __NR_ugetrlimit: -#endif -#if defined(__i386__) || defined(__mips__) - case __NR_ulimit: -#endif - case __NR_getrusage: - case __NR_personality: // Can change its personality as well. - case __NR_prlimit64: // Like setrlimit / getrlimit. - case __NR_setrlimit: - case __NR_times: - return true; - default: - return false; - } -} - -bool SyscallSets::IsDebug(int sysno) { - switch (sysno) { - case __NR_ptrace: - case __NR_process_vm_readv: - case __NR_process_vm_writev: - case __NR_kcmp: - return true; - default: - return false; - } -} - -bool SyscallSets::IsGlobalSystemStatus(int sysno) { - switch (sysno) { -#if !defined(__aarch64__) - case __NR__sysctl: - case __NR_sysfs: -#endif - case __NR_sysinfo: - case __NR_uname: -#if defined(__i386__) - case __NR_olduname: - case __NR_oldolduname: -#endif - return true; - default: - return false; - } -} - -bool SyscallSets::IsEventFd(int sysno) { - switch (sysno) { -#if !defined(__aarch64__) - case __NR_eventfd: -#endif - case __NR_eventfd2: - return true; - default: - return false; - } -} - -// Asynchronous I/O API. -bool SyscallSets::IsAsyncIo(int sysno) { - switch (sysno) { - case __NR_io_cancel: - case __NR_io_destroy: - case __NR_io_getevents: - case __NR_io_setup: - case __NR_io_submit: - return true; - default: - return false; - } -} - -bool SyscallSets::IsKeyManagement(int sysno) { - switch (sysno) { - case __NR_add_key: - case __NR_keyctl: - case __NR_request_key: - return true; - default: - return false; - } -} - -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -bool SyscallSets::IsSystemVSemaphores(int sysno) { - switch (sysno) { - case __NR_semctl: - case __NR_semget: - case __NR_semop: - case __NR_semtimedop: - return true; - default: - return false; - } -} -#endif - -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -// These give a lot of ambient authority and bypass the setuid sandbox. -bool SyscallSets::IsSystemVSharedMemory(int sysno) { - switch (sysno) { - case __NR_shmat: - case __NR_shmctl: - case __NR_shmdt: - case __NR_shmget: - return true; - default: - return false; - } -} -#endif - -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -bool SyscallSets::IsSystemVMessageQueue(int sysno) { - switch (sysno) { - case __NR_msgctl: - case __NR_msgget: - case __NR_msgrcv: - case __NR_msgsnd: - return true; - default: - return false; - } -} -#endif - -#if defined(__i386__) || defined(__mips__) -// Big system V multiplexing system call. -bool SyscallSets::IsSystemVIpc(int sysno) { - switch (sysno) { - case __NR_ipc: - return true; - default: - return false; - } -} -#endif - -bool SyscallSets::IsAnySystemV(int sysno) { -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) - return IsSystemVMessageQueue(sysno) || IsSystemVSemaphores(sysno) || - IsSystemVSharedMemory(sysno); -#elif defined(__i386__) || defined(__mips__) - return IsSystemVIpc(sysno); -#endif -} - -bool SyscallSets::IsAdvancedScheduler(int sysno) { - switch (sysno) { - case __NR_ioprio_get: // IO scheduler. - case __NR_ioprio_set: - case __NR_sched_get_priority_max: - case __NR_sched_get_priority_min: - case __NR_sched_getaffinity: - case __NR_sched_getattr: - case __NR_sched_getparam: - case __NR_sched_getscheduler: - case __NR_sched_rr_get_interval: - case __NR_sched_setaffinity: - case __NR_sched_setattr: - case __NR_sched_setparam: - case __NR_sched_setscheduler: - return true; - default: - return false; - } -} - -bool SyscallSets::IsInotify(int sysno) { - switch (sysno) { - case __NR_inotify_add_watch: -#if !defined(__aarch64__) - case __NR_inotify_init: -#endif - case __NR_inotify_init1: - case __NR_inotify_rm_watch: - return true; - default: - return false; - } -} - -bool SyscallSets::IsFaNotify(int sysno) { - switch (sysno) { - case __NR_fanotify_init: - case __NR_fanotify_mark: - return true; - default: - return false; - } -} - -bool SyscallSets::IsTimer(int sysno) { - switch (sysno) { - case __NR_getitimer: -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_alarm: -#endif - case __NR_setitimer: - return true; - default: - return false; - } -} - -bool SyscallSets::IsAdvancedTimer(int sysno) { - switch (sysno) { - case __NR_timer_create: - case __NR_timer_delete: - case __NR_timer_getoverrun: - case __NR_timer_gettime: - case __NR_timer_settime: - case __NR_timerfd_create: - case __NR_timerfd_gettime: - case __NR_timerfd_settime: - return true; - default: - return false; - } -} - -bool SyscallSets::IsExtendedAttributes(int sysno) { - switch (sysno) { - case __NR_fgetxattr: - case __NR_flistxattr: - case __NR_fremovexattr: - case __NR_fsetxattr: - case __NR_getxattr: - case __NR_lgetxattr: - case __NR_listxattr: - case __NR_llistxattr: - case __NR_lremovexattr: - case __NR_lsetxattr: - case __NR_removexattr: - case __NR_setxattr: - return true; - default: - return false; - } -} - -// Various system calls that need to be researched. -// TODO(jln): classify this better. -bool SyscallSets::IsMisc(int sysno) { - switch (sysno) { -#if !defined(__mips__) - case __NR_getrandom: -#endif - case __NR_name_to_handle_at: - case __NR_open_by_handle_at: - case __NR_perf_event_open: - case __NR_syncfs: - case __NR_vhangup: -// The system calls below are not implemented. -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_afs_syscall: -#endif -#if defined(__i386__) || defined(__mips__) - case __NR_break: -#endif -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_getpmsg: -#endif -#if defined(__i386__) || defined(__mips__) - case __NR_gtty: - case __NR_idle: - case __NR_lock: - case __NR_mpx: - case __NR_prof: - case __NR_profil: -#endif -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - case __NR_putpmsg: -#endif -#if defined(__x86_64__) - case __NR_security: -#endif -#if defined(__i386__) || defined(__mips__) - case __NR_stty: -#endif -#if defined(__x86_64__) - case __NR_tuxcall: -#endif -#if !defined(__aarch64__) - case __NR_vserver: -#endif - return true; - default: - return false; - } -} - -#if defined(__arm__) -bool SyscallSets::IsArmPciConfig(int sysno) { - switch (sysno) { - case __NR_pciconfig_iobase: - case __NR_pciconfig_read: - case __NR_pciconfig_write: - return true; - default: - return false; - } -} - -bool SyscallSets::IsArmPrivate(int sysno) { - switch (sysno) { - case __ARM_NR_breakpoint: - case __ARM_NR_cacheflush: - case __ARM_NR_set_tls: - case __ARM_NR_usr26: - case __ARM_NR_usr32: - return true; - default: - return false; - } -} -#endif // defined(__arm__) - -#if defined(__mips__) -bool SyscallSets::IsMipsPrivate(int sysno) { - switch (sysno) { - case __NR_cacheflush: - case __NR_cachectl: - return true; - default: - return false; - } -} - -bool SyscallSets::IsMipsMisc(int sysno) { - switch (sysno) { - case __NR_sysmips: - case __NR_unused150: - return true; - default: - return false; - } -} -#endif // defined(__mips__) -} // namespace sandbox. diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.h b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.h deleted file mode 100644 index 5ba6335a95..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2013 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_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_SETS_H_ -#define SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_SETS_H_ - -#include "base/macros.h" -#include "build/build_config.h" -#include "sandbox/sandbox_export.h" - -// These are helpers to build seccomp-bpf policies, i.e. policies for a -// sandbox that reduces the Linux kernel's attack surface. Given their -// nature, they don't have any clear semantics and are completely -// "implementation-defined". - -namespace sandbox { - -class SANDBOX_EXPORT SyscallSets { - public: - static bool IsKill(int sysno); - static bool IsAllowedGettime(int sysno); - static bool IsCurrentDirectory(int sysno); - static bool IsUmask(int sysno); - // System calls that directly access the file system. They might acquire - // a new file descriptor or otherwise perform an operation directly - // via a path. - static bool IsFileSystem(int sysno); - static bool IsAllowedFileSystemAccessViaFd(int sysno); - static bool IsDeniedFileSystemAccessViaFd(int sysno); - static bool IsGetSimpleId(int sysno); - static bool IsProcessPrivilegeChange(int sysno); - static bool IsProcessGroupOrSession(int sysno); - static bool IsAllowedSignalHandling(int sysno); - static bool IsAllowedOperationOnFd(int sysno); - static bool IsKernelInternalApi(int sysno); - // This should be thought through in conjunction with IsFutex(). - static bool IsAllowedProcessStartOrDeath(int sysno); - // It's difficult to restrict those, but there is attack surface here. - static bool IsAllowedFutex(int sysno); - static bool IsAllowedEpoll(int sysno); - static bool IsAllowedGetOrModifySocket(int sysno); - static bool IsDeniedGetOrModifySocket(int sysno); - -#if defined(__i386__) || defined(__mips__) - // Big multiplexing system call for sockets. - static bool IsSocketCall(int sysno); -#endif - -#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \ - defined(__aarch64__) - static bool IsNetworkSocketInformation(int sysno); -#endif - - static bool IsAllowedAddressSpaceAccess(int sysno); - static bool IsAllowedGeneralIo(int sysno); - static bool IsPrctl(int sysno); - static bool IsSeccomp(int sysno); - static bool IsAllowedBasicScheduler(int sysno); - static bool IsAdminOperation(int sysno); - static bool IsKernelModule(int sysno); - static bool IsGlobalFSViewChange(int sysno); - static bool IsFsControl(int sysno); - static bool IsNuma(int sysno); - static bool IsMessageQueue(int sysno); - static bool IsGlobalProcessEnvironment(int sysno); - static bool IsDebug(int sysno); - static bool IsGlobalSystemStatus(int sysno); - static bool IsEventFd(int sysno); - // Asynchronous I/O API. - static bool IsAsyncIo(int sysno); - static bool IsKeyManagement(int sysno); -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) - static bool IsSystemVSemaphores(int sysno); -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) - // These give a lot of ambient authority and bypass the setuid sandbox. - static bool IsSystemVSharedMemory(int sysno); -#endif - -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) - static bool IsSystemVMessageQueue(int sysno); -#endif - -#if defined(__i386__) || defined(__mips__) - // Big system V multiplexing system call. - static bool IsSystemVIpc(int sysno); -#endif - - static bool IsAnySystemV(int sysno); - static bool IsAdvancedScheduler(int sysno); - static bool IsInotify(int sysno); - static bool IsFaNotify(int sysno); - static bool IsTimer(int sysno); - static bool IsAdvancedTimer(int sysno); - static bool IsExtendedAttributes(int sysno); - static bool IsMisc(int sysno); -#if defined(__arm__) - static bool IsArmPciConfig(int sysno); - static bool IsArmPrivate(int sysno); -#endif // defined(__arm__) -#if defined(__mips__) - static bool IsMipsPrivate(int sysno); - static bool IsMipsMisc(int sysno); -#endif // defined(__mips__) - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(SyscallSets); -}; - -} // namespace sandbox. - -#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_SETS_H_ diff --git a/sandbox/linux/seccomp-bpf/DEPS b/sandbox/linux/seccomp-bpf/DEPS deleted file mode 100644 index 149c463b06..0000000000 --- a/sandbox/linux/seccomp-bpf/DEPS +++ /dev/null @@ -1,5 +0,0 @@ -include_rules = [ - "+sandbox/linux/bpf_dsl", - "+sandbox/linux/services", - "+sandbox/linux/system_headers", -] diff --git a/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h deleted file mode 100644 index a4315ba3c2..0000000000 --- a/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 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_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_ -#define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_ - -#include <memory> - -#include "base/macros.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h" - -namespace sandbox { - -// This templated class allows building a BPFTesterDelegate from a -// deprecated-style BPF policy (that is a SyscallEvaluator function pointer, -// instead of a SandboxBPFPolicy class), specified in |policy_function| and a -// function pointer to a test in |test_function|. -// This allows both the policy and the test function to take a pointer to an -// object of type "Aux" as a parameter. This is used to implement the BPF_TEST -// macro and should generally not be used directly. -template <class Policy, class Aux> -class BPFTesterCompatibilityDelegate : public BPFTesterDelegate { - public: - typedef void (*TestFunction)(Aux*); - - explicit BPFTesterCompatibilityDelegate(TestFunction test_function) - : aux_(), test_function_(test_function) {} - - ~BPFTesterCompatibilityDelegate() override {} - - std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override { - // The current method is guaranteed to only run in the child process - // running the test. In this process, the current object is guaranteed - // to live forever. So it's ok to pass aux_pointer_for_policy_ to - // the policy, which could in turn pass it to the kernel via Trap(). - return std::unique_ptr<bpf_dsl::Policy>(new Policy(&aux_)); - } - - void RunTestFunction() override { - // Run the actual test. - // The current object is guaranteed to live forever in the child process - // where this will run. - test_function_(&aux_); - } - - private: - Aux aux_; - TestFunction test_function_; - - DISALLOW_COPY_AND_ASSIGN(BPFTesterCompatibilityDelegate); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_ diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.h b/sandbox/linux/seccomp-bpf/bpf_tests.h deleted file mode 100644 index 8b2b12afd8..0000000000 --- a/sandbox/linux/seccomp-bpf/bpf_tests.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SECCOMP_BPF_BPF_TESTS_H__ -#define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTS_H__ - -#include <memory> - -#include "base/logging.h" -#include "base/macros.h" -#include "build/build_config.h" -#include "sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h" -#include "sandbox/linux/tests/unit_tests.h" - -namespace sandbox { - -// BPF_TEST_C() is a special version of SANDBOX_TEST(). It runs a test function -// in a sub-process, under a seccomp-bpf policy specified in -// |bpf_policy_class_name| without failing on configurations that are allowed -// to not support seccomp-bpf in their kernels. -// This is the preferred format for new BPF tests. |bpf_policy_class_name| is a -// class name (which will be default-constructed) that implements the -// Policy interface. -// The test function's body can simply follow. Test functions should use -// the BPF_ASSERT macros defined below, not GTEST's macros. The use of -// CHECK* macros is supported but less robust. -#define BPF_TEST_C(test_case_name, test_name, bpf_policy_class_name) \ - BPF_DEATH_TEST_C( \ - test_case_name, test_name, DEATH_SUCCESS(), bpf_policy_class_name) - -// Identical to BPF_TEST_C but allows to specify the nature of death. -#define BPF_DEATH_TEST_C( \ - test_case_name, test_name, death, bpf_policy_class_name) \ - void BPF_TEST_C_##test_name(); \ - TEST(test_case_name, DISABLE_ON_TSAN(test_name)) { \ - sandbox::SandboxBPFTestRunner bpf_test_runner( \ - new sandbox::BPFTesterSimpleDelegate<bpf_policy_class_name>( \ - BPF_TEST_C_##test_name)); \ - sandbox::UnitTests::RunTestInProcess(&bpf_test_runner, death); \ - } \ - void BPF_TEST_C_##test_name() - -// This form of BPF_TEST is a little verbose and should be reserved for complex -// tests where a lot of control is required. -// |bpf_tester_delegate_class| must be a classname implementing the -// BPFTesterDelegate interface. -#define BPF_TEST_D(test_case_name, test_name, bpf_tester_delegate_class) \ - BPF_DEATH_TEST_D( \ - test_case_name, test_name, DEATH_SUCCESS(), bpf_tester_delegate_class) - -// Identical to BPF_TEST_D but allows to specify the nature of death. -#define BPF_DEATH_TEST_D( \ - test_case_name, test_name, death, bpf_tester_delegate_class) \ - TEST(test_case_name, DISABLE_ON_TSAN(test_name)) { \ - sandbox::SandboxBPFTestRunner bpf_test_runner( \ - new bpf_tester_delegate_class()); \ - sandbox::UnitTests::RunTestInProcess(&bpf_test_runner, death); \ - } - -// Assertions are handled exactly the same as with a normal SANDBOX_TEST() -#define BPF_ASSERT SANDBOX_ASSERT -#define BPF_ASSERT_EQ(x, y) BPF_ASSERT((x) == (y)) -#define BPF_ASSERT_NE(x, y) BPF_ASSERT((x) != (y)) -#define BPF_ASSERT_LT(x, y) BPF_ASSERT((x) < (y)) -#define BPF_ASSERT_GT(x, y) BPF_ASSERT((x) > (y)) -#define BPF_ASSERT_LE(x, y) BPF_ASSERT((x) <= (y)) -#define BPF_ASSERT_GE(x, y) BPF_ASSERT((x) >= (y)) - -// This form of BPF_TEST is now discouraged (but still allowed) in favor of -// BPF_TEST_D and BPF_TEST_C. -// The |policy| parameter should be a Policy subclass. -// BPF_TEST() takes a C++ data type as an fourth parameter. A variable -// of this type will be allocated and a pointer to it will be -// available within the test function as "BPF_AUX". The pointer will -// also be passed as an argument to the policy's constructor. Policies -// would typically use it as an argument to SandboxBPF::Trap(), if -// they want to communicate data between the BPF_TEST() and a Trap() -// function. The life-time of this object is the same as the life-time -// of the process running under the seccomp-bpf policy. -// |aux| must not be void. -#define BPF_TEST(test_case_name, test_name, policy, aux) \ - BPF_DEATH_TEST(test_case_name, test_name, DEATH_SUCCESS(), policy, aux) - -// A BPF_DEATH_TEST is just the same as a BPF_TEST, but it assumes that the -// test will fail with a particular known error condition. Use the DEATH_XXX() -// macros from unit_tests.h to specify the expected error condition. -#define BPF_DEATH_TEST(test_case_name, test_name, death, policy, aux) \ - void BPF_TEST_##test_name(aux* BPF_AUX); \ - TEST(test_case_name, DISABLE_ON_TSAN(test_name)) { \ - sandbox::SandboxBPFTestRunner bpf_test_runner( \ - new sandbox::BPFTesterCompatibilityDelegate<policy, aux>( \ - BPF_TEST_##test_name)); \ - sandbox::UnitTests::RunTestInProcess(&bpf_test_runner, death); \ - } \ - void BPF_TEST_##test_name(aux* BPF_AUX) - -// This class takes a simple function pointer as a constructor parameter and a -// class name as a template parameter to implement the BPFTesterDelegate -// interface which can be used to build BPF unittests with -// the SandboxBPFTestRunner class. -template <class PolicyClass> -class BPFTesterSimpleDelegate : public BPFTesterDelegate { - public: - explicit BPFTesterSimpleDelegate(void (*test_function)(void)) - : test_function_(test_function) {} - ~BPFTesterSimpleDelegate() override {} - - std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override { - return std::unique_ptr<bpf_dsl::Policy>(new PolicyClass()); - } - void RunTestFunction() override { - DCHECK(test_function_); - test_function_(); - } - - private: - void (*test_function_)(void); - DISALLOW_COPY_AND_ASSIGN(BPFTesterSimpleDelegate); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTS_H__ diff --git a/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc b/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc deleted file mode 100644 index c16cd72dd8..0000000000 --- a/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2014 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/linux/seccomp-bpf/bpf_tests.h" - -#include <errno.h> -#include <sys/ptrace.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include <memory> - -#include "base/logging.h" -#include "base/macros.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -using sandbox::bpf_dsl::Allow; -using sandbox::bpf_dsl::Error; -using sandbox::bpf_dsl::ResultExpr; - -namespace sandbox { - -namespace { - -class FourtyTwo { - public: - static const int kMagicValue = 42; - FourtyTwo() : value_(kMagicValue) {} - int value() { return value_; } - - private: - int value_; - DISALLOW_COPY_AND_ASSIGN(FourtyTwo); -}; - -class EmptyClassTakingPolicy : public bpf_dsl::Policy { - public: - explicit EmptyClassTakingPolicy(FourtyTwo* fourty_two) { - BPF_ASSERT(fourty_two); - BPF_ASSERT(FourtyTwo::kMagicValue == fourty_two->value()); - } - ~EmptyClassTakingPolicy() override {} - - ResultExpr EvaluateSyscall(int sysno) const override { - DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); - return Allow(); - } -}; - -BPF_TEST(BPFTest, - BPFAUXPointsToClass, - EmptyClassTakingPolicy, - FourtyTwo /* *BPF_AUX */) { - // BPF_AUX should point to an instance of FourtyTwo. - BPF_ASSERT(BPF_AUX); - BPF_ASSERT(FourtyTwo::kMagicValue == BPF_AUX->value()); -} - -void DummyTestFunction(FourtyTwo *fourty_two) { -} - -TEST(BPFTest, BPFTesterCompatibilityDelegateLeakTest) { - // Don't do anything, simply gives dynamic tools an opportunity to detect - // leaks. - { - BPFTesterCompatibilityDelegate<EmptyClassTakingPolicy, FourtyTwo> - simple_delegate(DummyTestFunction); - } - { - // Test polymorphism. - std::unique_ptr<BPFTesterDelegate> simple_delegate( - new BPFTesterCompatibilityDelegate<EmptyClassTakingPolicy, FourtyTwo>( - DummyTestFunction)); - } -} - -class EnosysPtracePolicy : public bpf_dsl::Policy { - public: - EnosysPtracePolicy() { my_pid_ = sys_getpid(); } - ~EnosysPtracePolicy() override { - // Policies should be able to bind with the process on which they are - // created. They should never be created in a parent process. - BPF_ASSERT_EQ(my_pid_, sys_getpid()); - } - - ResultExpr EvaluateSyscall(int system_call_number) const override { - CHECK(SandboxBPF::IsValidSyscallNumber(system_call_number)); - if (system_call_number == __NR_ptrace) { - // The EvaluateSyscall function should run in the process that created - // the current object. - BPF_ASSERT_EQ(my_pid_, sys_getpid()); - return Error(ENOSYS); - } else { - return Allow(); - } - } - - private: - pid_t my_pid_; - DISALLOW_COPY_AND_ASSIGN(EnosysPtracePolicy); -}; - -class BasicBPFTesterDelegate : public BPFTesterDelegate { - public: - BasicBPFTesterDelegate() {} - ~BasicBPFTesterDelegate() override {} - - std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override { - return std::unique_ptr<bpf_dsl::Policy>(new EnosysPtracePolicy()); - } - void RunTestFunction() override { - errno = 0; - int ret = ptrace(PTRACE_TRACEME, -1, NULL, NULL); - BPF_ASSERT(-1 == ret); - BPF_ASSERT(ENOSYS == errno); - } - - private: - DISALLOW_COPY_AND_ASSIGN(BasicBPFTesterDelegate); -}; - -// This is the most powerful and complex way to create a BPF test, but it -// requires a full class definition (BasicBPFTesterDelegate). -BPF_TEST_D(BPFTest, BPFTestWithDelegateClass, BasicBPFTesterDelegate); - -// This is the simplest form of BPF tests. -BPF_TEST_C(BPFTest, BPFTestWithInlineTest, EnosysPtracePolicy) { - errno = 0; - int ret = ptrace(PTRACE_TRACEME, -1, NULL, NULL); - BPF_ASSERT(-1 == ret); - BPF_ASSERT(ENOSYS == errno); -} - -const char kHelloMessage[] = "Hello"; - -BPF_DEATH_TEST_C(BPFTest, - BPFDeathTestWithInlineTest, - DEATH_MESSAGE(kHelloMessage), - EnosysPtracePolicy) { - LOG(ERROR) << kHelloMessage; - _exit(1); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf/die.cc b/sandbox/linux/seccomp-bpf/die.cc deleted file mode 100644 index 3baf1f13d9..0000000000 --- a/sandbox/linux/seccomp-bpf/die.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2012 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/linux/seccomp-bpf/die.h" - -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <sys/prctl.h> -#include <sys/syscall.h> -#include <unistd.h> - -#include <string> - -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_signal.h" - -namespace sandbox { - -void Die::ExitGroup() { - // exit_group() should exit our program. After all, it is defined as a - // function that doesn't return. But things can theoretically go wrong. - // Especially, since we are dealing with system call filters. Continuing - // execution would be very bad in most cases where ExitGroup() gets called. - // So, we'll try a few other strategies too. - Syscall::Call(__NR_exit_group, 1); - - // We have no idea what our run-time environment looks like. So, signal - // handlers might or might not do the right thing. Try to reset settings - // to a defined state; but we have not way to verify whether we actually - // succeeded in doing so. Nonetheless, triggering a fatal signal could help - // us terminate. - struct sigaction sa = {}; - sa.sa_handler = LINUX_SIG_DFL; - sa.sa_flags = LINUX_SA_RESTART; - sys_sigaction(LINUX_SIGSEGV, &sa, nullptr); - Syscall::Call(__NR_prctl, PR_SET_DUMPABLE, (void*)0, (void*)0, (void*)0); - if (*(volatile char*)0) { - } - - // If there is no way for us to ask for the program to exit, the next - // best thing we can do is to loop indefinitely. Maybe, somebody will notice - // and file a bug... - // We in fact retry the system call inside of our loop so that it will - // stand out when somebody tries to diagnose the problem by using "strace". - for (;;) { - Syscall::Call(__NR_exit_group, 1); - } -} - -void Die::SandboxDie(const char* msg, const char* file, int line) { - if (simple_exit_) { - LogToStderr(msg, file, line); - } else { - logging::LogMessage(file, line, logging::LOG_FATAL).stream() << msg; - } - ExitGroup(); -} - -void Die::RawSandboxDie(const char* msg) { - if (!msg) - msg = ""; - RAW_LOG(FATAL, msg); - ExitGroup(); -} - -void Die::SandboxInfo(const char* msg, const char* file, int line) { - if (!suppress_info_) { - logging::LogMessage(file, line, logging::LOG_INFO).stream() << msg; - } -} - -void Die::LogToStderr(const char* msg, const char* file, int line) { - if (msg) { - char buf[40]; - snprintf(buf, sizeof(buf), "%d", line); - std::string s = std::string(file) + ":" + buf + ":" + msg + "\n"; - - // No need to loop. Short write()s are unlikely and if they happen we - // probably prefer them over a loop that blocks. - ignore_result( - HANDLE_EINTR(Syscall::Call(__NR_write, 2, s.c_str(), s.length()))); - } -} - -bool Die::simple_exit_ = false; -bool Die::suppress_info_ = false; - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf/die.h b/sandbox/linux/seccomp-bpf/die.h deleted file mode 100644 index b3f3f72c2f..0000000000 --- a/sandbox/linux/seccomp-bpf/die.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SECCOMP_BPF_DIE_H__ -#define SANDBOX_LINUX_SECCOMP_BPF_DIE_H__ - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// This is the main API for using this file. Prints a error message and -// exits with a fatal error. This is not async-signal safe. -#define SANDBOX_DIE(m) sandbox::Die::SandboxDie(m, __FILE__, __LINE__) - -// An async signal safe version of the same API. Won't print the filename -// and line numbers. -#define RAW_SANDBOX_DIE(m) sandbox::Die::RawSandboxDie(m) - -// Adds an informational message to the log file or stderr as appropriate. -#define SANDBOX_INFO(m) sandbox::Die::SandboxInfo(m, __FILE__, __LINE__) - -class SANDBOX_EXPORT Die { - public: - // Terminate the program, even if the current sandbox policy prevents some - // of the more commonly used functions used for exiting. - // Most users would want to call SANDBOX_DIE() instead, as it logs extra - // information. But calling ExitGroup() is correct and in some rare cases - // preferable. So, we make it part of the public API. - static void ExitGroup() __attribute__((noreturn)); - - // This method gets called by SANDBOX_DIE(). There is normally no reason - // to call it directly unless you are defining your own exiting macro. - static void SandboxDie(const char* msg, const char* file, int line) - __attribute__((noreturn)); - - static void RawSandboxDie(const char* msg) __attribute__((noreturn)); - - // This method gets called by SANDBOX_INFO(). There is normally no reason - // to call it directly unless you are defining your own logging macro. - static void SandboxInfo(const char* msg, const char* file, int line); - - // Writes a message to stderr. Used as a fall-back choice, if we don't have - // any other way to report an error. - static void LogToStderr(const char* msg, const char* file, int line); - - // We generally want to run all exit handlers. This means, on SANDBOX_DIE() - // we should be calling LOG(FATAL). But there are some situations where - // we just need to print a message and then terminate. This would typically - // happen in cases where we consume the error message internally (e.g. in - // unit tests or in the supportsSeccompSandbox() method). - static void EnableSimpleExit() { simple_exit_ = true; } - - // Sometimes we need to disable all informational messages (e.g. from within - // unittests). - static void SuppressInfoMessages(bool flag) { suppress_info_ = flag; } - - private: - static bool simple_exit_; - static bool suppress_info_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(Die); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SECCOMP_BPF_DIE_H__ diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc deleted file mode 100644 index 4d8d436713..0000000000 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (c) 2012 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/linux/seccomp-bpf/sandbox_bpf.h" - -#include <errno.h> -#include <stdint.h> -#include <sys/prctl.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/compiler_specific.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/third_party/valgrind/valgrind.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/bpf_dsl/policy_compiler.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/bpf_dsl/syscall_set.h" -#include "sandbox/linux/seccomp-bpf/die.h" -#include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/seccomp-bpf/trap.h" -#include "sandbox/linux/services/proc_util.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/services/thread_helpers.h" -#include "sandbox/linux/system_headers/linux_filter.h" -#include "sandbox/linux/system_headers/linux_seccomp.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -namespace sandbox { - -namespace { - -bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; } - -bool IsSingleThreaded(int proc_fd) { - return ThreadHelpers::IsSingleThreaded(proc_fd); -} - -// Check if the kernel supports seccomp-filter (a.k.a. seccomp mode 2) via -// prctl(). -bool KernelSupportsSeccompBPF() { - errno = 0; - const int rv = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, nullptr); - - if (rv == -1 && EFAULT == errno) { - return true; - } - return false; -} - -// LG introduced a buggy syscall, sys_set_media_ext, with the same number as -// seccomp. Return true if the current kernel has this buggy syscall. -// -// We want this to work with upcoming versions of seccomp, so we pass bogus -// flags that are unlikely to ever be used by the kernel. A normal kernel would -// return -EINVAL, but a buggy LG kernel would return 1. -bool KernelHasLGBug() { -#if defined(OS_ANDROID) - // sys_set_media will see this as NULL, which should be a safe (non-crashing) - // way to invoke it. A genuine seccomp syscall will see it as - // SECCOMP_SET_MODE_STRICT. - const unsigned int operation = 0; - // Chosen by fair dice roll. Guaranteed to be random. - const unsigned int flags = 0xf7a46a5c; - const int rv = sys_seccomp(operation, flags, nullptr); - // A genuine kernel would return -EINVAL (which would set rv to -1 and errno - // to EINVAL), or at the very least return some kind of error (which would - // set rv to -1). Any other behavior indicates that whatever code received - // our syscall was not the real seccomp. - if (rv != -1) { - return true; - } -#endif // defined(OS_ANDROID) - - return false; -} - -// Check if the kernel supports seccomp-filter via the seccomp system call -// and the TSYNC feature to enable seccomp on all threads. -bool KernelSupportsSeccompTsync() { - if (KernelHasLGBug()) { - return false; - } - - errno = 0; - const int rv = - sys_seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, nullptr); - - if (rv == -1 && errno == EFAULT) { - return true; - } else { - // TODO(jln): turn these into DCHECK after 417888 is considered fixed. - CHECK_EQ(-1, rv); - CHECK(ENOSYS == errno || EINVAL == errno); - return false; - } -} - -uint64_t EscapePC() { - intptr_t rv = Syscall::Call(-1); - if (rv == -1 && errno == ENOSYS) { - return 0; - } - return static_cast<uint64_t>(static_cast<uintptr_t>(rv)); -} - -intptr_t SandboxPanicTrap(const struct arch_seccomp_data&, void* aux) { - SANDBOX_DIE(static_cast<const char*>(aux)); -} - -bpf_dsl::ResultExpr SandboxPanic(const char* error) { - return bpf_dsl::Trap(SandboxPanicTrap, error); -} - -} // namespace - -SandboxBPF::SandboxBPF(bpf_dsl::Policy* policy) - : proc_fd_(), sandbox_has_started_(false), policy_(policy) { -} - -SandboxBPF::~SandboxBPF() { -} - -// static -bool SandboxBPF::SupportsSeccompSandbox(SeccompLevel level) { - // Never pretend to support seccomp with Valgrind, as it - // throws the tool off. - if (IsRunningOnValgrind()) { - return false; - } - - switch (level) { - case SeccompLevel::SINGLE_THREADED: - return KernelSupportsSeccompBPF(); - case SeccompLevel::MULTI_THREADED: - return KernelSupportsSeccompTsync(); - } - NOTREACHED(); - return false; -} - -bool SandboxBPF::StartSandbox(SeccompLevel seccomp_level) { - DCHECK(policy_); - CHECK(seccomp_level == SeccompLevel::SINGLE_THREADED || - seccomp_level == SeccompLevel::MULTI_THREADED); - - if (sandbox_has_started_) { - SANDBOX_DIE( - "Cannot repeatedly start sandbox. Create a separate Sandbox " - "object instead."); - return false; - } - - if (!proc_fd_.is_valid()) { - SetProcFd(ProcUtil::OpenProc()); - } - - const bool supports_tsync = KernelSupportsSeccompTsync(); - - if (seccomp_level == SeccompLevel::SINGLE_THREADED) { - // Wait for /proc/self/task/ to update if needed and assert the - // process is single threaded. - ThreadHelpers::AssertSingleThreaded(proc_fd_.get()); - } else if (seccomp_level == SeccompLevel::MULTI_THREADED) { - if (IsSingleThreaded(proc_fd_.get())) { - SANDBOX_DIE("Cannot start sandbox; " - "process may be single-threaded when reported as not"); - return false; - } - if (!supports_tsync) { - SANDBOX_DIE("Cannot start sandbox; kernel does not support synchronizing " - "filters for a threadgroup"); - return false; - } - } - - // We no longer need access to any files in /proc. We want to do this - // before installing the filters, just in case that our policy denies - // close(). - if (proc_fd_.is_valid()) { - proc_fd_.reset(); - } - - // Install the filters. - InstallFilter(supports_tsync || - seccomp_level == SeccompLevel::MULTI_THREADED); - - return true; -} - -void SandboxBPF::SetProcFd(base::ScopedFD proc_fd) { - proc_fd_.swap(proc_fd); -} - -// static -bool SandboxBPF::IsValidSyscallNumber(int sysnum) { - return SyscallSet::IsValid(sysnum); -} - -// static -bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) { - return bpf_dsl::PolicyCompiler::IsRequiredForUnsafeTrap(sysno); -} - -// static -intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { - return Syscall::Call( - args.nr, static_cast<intptr_t>(args.args[0]), - static_cast<intptr_t>(args.args[1]), static_cast<intptr_t>(args.args[2]), - static_cast<intptr_t>(args.args[3]), static_cast<intptr_t>(args.args[4]), - static_cast<intptr_t>(args.args[5])); -} - -CodeGen::Program SandboxBPF::AssembleFilter() { - DCHECK(policy_); - - bpf_dsl::PolicyCompiler compiler(policy_.get(), Trap::Registry()); - if (Trap::SandboxDebuggingAllowedByUser()) { - compiler.DangerousSetEscapePC(EscapePC()); - } - compiler.SetPanicFunc(SandboxPanic); - return compiler.Compile(); -} - -void SandboxBPF::InstallFilter(bool must_sync_threads) { - // We want to be very careful in not imposing any requirements on the - // policies that are set with SetSandboxPolicy(). This means, as soon as - // the sandbox is active, we shouldn't be relying on libraries that could - // be making system calls. This, for example, means we should avoid - // using the heap and we should avoid using STL functions. - // Temporarily copy the contents of the "program" vector into a - // stack-allocated array; and then explicitly destroy that object. - // This makes sure we don't ex- or implicitly call new/delete after we - // installed the BPF filter program in the kernel. Depending on the - // system memory allocator that is in effect, these operators can result - // in system calls to things like munmap() or brk(). - CodeGen::Program program = AssembleFilter(); - - struct sock_filter bpf[program.size()]; - const struct sock_fprog prog = {static_cast<unsigned short>(program.size()), - bpf}; - memcpy(bpf, &program[0], sizeof(bpf)); - CodeGen::Program().swap(program); // vector swap trick - - // Make an attempt to release memory that is no longer needed here, rather - // than in the destructor. Try to avoid as much as possible to presume of - // what will be possible to do in the new (sandboxed) execution environment. - policy_.reset(); - - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - SANDBOX_DIE("Kernel refuses to enable no-new-privs"); - } - - // Install BPF filter program. If the thread state indicates multi-threading - // support, then the kernel hass the seccomp system call. Otherwise, fall - // back on prctl, which requires the process to be single-threaded. - if (must_sync_threads) { - int rv = - sys_seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, &prog); - if (rv) { - SANDBOX_DIE( - "Kernel refuses to turn on and synchronize threads for BPF filters"); - } - } else { - if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { - SANDBOX_DIE("Kernel refuses to turn on BPF filters"); - } - } - - sandbox_has_started_ = true; -} - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h deleted file mode 100644 index 1637b26ea5..0000000000 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_ -#define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_ - -#include <stdint.h> - -#include <memory> - -#include "base/files/scoped_file.h" -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/codegen.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { -struct arch_seccomp_data; -namespace bpf_dsl { -class Policy; -} - -// This class can be used to apply a syscall sandboxing policy expressed in a -// bpf_dsl::Policy object to the current process. -// Syscall sandboxing policies get inherited by subprocesses and, once applied, -// can never be removed for the lifetime of the process. -class SANDBOX_EXPORT SandboxBPF { - public: - enum class SeccompLevel { - SINGLE_THREADED, - MULTI_THREADED, - }; - - // Ownership of |policy| is transfered here to the sandbox object. - // nullptr is allowed for unit tests. - explicit SandboxBPF(bpf_dsl::Policy* policy); - // NOTE: Setting a policy and starting the sandbox is a one-way operation. - // The kernel does not provide any option for unloading a loaded sandbox. The - // sandbox remains engaged even when the object is destructed. - ~SandboxBPF(); - - // Detect if the kernel supports the specified seccomp level. - // See StartSandbox() for a description of these. - static bool SupportsSeccompSandbox(SeccompLevel level); - - // This is the main public entry point. It sets up the resources needed by - // the sandbox, and enters Seccomp mode. - // The calling process must provide a |level| to tell the sandbox which type - // of kernel support it should engage. - // SINGLE_THREADED will only sandbox the calling thread. Since it would be a - // security risk, the sandbox will also check that the current process is - // single threaded and crash if it isn't the case. - // MULTI_THREADED requires more recent kernel support and allows to sandbox - // all the threads of the current process. Be mindful of potential races, - // with other threads using disallowed system calls either before or after - // the sandbox is engaged. - // - // It is possible to stack multiple sandboxes by creating separate "Sandbox" - // objects and calling "StartSandbox()" on each of them. Please note, that - // this requires special care, though, as newly stacked sandboxes can never - // relax restrictions imposed by earlier sandboxes. Furthermore, installing - // a new policy requires making system calls, that might already be - // disallowed. - // Finally, stacking does add more kernel overhead than having a single - // combined policy. So, it should only be used if there are no alternatives. - bool StartSandbox(SeccompLevel level) WARN_UNUSED_RESULT; - - // The sandbox needs to be able to access files in "/proc/self/". If - // this directory is not accessible when "StartSandbox()" gets called, the - // caller must provide an already opened file descriptor by calling - // "SetProcFd()". - // The sandbox becomes the new owner of this file descriptor and will - // close it when "StartSandbox()" executes or when the sandbox object - // disappears. - void SetProcFd(base::ScopedFD proc_fd); - - // Checks whether a particular system call number is valid on the current - // architecture. - static bool IsValidSyscallNumber(int sysnum); - - // UnsafeTraps require some syscalls to always be allowed. - // This helper function returns true for these calls. - static bool IsRequiredForUnsafeTrap(int sysno); - - // From within an UnsafeTrap() it is often useful to be able to execute - // the system call that triggered the trap. The ForwardSyscall() method - // makes this easy. It is more efficient than calling glibc's syscall() - // function, as it avoid the extra round-trip to the signal handler. And - // it automatically does the correct thing to report kernel-style error - // conditions, rather than setting errno. See the comments for TrapFnc for - // details. In other words, the return value from ForwardSyscall() is - // directly suitable as a return value for a trap handler. - static intptr_t ForwardSyscall(const struct arch_seccomp_data& args); - - private: - friend class SandboxBPFTestRunner; - - // Assembles a BPF filter program from the current policy. After calling this - // function, you must not call any other sandboxing function. - CodeGen::Program AssembleFilter(); - - // Assembles and installs a filter based on the policy that has previously - // been configured with SetSandboxPolicy(). - void InstallFilter(bool must_sync_threads); - - base::ScopedFD proc_fd_; - bool sandbox_has_started_; - std::unique_ptr<bpf_dsl::Policy> policy_; - - DISALLOW_COPY_AND_ASSIGN(SandboxBPF); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_ diff --git a/sandbox/linux/seccomp-bpf/syscall.cc b/sandbox/linux/seccomp-bpf/syscall.cc deleted file mode 100644 index 4d55936189..0000000000 --- a/sandbox/linux/seccomp-bpf/syscall.cc +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright (c) 2012 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/linux/seccomp-bpf/syscall.h" - -#include <errno.h> -#include <stdint.h> - -#include "base/logging.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" - -namespace sandbox { - -namespace { - -#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ - defined(ARCH_CPU_MIPS_FAMILY) -// Number that's not currently used by any Linux kernel ABIs. -const int kInvalidSyscallNumber = 0x351d3; -#else -#error Unrecognized architecture -#endif - -asm(// We need to be able to tell the kernel exactly where we made a - // system call. The C++ compiler likes to sometimes clone or - // inline code, which would inadvertently end up duplicating - // the entry point. - // "gcc" can suppress code duplication with suitable function - // attributes, but "clang" doesn't have this ability. - // The "clang" developer mailing list suggested that the correct - // and portable solution is a file-scope assembly block. - // N.B. We do mark our code as a proper function so that backtraces - // work correctly. But we make absolutely no attempt to use the - // ABI's calling conventions for passing arguments. We will only - // ever be called from assembly code and thus can pick more - // suitable calling conventions. -#if defined(__i386__) - ".text\n" - ".align 16, 0x90\n" - ".type SyscallAsm, @function\n" - "SyscallAsm:.cfi_startproc\n" - // Check if "%eax" is negative. If so, do not attempt to make a - // system call. Instead, compute the return address that is visible - // to the kernel after we execute "int $0x80". This address can be - // used as a marker that BPF code inspects. - "test %eax, %eax\n" - "jge 1f\n" - // Always, make sure that our code is position-independent, or - // address space randomization might not work on i386. This means, - // we can't use "lea", but instead have to rely on "call/pop". - "call 0f; .cfi_adjust_cfa_offset 4\n" - "0:pop %eax; .cfi_adjust_cfa_offset -4\n" - "addl $2f-0b, %eax\n" - "ret\n" - // Save register that we don't want to clobber. On i386, we need to - // save relatively aggressively, as there are a couple or registers - // that are used internally (e.g. %ebx for position-independent - // code, and %ebp for the frame pointer), and as we need to keep at - // least a few registers available for the register allocator. - "1:push %esi; .cfi_adjust_cfa_offset 4; .cfi_rel_offset esi, 0\n" - "push %edi; .cfi_adjust_cfa_offset 4; .cfi_rel_offset edi, 0\n" - "push %ebx; .cfi_adjust_cfa_offset 4; .cfi_rel_offset ebx, 0\n" - "push %ebp; .cfi_adjust_cfa_offset 4; .cfi_rel_offset ebp, 0\n" - // Copy entries from the array holding the arguments into the - // correct CPU registers. - "movl 0(%edi), %ebx\n" - "movl 4(%edi), %ecx\n" - "movl 8(%edi), %edx\n" - "movl 12(%edi), %esi\n" - "movl 20(%edi), %ebp\n" - "movl 16(%edi), %edi\n" - // Enter the kernel. - "int $0x80\n" - // This is our "magic" return address that the BPF filter sees. - "2:" - // Restore any clobbered registers that we didn't declare to the - // compiler. - "pop %ebp; .cfi_restore ebp; .cfi_adjust_cfa_offset -4\n" - "pop %ebx; .cfi_restore ebx; .cfi_adjust_cfa_offset -4\n" - "pop %edi; .cfi_restore edi; .cfi_adjust_cfa_offset -4\n" - "pop %esi; .cfi_restore esi; .cfi_adjust_cfa_offset -4\n" - "ret\n" - ".cfi_endproc\n" - "9:.size SyscallAsm, 9b-SyscallAsm\n" -#elif defined(__x86_64__) - ".text\n" - ".align 16, 0x90\n" - ".type SyscallAsm, @function\n" - "SyscallAsm:.cfi_startproc\n" - // Check if "%rdi" is negative. If so, do not attempt to make a - // system call. Instead, compute the return address that is visible - // to the kernel after we execute "syscall". This address can be - // used as a marker that BPF code inspects. - "test %rdi, %rdi\n" - "jge 1f\n" - // Always make sure that our code is position-independent, or the - // linker will throw a hissy fit on x86-64. - "lea 2f(%rip), %rax\n" - "ret\n" - // Now we load the registers used to pass arguments to the system - // call: system call number in %rax, and arguments in %rdi, %rsi, - // %rdx, %r10, %r8, %r9. Note: These are all caller-save registers - // (only %rbx, %rbp, %rsp, and %r12-%r15 are callee-save), so no - // need to worry here about spilling registers or CFI directives. - "1:movq %rdi, %rax\n" - "movq 0(%rsi), %rdi\n" - "movq 16(%rsi), %rdx\n" - "movq 24(%rsi), %r10\n" - "movq 32(%rsi), %r8\n" - "movq 40(%rsi), %r9\n" - "movq 8(%rsi), %rsi\n" - // Enter the kernel. - "syscall\n" - // This is our "magic" return address that the BPF filter sees. - "2:ret\n" - ".cfi_endproc\n" - "9:.size SyscallAsm, 9b-SyscallAsm\n" -#elif defined(__arm__) - // Throughout this file, we use the same mode (ARM vs. thumb) - // that the C++ compiler uses. This means, when transfering control - // from C++ to assembly code, we do not need to switch modes (e.g. - // by using the "bx" instruction). It also means that our assembly - // code should not be invoked directly from code that lives in - // other compilation units, as we don't bother implementing thumb - // interworking. That's OK, as we don't make any of the assembly - // symbols public. They are all local to this file. - ".text\n" - ".align 2\n" - ".type SyscallAsm, %function\n" -#if defined(__thumb__) - ".thumb_func\n" -#else - ".arm\n" -#endif - "SyscallAsm:\n" -#if !defined(__native_client_nonsfi__) - // .fnstart and .fnend pseudo operations creates unwind table. - // It also creates a reference to the symbol __aeabi_unwind_cpp_pr0, which - // is not provided by PNaCl toolchain. Disable it. - ".fnstart\n" -#endif - "@ args = 0, pretend = 0, frame = 8\n" - "@ frame_needed = 1, uses_anonymous_args = 0\n" -#if defined(__thumb__) - ".cfi_startproc\n" - "push {r7, lr}\n" - ".save {r7, lr}\n" - ".cfi_offset 14, -4\n" - ".cfi_offset 7, -8\n" - ".cfi_def_cfa_offset 8\n" -#else - "stmfd sp!, {fp, lr}\n" - "add fp, sp, #4\n" -#endif - // Check if "r0" is negative. If so, do not attempt to make a - // system call. Instead, compute the return address that is visible - // to the kernel after we execute "swi 0". This address can be - // used as a marker that BPF code inspects. - "cmp r0, #0\n" - "bge 1f\n" - "adr r0, 2f\n" - "b 2f\n" - // We declared (almost) all clobbered registers to the compiler. On - // ARM there is no particular register pressure. So, we can go - // ahead and directly copy the entries from the arguments array - // into the appropriate CPU registers. - "1:ldr r5, [r6, #20]\n" - "ldr r4, [r6, #16]\n" - "ldr r3, [r6, #12]\n" - "ldr r2, [r6, #8]\n" - "ldr r1, [r6, #4]\n" - "mov r7, r0\n" - "ldr r0, [r6, #0]\n" - // Enter the kernel - "swi 0\n" -// Restore the frame pointer. Also restore the program counter from -// the link register; this makes us return to the caller. -#if defined(__thumb__) - "2:pop {r7, pc}\n" - ".cfi_endproc\n" -#else - "2:ldmfd sp!, {fp, pc}\n" -#endif -#if !defined(__native_client_nonsfi__) - // Do not use .fnstart and .fnend for PNaCl toolchain. See above comment, - // for more details. - ".fnend\n" -#endif - "9:.size SyscallAsm, 9b-SyscallAsm\n" -#elif defined(__mips__) - ".text\n" - ".option pic2\n" - ".align 4\n" - ".global SyscallAsm\n" - ".type SyscallAsm, @function\n" - "SyscallAsm:.ent SyscallAsm\n" - ".frame $sp, 40, $ra\n" - ".set push\n" - ".set noreorder\n" - ".cpload $t9\n" - "addiu $sp, $sp, -40\n" - "sw $ra, 36($sp)\n" - // Check if "v0" is negative. If so, do not attempt to make a - // system call. Instead, compute the return address that is visible - // to the kernel after we execute "syscall". This address can be - // used as a marker that BPF code inspects. - "bgez $v0, 1f\n" - " nop\n" - // This is equivalent to "la $v0, 2f". - // LA macro has to be avoided since LLVM-AS has issue with LA in PIC mode - // https://llvm.org/bugs/show_bug.cgi?id=27644 - "lw $v0, %got(2f)($gp)\n" - "addiu $v0, $v0, %lo(2f)\n" - "b 2f\n" - " nop\n" - // On MIPS first four arguments go to registers a0 - a3 and any - // argument after that goes to stack. We can go ahead and directly - // copy the entries from the arguments array into the appropriate - // CPU registers and on the stack. - "1:lw $a3, 28($a0)\n" - "lw $a2, 24($a0)\n" - "lw $a1, 20($a0)\n" - "lw $t0, 16($a0)\n" - "sw $a3, 28($sp)\n" - "sw $a2, 24($sp)\n" - "sw $a1, 20($sp)\n" - "sw $t0, 16($sp)\n" - "lw $a3, 12($a0)\n" - "lw $a2, 8($a0)\n" - "lw $a1, 4($a0)\n" - "lw $a0, 0($a0)\n" - // Enter the kernel - "syscall\n" - // This is our "magic" return address that the BPF filter sees. - // Restore the return address from the stack. - "2:lw $ra, 36($sp)\n" - "jr $ra\n" - " addiu $sp, $sp, 40\n" - ".set pop\n" - ".end SyscallAsm\n" - ".size SyscallAsm,.-SyscallAsm\n" -#elif defined(__aarch64__) - ".text\n" - ".align 2\n" - ".type SyscallAsm, %function\n" - "SyscallAsm:\n" - ".cfi_startproc\n" - "cmp x0, #0\n" - "b.ge 1f\n" - "adr x0,2f\n" - "b 2f\n" - "1:ldr x5, [x6, #40]\n" - "ldr x4, [x6, #32]\n" - "ldr x3, [x6, #24]\n" - "ldr x2, [x6, #16]\n" - "ldr x1, [x6, #8]\n" - "mov x8, x0\n" - "ldr x0, [x6, #0]\n" - // Enter the kernel - "svc 0\n" - "2:ret\n" - ".cfi_endproc\n" - ".size SyscallAsm, .-SyscallAsm\n" -#endif - ); // asm - -#if defined(__x86_64__) -extern "C" { -intptr_t SyscallAsm(intptr_t nr, const intptr_t args[6]); -} -#elif defined(__mips__) -extern "C" { -intptr_t SyscallAsm(intptr_t nr, const intptr_t args[8]); -} -#endif - -} // namespace - -intptr_t Syscall::InvalidCall() { - // Explicitly pass eight zero arguments just in case. - return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); -} - -intptr_t Syscall::Call(int nr, - intptr_t p0, - intptr_t p1, - intptr_t p2, - intptr_t p3, - intptr_t p4, - intptr_t p5, - intptr_t p6, - intptr_t p7) { - // We rely on "intptr_t" to be the exact size as a "void *". This is - // typically true, but just in case, we add a check. The language - // specification allows platforms some leeway in cases, where - // "sizeof(void *)" is not the same as "sizeof(void (*)())". We expect - // that this would only be an issue for IA64, which we are currently not - // planning on supporting. And it is even possible that this would work - // on IA64, but for lack of actual hardware, I cannot test. - static_assert(sizeof(void*) == sizeof(intptr_t), - "pointer types and intptr_t must be exactly the same size"); - - // TODO(nedeljko): Enable use of more than six parameters on architectures - // where that makes sense. -#if defined(__mips__) - const intptr_t args[8] = {p0, p1, p2, p3, p4, p5, p6, p7}; -#else - DCHECK_EQ(p6, 0) << " Support for syscalls with more than six arguments not " - "added for this architecture"; - DCHECK_EQ(p7, 0) << " Support for syscalls with more than six arguments not " - "added for this architecture"; - const intptr_t args[6] = {p0, p1, p2, p3, p4, p5}; -#endif // defined(__mips__) - -// Invoke our file-scope assembly code. The constraints have been picked -// carefully to match what the rest of the assembly code expects in input, -// output, and clobbered registers. -#if defined(__i386__) - intptr_t ret = nr; - asm volatile( - "call SyscallAsm\n" - // N.B. These are not the calling conventions normally used by the ABI. - : "=a"(ret) - : "0"(ret), "D"(args) - : "cc", "esp", "memory", "ecx", "edx"); -#elif defined(__x86_64__) - intptr_t ret = SyscallAsm(nr, args); -#elif defined(__arm__) - intptr_t ret; - { - register intptr_t inout __asm__("r0") = nr; - register const intptr_t* data __asm__("r6") = args; - asm volatile( - "bl SyscallAsm\n" - // N.B. These are not the calling conventions normally used by the ABI. - : "=r"(inout) - : "0"(inout), "r"(data) - : "cc", - "lr", - "memory", - "r1", - "r2", - "r3", - "r4", - "r5" -#if !defined(__thumb__) - // In thumb mode, we cannot use "r7" as a general purpose register, as - // it is our frame pointer. We have to manually manage and preserve - // it. - // In ARM mode, we have a dedicated frame pointer register and "r7" is - // thus available as a general purpose register. We don't preserve it, - // but instead mark it as clobbered. - , - "r7" -#endif // !defined(__thumb__) - ); - ret = inout; - } -#elif defined(__mips__) - int err_status; - intptr_t ret = Syscall::SandboxSyscallRaw(nr, args, &err_status); - - if (err_status) { - // On error, MIPS returns errno from syscall instead of -errno. - // The purpose of this negation is for SandboxSyscall() to behave - // more like it would on other architectures. - ret = -ret; - } -#elif defined(__aarch64__) - intptr_t ret; - { - register intptr_t inout __asm__("x0") = nr; - register const intptr_t* data __asm__("x6") = args; - asm volatile("bl SyscallAsm\n" - : "=r"(inout) - : "0"(inout), "r"(data) - : "memory", "x1", "x2", "x3", "x4", "x5", "x8", "x30"); - ret = inout; - } - -#else -#error "Unimplemented architecture" -#endif - return ret; -} - -void Syscall::PutValueInUcontext(intptr_t ret_val, ucontext_t* ctx) { -#if defined(__mips__) - // Mips ABI states that on error a3 CPU register has non zero value and if - // there is no error, it should be zero. - if (ret_val <= -1 && ret_val >= -4095) { - // |ret_val| followes the Syscall::Call() convention of being -errno on - // errors. In order to write correct value to return register this sign - // needs to be changed back. - ret_val = -ret_val; - SECCOMP_PARM4(ctx) = 1; - } else - SECCOMP_PARM4(ctx) = 0; -#endif - SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val); -} - -#if defined(__mips__) -intptr_t Syscall::SandboxSyscallRaw(int nr, - const intptr_t* args, - intptr_t* err_ret) { - register intptr_t ret __asm__("v0") = nr; - register intptr_t syscallasm __asm__("t9") = (intptr_t) &SyscallAsm; - // a3 register becomes non zero on error. - register intptr_t err_stat __asm__("a3") = 0; - { - register const intptr_t* data __asm__("a0") = args; - asm volatile( - "jalr $t9\n" - " nop\n" - : "=r"(ret), "=r"(err_stat) - : "0"(ret), - "r"(data), - "r"(syscallasm) - // a2 is in the clober list so inline assembly can not change its - // value. - : "memory", "ra", "a2"); - } - - // Set an error status so it can be used outside of this function - *err_ret = err_stat; - - return ret; -} -#endif // defined(__mips__) - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf/syscall.h b/sandbox/linux/seccomp-bpf/syscall.h deleted file mode 100644 index ccfc88dcb3..0000000000 --- a/sandbox/linux/seccomp-bpf/syscall.h +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SECCOMP_BPF_SYSCALL_H__ -#define SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ - -#include <signal.h> -#include <stdint.h> - -#include "base/macros.h" -#include "sandbox/linux/system_headers/linux_signal.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// This purely static class can be used to perform system calls with some -// low-level control. -class SANDBOX_EXPORT Syscall { - public: - // InvalidCall() invokes Call() with a platform-appropriate syscall - // number that is guaranteed to not be implemented (i.e., normally - // returns -ENOSYS). - // This is primarily meant to be useful for writing sandbox policy - // unit tests. - static intptr_t InvalidCall(); - - // System calls can take up to six parameters (up to eight on some - // architectures). Traditionally, glibc - // implements this property by using variadic argument lists. This works, but - // confuses modern tools such as valgrind, because we are nominally passing - // uninitialized data whenever we call through this function and pass less - // than the full six arguments. - // So, instead, we use C++'s template system to achieve a very similar - // effect. C++ automatically sets the unused parameters to zero for us, and - // it also does the correct type expansion (e.g. from 32bit to 64bit) where - // necessary. - // We have to use C-style cast operators as we want to be able to accept both - // integer and pointer types. - template <class T0, - class T1, - class T2, - class T3, - class T4, - class T5, - class T6, - class T7> - static inline intptr_t - Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7) { - return Call(nr, - (intptr_t)p0, - (intptr_t)p1, - (intptr_t)p2, - (intptr_t)p3, - (intptr_t)p4, - (intptr_t)p5, - (intptr_t)p6, - (intptr_t)p7); - } - - template <class T0, - class T1, - class T2, - class T3, - class T4, - class T5, - class T6> - static inline intptr_t - Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6) { - return Call(nr, - (intptr_t)p0, - (intptr_t)p1, - (intptr_t)p2, - (intptr_t)p3, - (intptr_t)p4, - (intptr_t)p5, - (intptr_t)p6, - 0); - } - - template <class T0, class T1, class T2, class T3, class T4, class T5> - static inline intptr_t - Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) { - return Call(nr, - (intptr_t)p0, - (intptr_t)p1, - (intptr_t)p2, - (intptr_t)p3, - (intptr_t)p4, - (intptr_t)p5, - 0, - 0); - } - - template <class T0, class T1, class T2, class T3, class T4> - static inline intptr_t Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) { - return Call(nr, p0, p1, p2, p3, p4, 0, 0, 0); - } - - template <class T0, class T1, class T2, class T3> - static inline intptr_t Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3) { - return Call(nr, p0, p1, p2, p3, 0, 0, 0, 0); - } - - template <class T0, class T1, class T2> - static inline intptr_t Call(int nr, T0 p0, T1 p1, T2 p2) { - return Call(nr, p0, p1, p2, 0, 0, 0, 0, 0); - } - - template <class T0, class T1> - static inline intptr_t Call(int nr, T0 p0, T1 p1) { - return Call(nr, p0, p1, 0, 0, 0, 0, 0, 0); - } - - template <class T0> - static inline intptr_t Call(int nr, T0 p0) { - return Call(nr, p0, 0, 0, 0, 0, 0, 0, 0); - } - - static inline intptr_t Call(int nr) { - return Call(nr, 0, 0, 0, 0, 0, 0, 0, 0); - } - - // Set the registers in |ctx| to match what they would be after a system call - // returning |ret_val|. |ret_val| must follow the Syscall::Call() convention - // of being -errno on errors. - static void PutValueInUcontext(intptr_t ret_val, ucontext_t* ctx); - - private: - // This performs system call |nr| with the arguments p0 to p7 from a constant - // userland address, which is for instance observable by seccomp-bpf filters. - // The constant userland address from which these system calls are made will - // be returned if |nr| is passed as -1. - // On error, this function will return a value between -1 and -4095 which - // should be interpreted as -errno. - static intptr_t Call(int nr, - intptr_t p0, - intptr_t p1, - intptr_t p2, - intptr_t p3, - intptr_t p4, - intptr_t p5, - intptr_t p6, - intptr_t p7); - -#if defined(__mips__) - // This function basically does on MIPS what SandboxSyscall() is doing on - // other architectures. However, because of specificity of MIPS regarding - // handling syscall errors, SandboxSyscall() is made as a wrapper for this - // function in order for SandboxSyscall() to behave more like on other - // architectures on places where return value from SandboxSyscall() is used - // directly (like in most tests). - // The syscall "nr" is called with arguments that are set in an array on which - // pointer "args" points to and an information weather there is an error or no - // is returned to SandboxSyscall() by err_stat. - static intptr_t SandboxSyscallRaw(int nr, - const intptr_t* args, - intptr_t* err_stat); -#endif // defined(__mips__) - - DISALLOW_IMPLICIT_CONSTRUCTORS(Syscall); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ diff --git a/sandbox/linux/seccomp-bpf/syscall_unittest.cc b/sandbox/linux/seccomp-bpf/syscall_unittest.cc deleted file mode 100644 index 01336f9b62..0000000000 --- a/sandbox/linux/seccomp-bpf/syscall_unittest.cc +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2012 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/linux/seccomp-bpf/syscall.h" - -#include <asm/unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/mman.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include <vector> - -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/policy.h" -#include "sandbox/linux/seccomp-bpf/bpf_tests.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -using sandbox::bpf_dsl::Allow; -using sandbox::bpf_dsl::ResultExpr; -using sandbox::bpf_dsl::Trap; - -namespace sandbox { - -namespace { - -// Different platforms use different symbols for the six-argument version -// of the mmap() system call. Test for the correct symbol at compile time. -#ifdef __NR_mmap2 -const int kMMapNr = __NR_mmap2; -#else -const int kMMapNr = __NR_mmap; -#endif - -TEST(Syscall, InvalidCallReturnsENOSYS) { - EXPECT_EQ(-ENOSYS, Syscall::InvalidCall()); -} - -TEST(Syscall, WellKnownEntryPoint) { -// Test that Syscall::Call(-1) is handled specially. Don't do this on ARM, -// where syscall(-1) crashes with SIGILL. Not running the test is fine, as we -// are still testing ARM code in the next set of tests. -#if !defined(__arm__) && !defined(__aarch64__) - EXPECT_NE(Syscall::Call(-1), syscall(-1)); -#endif - -// If possible, test that Syscall::Call(-1) returns the address right -// after -// a kernel entry point. -#if defined(__i386__) - EXPECT_EQ(0x80CDu, ((uint16_t*)Syscall::Call(-1))[-1]); // INT 0x80 -#elif defined(__x86_64__) - EXPECT_EQ(0x050Fu, ((uint16_t*)Syscall::Call(-1))[-1]); // SYSCALL -#elif defined(__arm__) -#if defined(__thumb__) - EXPECT_EQ(0xDF00u, ((uint16_t*)Syscall::Call(-1))[-1]); // SWI 0 -#else - EXPECT_EQ(0xEF000000u, ((uint32_t*)Syscall::Call(-1))[-1]); // SVC 0 -#endif -#elif defined(__mips__) - // Opcode for MIPS sycall is in the lower 16-bits - EXPECT_EQ(0x0cu, (((uint32_t*)Syscall::Call(-1))[-1]) & 0x0000FFFF); -#elif defined(__aarch64__) - EXPECT_EQ(0xD4000001u, ((uint32_t*)Syscall::Call(-1))[-1]); // SVC 0 -#else -#warning Incomplete test case; need port for target platform -#endif -} - -TEST(Syscall, TrivialSyscallNoArgs) { - // Test that we can do basic system calls - EXPECT_EQ(Syscall::Call(__NR_getpid), syscall(__NR_getpid)); -} - -TEST(Syscall, TrivialSyscallOneArg) { - int new_fd; - // Duplicate standard error and close it. - ASSERT_GE(new_fd = Syscall::Call(__NR_dup, 2), 0); - int close_return_value = IGNORE_EINTR(Syscall::Call(__NR_close, new_fd)); - ASSERT_EQ(close_return_value, 0); -} - -TEST(Syscall, TrivialFailingSyscall) { - errno = -42; - int ret = Syscall::Call(__NR_dup, -1); - ASSERT_EQ(-EBADF, ret); - // Verify that Syscall::Call does not touch errno. - ASSERT_EQ(-42, errno); -} - -// SIGSYS trap handler that will be called on __NR_uname. -intptr_t CopySyscallArgsToAux(const struct arch_seccomp_data& args, void* aux) { - // |aux| is our BPF_AUX pointer. - std::vector<uint64_t>* const seen_syscall_args = - static_cast<std::vector<uint64_t>*>(aux); - BPF_ASSERT(arraysize(args.args) == 6); - seen_syscall_args->assign(args.args, args.args + arraysize(args.args)); - return -ENOMEM; -} - -class CopyAllArgsOnUnamePolicy : public bpf_dsl::Policy { - public: - explicit CopyAllArgsOnUnamePolicy(std::vector<uint64_t>* aux) : aux_(aux) {} - ~CopyAllArgsOnUnamePolicy() override {} - - ResultExpr EvaluateSyscall(int sysno) const override { - DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); - if (sysno == __NR_uname) { - return Trap(CopySyscallArgsToAux, aux_); - } else { - return Allow(); - } - } - - private: - std::vector<uint64_t>* aux_; - - DISALLOW_COPY_AND_ASSIGN(CopyAllArgsOnUnamePolicy); -}; - -// We are testing Syscall::Call() by making use of a BPF filter that -// allows us -// to inspect the system call arguments that the kernel saw. -BPF_TEST(Syscall, - SyntheticSixArgs, - CopyAllArgsOnUnamePolicy, - std::vector<uint64_t> /* (*BPF_AUX) */) { - const int kExpectedValue = 42; - // In this test we only pass integers to the kernel. We might want to make - // additional tests to try other types. What we will see depends on - // implementation details of kernel BPF filters and we will need to document - // the expected behavior very clearly. - int syscall_args[6]; - for (size_t i = 0; i < arraysize(syscall_args); ++i) { - syscall_args[i] = kExpectedValue + i; - } - - // We could use pretty much any system call we don't need here. uname() is - // nice because it doesn't have any dangerous side effects. - BPF_ASSERT(Syscall::Call(__NR_uname, - syscall_args[0], - syscall_args[1], - syscall_args[2], - syscall_args[3], - syscall_args[4], - syscall_args[5]) == -ENOMEM); - - // We expect the trap handler to have copied the 6 arguments. - BPF_ASSERT(BPF_AUX->size() == 6); - - // Don't loop here so that we can see which argument does cause the failure - // easily from the failing line. - // uint64_t is the type passed to our SIGSYS handler. - BPF_ASSERT((*BPF_AUX)[0] == static_cast<uint64_t>(syscall_args[0])); - BPF_ASSERT((*BPF_AUX)[1] == static_cast<uint64_t>(syscall_args[1])); - BPF_ASSERT((*BPF_AUX)[2] == static_cast<uint64_t>(syscall_args[2])); - BPF_ASSERT((*BPF_AUX)[3] == static_cast<uint64_t>(syscall_args[3])); - BPF_ASSERT((*BPF_AUX)[4] == static_cast<uint64_t>(syscall_args[4])); - BPF_ASSERT((*BPF_AUX)[5] == static_cast<uint64_t>(syscall_args[5])); -} - -TEST(Syscall, ComplexSyscallSixArgs) { - int fd; - ASSERT_LE(0, - fd = Syscall::Call(__NR_openat, AT_FDCWD, "/dev/null", O_RDWR, 0L)); - - // Use mmap() to allocate some read-only memory - char* addr0; - ASSERT_NE( - (char*)NULL, - addr0 = reinterpret_cast<char*>(Syscall::Call(kMMapNr, - (void*)NULL, - 4096, - PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, - fd, - 0L))); - - // Try to replace the existing mapping with a read-write mapping - char* addr1; - ASSERT_EQ(addr0, - addr1 = reinterpret_cast<char*>( - Syscall::Call(kMMapNr, - addr0, - 4096L, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - fd, - 0L))); - ++*addr1; // This should not seg fault - - // Clean up - EXPECT_EQ(0, Syscall::Call(__NR_munmap, addr1, 4096L)); - EXPECT_EQ(0, IGNORE_EINTR(Syscall::Call(__NR_close, fd))); - - // Check that the offset argument (i.e. the sixth argument) is processed - // correctly. - ASSERT_GE( - fd = Syscall::Call(__NR_openat, AT_FDCWD, "/proc/self/exe", O_RDONLY, 0L), - 0); - char* addr2, *addr3; - ASSERT_NE((char*)NULL, - addr2 = reinterpret_cast<char*>(Syscall::Call( - kMMapNr, (void*)NULL, 8192L, PROT_READ, MAP_PRIVATE, fd, 0L))); - ASSERT_NE((char*)NULL, - addr3 = reinterpret_cast<char*>(Syscall::Call(kMMapNr, - (void*)NULL, - 4096L, - PROT_READ, - MAP_PRIVATE, - fd, -#if defined(__NR_mmap2) - 1L -#else - 4096L -#endif - ))); - EXPECT_EQ(0, memcmp(addr2 + 4096, addr3, 4096)); - - // Just to be absolutely on the safe side, also verify that the file - // contents matches what we are getting from a read() operation. - char buf[8192]; - EXPECT_EQ(8192, Syscall::Call(__NR_read, fd, buf, 8192L)); - EXPECT_EQ(0, memcmp(addr2, buf, 8192)); - - // Clean up - EXPECT_EQ(0, Syscall::Call(__NR_munmap, addr2, 8192L)); - EXPECT_EQ(0, Syscall::Call(__NR_munmap, addr3, 4096L)); - EXPECT_EQ(0, IGNORE_EINTR(Syscall::Call(__NR_close, fd))); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf/trap.cc b/sandbox/linux/seccomp-bpf/trap.cc deleted file mode 100644 index 003708d2c8..0000000000 --- a/sandbox/linux/seccomp-bpf/trap.cc +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright (c) 2012 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/linux/seccomp-bpf/trap.h" - -#include <errno.h> -#include <signal.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <sys/syscall.h> - -#include <algorithm> -#include <limits> -#include <tuple> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/seccomp-bpf/die.h" -#include "sandbox/linux/seccomp-bpf/syscall.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_seccomp.h" -#include "sandbox/linux/system_headers/linux_signal.h" - -namespace { - -struct arch_sigsys { - void* ip; - int nr; - unsigned int arch; -}; - -const int kCapacityIncrement = 20; - -// Unsafe traps can only be turned on, if the user explicitly allowed them -// by setting the CHROME_SANDBOX_DEBUGGING environment variable. -const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; - -// We need to tell whether we are performing a "normal" callback, or -// whether we were called recursively from within a UnsafeTrap() callback. -// This is a little tricky to do, because we need to somehow get access to -// per-thread data from within a signal context. Normal TLS storage is not -// safely accessible at this time. We could roll our own, but that involves -// a lot of complexity. Instead, we co-opt one bit in the signal mask. -// If BUS is blocked, we assume that we have been called recursively. -// There is a possibility for collision with other code that needs to do -// this, but in practice the risks are low. -// If SIGBUS turns out to be a problem, we could instead co-opt one of the -// realtime signals. There are plenty of them. Unfortunately, there is no -// way to mark a signal as allocated. So, the potential for collision is -// possibly even worse. -bool GetIsInSigHandler(const ucontext_t* ctx) { - // Note: on Android, sigismember does not take a pointer to const. - return sigismember(const_cast<sigset_t*>(&ctx->uc_sigmask), LINUX_SIGBUS); -} - -void SetIsInSigHandler() { - sigset_t mask; - if (sigemptyset(&mask) || sigaddset(&mask, LINUX_SIGBUS) || - sandbox::sys_sigprocmask(LINUX_SIG_BLOCK, &mask, NULL)) { - SANDBOX_DIE("Failed to block SIGBUS"); - } -} - -bool IsDefaultSignalAction(const struct sigaction& sa) { - if (sa.sa_flags & SA_SIGINFO || sa.sa_handler != SIG_DFL) { - return false; - } - return true; -} - -} // namespace - -namespace sandbox { - -Trap::Trap() - : trap_array_(NULL), - trap_array_size_(0), - trap_array_capacity_(0), - has_unsafe_traps_(false) { - // Set new SIGSYS handler - struct sigaction sa = {}; - // In some toolchain, sa_sigaction is not declared in struct sigaction. - // So, here cast the pointer to the sa_handler's type. This works because - // |sa_handler| and |sa_sigaction| shares the same memory. - sa.sa_handler = reinterpret_cast<void (*)(int)>(SigSysAction); - sa.sa_flags = LINUX_SA_SIGINFO | LINUX_SA_NODEFER; - struct sigaction old_sa = {}; - if (sys_sigaction(LINUX_SIGSYS, &sa, &old_sa) < 0) { - SANDBOX_DIE("Failed to configure SIGSYS handler"); - } - - if (!IsDefaultSignalAction(old_sa)) { - static const char kExistingSIGSYSMsg[] = - "Existing signal handler when trying to install SIGSYS. SIGSYS needs " - "to be reserved for seccomp-bpf."; - DLOG(FATAL) << kExistingSIGSYSMsg; - LOG(ERROR) << kExistingSIGSYSMsg; - } - - // Unmask SIGSYS - sigset_t mask; - if (sigemptyset(&mask) || sigaddset(&mask, LINUX_SIGSYS) || - sys_sigprocmask(LINUX_SIG_UNBLOCK, &mask, NULL)) { - SANDBOX_DIE("Failed to configure SIGSYS handler"); - } -} - -bpf_dsl::TrapRegistry* Trap::Registry() { - // Note: This class is not thread safe. It is the caller's responsibility - // to avoid race conditions. Normally, this is a non-issue as the sandbox - // can only be initialized if there are no other threads present. - // Also, this is not a normal singleton. Once created, the global trap - // object must never be destroyed again. - if (!global_trap_) { - global_trap_ = new Trap(); - if (!global_trap_) { - SANDBOX_DIE("Failed to allocate global trap handler"); - } - } - return global_trap_; -} - -void Trap::SigSysAction(int nr, LinuxSigInfo* info, void* void_context) { - if (info) { - MSAN_UNPOISON(info, sizeof(*info)); - } - - // Obtain the signal context. This, most notably, gives us access to - // all CPU registers at the time of the signal. - ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context); - if (ctx) { - MSAN_UNPOISON(ctx, sizeof(*ctx)); - } - - if (!global_trap_) { - RAW_SANDBOX_DIE( - "This can't happen. Found no global singleton instance " - "for Trap() handling."); - } - global_trap_->SigSys(nr, info, ctx); -} - -void Trap::SigSys(int nr, LinuxSigInfo* info, ucontext_t* ctx) { - // Signal handlers should always preserve "errno". Otherwise, we could - // trigger really subtle bugs. - const int old_errno = errno; - - // Various sanity checks to make sure we actually received a signal - // triggered by a BPF filter. If something else triggered SIGSYS - // (e.g. kill()), there is really nothing we can do with this signal. - if (nr != LINUX_SIGSYS || info->si_code != SYS_SECCOMP || !ctx || - info->si_errno <= 0 || - static_cast<size_t>(info->si_errno) > trap_array_size_) { - // ATI drivers seem to send SIGSYS, so this cannot be FATAL. - // See crbug.com/178166. - // TODO(jln): add a DCHECK or move back to FATAL. - RAW_LOG(ERROR, "Unexpected SIGSYS received."); - errno = old_errno; - return; - } - - - // Obtain the siginfo information that is specific to SIGSYS. Unfortunately, - // most versions of glibc don't include this information in siginfo_t. So, - // we need to explicitly copy it into a arch_sigsys structure. - struct arch_sigsys sigsys; - memcpy(&sigsys, &info->_sifields, sizeof(sigsys)); - -#if defined(__mips__) - // When indirect syscall (syscall(__NR_foo, ...)) is made on Mips, the - // number in register SECCOMP_SYSCALL(ctx) is always __NR_syscall and the - // real number of a syscall (__NR_foo) is in SECCOMP_PARM1(ctx) - bool sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) && - sigsys.nr != static_cast<int>(SECCOMP_PARM1(ctx)); -#else - bool sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)); -#endif - - // Some more sanity checks. - if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) || - sigsys_nr_is_bad || sigsys.arch != SECCOMP_ARCH) { - // TODO(markus): - // SANDBOX_DIE() can call LOG(FATAL). This is not normally async-signal - // safe and can lead to bugs. We should eventually implement a different - // logging and reporting mechanism that is safe to be called from - // the sigSys() handler. - RAW_SANDBOX_DIE("Sanity checks are failing after receiving SIGSYS."); - } - - intptr_t rc; - if (has_unsafe_traps_ && GetIsInSigHandler(ctx)) { - errno = old_errno; - if (sigsys.nr == __NR_clone) { - RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler."); - } -#if defined(__mips__) - // Mips supports up to eight arguments for syscall. - // However, seccomp bpf can filter only up to six arguments, so using eight - // arguments has sense only when using UnsafeTrap() handler. - rc = Syscall::Call(SECCOMP_SYSCALL(ctx), - SECCOMP_PARM1(ctx), - SECCOMP_PARM2(ctx), - SECCOMP_PARM3(ctx), - SECCOMP_PARM4(ctx), - SECCOMP_PARM5(ctx), - SECCOMP_PARM6(ctx), - SECCOMP_PARM7(ctx), - SECCOMP_PARM8(ctx)); -#else - rc = Syscall::Call(SECCOMP_SYSCALL(ctx), - SECCOMP_PARM1(ctx), - SECCOMP_PARM2(ctx), - SECCOMP_PARM3(ctx), - SECCOMP_PARM4(ctx), - SECCOMP_PARM5(ctx), - SECCOMP_PARM6(ctx)); -#endif // defined(__mips__) - } else { - const TrapKey& trap = trap_array_[info->si_errno - 1]; - if (!trap.safe) { - SetIsInSigHandler(); - } - - // Copy the seccomp-specific data into a arch_seccomp_data structure. This - // is what we are showing to TrapFnc callbacks that the system call - // evaluator registered with the sandbox. - struct arch_seccomp_data data = { - static_cast<int>(SECCOMP_SYSCALL(ctx)), - SECCOMP_ARCH, - reinterpret_cast<uint64_t>(sigsys.ip), - {static_cast<uint64_t>(SECCOMP_PARM1(ctx)), - static_cast<uint64_t>(SECCOMP_PARM2(ctx)), - static_cast<uint64_t>(SECCOMP_PARM3(ctx)), - static_cast<uint64_t>(SECCOMP_PARM4(ctx)), - static_cast<uint64_t>(SECCOMP_PARM5(ctx)), - static_cast<uint64_t>(SECCOMP_PARM6(ctx))}}; - - // Now call the TrapFnc callback associated with this particular instance - // of SECCOMP_RET_TRAP. - rc = trap.fnc(data, const_cast<void*>(trap.aux)); - } - - // Update the CPU register that stores the return code of the system call - // that we just handled, and restore "errno" to the value that it had - // before entering the signal handler. - Syscall::PutValueInUcontext(rc, ctx); - errno = old_errno; - - return; -} - -bool Trap::TrapKey::operator<(const TrapKey& o) const { - return std::tie(fnc, aux, safe) < std::tie(o.fnc, o.aux, o.safe); -} - -uint16_t Trap::Add(TrapFnc fnc, const void* aux, bool safe) { - if (!safe && !SandboxDebuggingAllowedByUser()) { - // Unless the user set the CHROME_SANDBOX_DEBUGGING environment variable, - // we never return an ErrorCode that is marked as "unsafe". This also - // means, the BPF compiler will never emit code that allow unsafe system - // calls to by-pass the filter (because they use the magic return address - // from Syscall::Call(-1)). - - // This SANDBOX_DIE() can optionally be removed. It won't break security, - // but it might make error messages from the BPF compiler a little harder - // to understand. Removing the SANDBOX_DIE() allows callers to easily check - // whether unsafe traps are supported (by checking whether the returned - // ErrorCode is ET_INVALID). - SANDBOX_DIE( - "Cannot use unsafe traps unless CHROME_SANDBOX_DEBUGGING " - "is enabled"); - - return 0; - } - - // Each unique pair of TrapFnc and auxiliary data make up a distinct instance - // of a SECCOMP_RET_TRAP. - TrapKey key(fnc, aux, safe); - - // We return unique identifiers together with SECCOMP_RET_TRAP. This allows - // us to associate trap with the appropriate handler. The kernel allows us - // identifiers in the range from 0 to SECCOMP_RET_DATA (0xFFFF). We want to - // avoid 0, as it could be confused for a trap without any specific id. - // The nice thing about sequentially numbered identifiers is that we can also - // trivially look them up from our signal handler without making any system - // calls that might be async-signal-unsafe. - // In order to do so, we store all of our traps in a C-style trap_array_. - - TrapIds::const_iterator iter = trap_ids_.find(key); - if (iter != trap_ids_.end()) { - // We have seen this pair before. Return the same id that we assigned - // earlier. - return iter->second; - } - - // This is a new pair. Remember it and assign a new id. - if (trap_array_size_ >= SECCOMP_RET_DATA /* 0xFFFF */ || - trap_array_size_ >= std::numeric_limits<uint16_t>::max()) { - // In practice, this is pretty much impossible to trigger, as there - // are other kernel limitations that restrict overall BPF program sizes. - SANDBOX_DIE("Too many SECCOMP_RET_TRAP callback instances"); - } - - // Our callers ensure that there are no other threads accessing trap_array_ - // concurrently (typically this is done by ensuring that we are single- - // threaded while the sandbox is being set up). But we nonetheless are - // modifying a live data structure that could be accessed any time a - // system call is made; as system calls could be triggering SIGSYS. - // So, we have to be extra careful that we update trap_array_ atomically. - // In particular, this means we shouldn't be using realloc() to resize it. - // Instead, we allocate a new array, copy the values, and then switch the - // pointer. We only really care about the pointer being updated atomically - // and the data that is pointed to being valid, as these are the only - // values accessed from the signal handler. It is OK if trap_array_size_ - // is inconsistent with the pointer, as it is monotonously increasing. - // Also, we only care about compiler barriers, as the signal handler is - // triggered synchronously from a system call. We don't have to protect - // against issues with the memory model or with completely asynchronous - // events. - if (trap_array_size_ >= trap_array_capacity_) { - trap_array_capacity_ += kCapacityIncrement; - TrapKey* old_trap_array = trap_array_; - TrapKey* new_trap_array = new TrapKey[trap_array_capacity_]; - std::copy_n(old_trap_array, trap_array_size_, new_trap_array); - - // Language specs are unclear on whether the compiler is allowed to move - // the "delete[]" above our preceding assignments and/or memory moves, - // iff the compiler believes that "delete[]" doesn't have any other - // global side-effects. - // We insert optimization barriers to prevent this from happening. - // The first barrier is probably not needed, but better be explicit in - // what we want to tell the compiler. - // The clang developer mailing list couldn't answer whether this is a - // legitimate worry; but they at least thought that the barrier is - // sufficient to prevent the (so far hypothetical) problem of re-ordering - // of instructions by the compiler. - // - // TODO(mdempsky): Try to clean this up using base/atomicops or C++11 - // atomics; see crbug.com/414363. - asm volatile("" : "=r"(new_trap_array) : "0"(new_trap_array) : "memory"); - trap_array_ = new_trap_array; - asm volatile("" : "=r"(trap_array_) : "0"(trap_array_) : "memory"); - - delete[] old_trap_array; - } - - uint16_t id = trap_array_size_ + 1; - trap_ids_[key] = id; - trap_array_[trap_array_size_] = key; - trap_array_size_++; - return id; -} - -bool Trap::SandboxDebuggingAllowedByUser() { - const char* debug_flag = getenv(kSandboxDebuggingEnv); - return debug_flag && *debug_flag; -} - -bool Trap::EnableUnsafeTraps() { - if (!has_unsafe_traps_) { - // Unsafe traps are a one-way fuse. Once enabled, they can never be turned - // off again. - // We only allow enabling unsafe traps, if the user explicitly set an - // appropriate environment variable. This prevents bugs that accidentally - // disable all sandboxing for all users. - if (SandboxDebuggingAllowedByUser()) { - // We only ever print this message once, when we enable unsafe traps the - // first time. - SANDBOX_INFO("WARNING! Disabling sandbox for debugging purposes"); - has_unsafe_traps_ = true; - } else { - SANDBOX_INFO( - "Cannot disable sandbox and use unsafe traps unless " - "CHROME_SANDBOX_DEBUGGING is turned on first"); - } - } - // Returns the, possibly updated, value of has_unsafe_traps_. - return has_unsafe_traps_; -} - -Trap* Trap::global_trap_; - -} // namespace sandbox diff --git a/sandbox/linux/seccomp-bpf/trap.h b/sandbox/linux/seccomp-bpf/trap.h deleted file mode 100644 index a73d2064b4..0000000000 --- a/sandbox/linux/seccomp-bpf/trap.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SECCOMP_BPF_TRAP_H__ -#define SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__ - -#include <stddef.h> -#include <stdint.h> - -#include <map> - -#include "base/macros.h" -#include "sandbox/linux/bpf_dsl/trap_registry.h" -#include "sandbox/linux/system_headers/linux_signal.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// The Trap class allows a BPF filter program to branch out to user space by -// raising a SIGSYS signal. -// N.B.: This class does not perform any synchronization operations. If -// modifications are made to any of the traps, it is the caller's -// responsibility to ensure that this happens in a thread-safe fashion. -// Preferably, that means that no other threads should be running at that -// time. For the purposes of our sandbox, this assertion should always be -// true. Threads are incompatible with the seccomp sandbox anyway. -class SANDBOX_EXPORT Trap : public bpf_dsl::TrapRegistry { - public: - uint16_t Add(TrapFnc fnc, const void* aux, bool safe) override; - - bool EnableUnsafeTraps() override; - - // Registry returns the trap registry used by Trap's SIGSYS handler, - // creating it if necessary. - static bpf_dsl::TrapRegistry* Registry(); - - // SandboxDebuggingAllowedByUser returns whether the - // "CHROME_SANDBOX_DEBUGGING" environment variable is set. - static bool SandboxDebuggingAllowedByUser(); - - private: - struct TrapKey { - TrapKey() : fnc(NULL), aux(NULL), safe(false) {} - TrapKey(TrapFnc f, const void* a, bool s) : fnc(f), aux(a), safe(s) {} - TrapFnc fnc; - const void* aux; - bool safe; - bool operator<(const TrapKey&) const; - }; - typedef std::map<TrapKey, uint16_t> TrapIds; - - // Our constructor is private. A shared global instance is created - // automatically as needed. - Trap(); - - // The destructor is unimplemented as destroying this object would - // break subsequent system calls that trigger a SIGSYS. - ~Trap() = delete; - - static void SigSysAction(int nr, LinuxSigInfo* info, void* void_context); - - // Make sure that SigSys is not inlined in order to get slightly better crash - // dumps. - void SigSys(int nr, LinuxSigInfo* info, ucontext_t* ctx) - __attribute__((noinline)); - // We have a global singleton that handles all of our SIGSYS traps. This - // variable must never be deallocated after it has been set up initially, as - // there is no way to reset in-kernel BPF filters that generate SIGSYS - // events. - static Trap* global_trap_; - - TrapIds trap_ids_; // Maps from TrapKeys to numeric ids - TrapKey* trap_array_; // Array of TrapKeys indexed by ids - size_t trap_array_size_; // Currently used size of array - size_t trap_array_capacity_; // Currently allocated capacity of array - bool has_unsafe_traps_; // Whether unsafe traps have been enabled - - // Copying and assigning is unimplemented. It doesn't make sense for a - // singleton. - DISALLOW_COPY_AND_ASSIGN(Trap); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__ diff --git a/sandbox/linux/seccomp-bpf/trap_unittest.cc b/sandbox/linux/seccomp-bpf/trap_unittest.cc deleted file mode 100644 index 99f94bfb3a..0000000000 --- a/sandbox/linux/seccomp-bpf/trap_unittest.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015 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/linux/seccomp-bpf/trap.h" - -#include <signal.h> - -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { -namespace { - -SANDBOX_TEST_ALLOW_NOISE(Trap, SigSysAction) { - // This creates a global Trap instance, and registers the signal handler - // (Trap::SigSysAction). - Trap::Registry(); - - // Send SIGSYS to self. If signal handler (SigSysAction) is not registered, - // the process will be terminated with status code -SIGSYS. - // Note that, SigSysAction handler would output an error message - // "Unexpected SIGSYS received." so it is necessary to allow the noise. - raise(SIGSYS); -} - -} // namespace -} // namespace sandbox diff --git a/sandbox/linux/services/DEPS b/sandbox/linux/services/DEPS deleted file mode 100644 index 70d9b18aa1..0000000000 --- a/sandbox/linux/services/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+sandbox/linux/system_headers", -] diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc deleted file mode 100644 index 50a109e2f4..0000000000 --- a/sandbox/linux/services/credentials.cc +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (c) 2013 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/linux/services/credentials.h" - -#include <errno.h> -#include <limits.h> -#include <signal.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "base/bind.h" -#include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/launch.h" -#include "base/third_party/valgrind/valgrind.h" -#include "build/build_config.h" -#include "sandbox/linux/services/namespace_utils.h" -#include "sandbox/linux/services/proc_util.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/services/thread_helpers.h" -#include "sandbox/linux/system_headers/capability.h" -#include "sandbox/linux/system_headers/linux_signal.h" - -namespace sandbox { - -namespace { - -bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; } - -// Checks that the set of RES-uids and the set of RES-gids have -// one element each and return that element in |resuid| and |resgid| -// respectively. It's ok to pass NULL as one or both of the ids. -bool GetRESIds(uid_t* resuid, gid_t* resgid) { - uid_t ruid, euid, suid; - gid_t rgid, egid, sgid; - PCHECK(sys_getresuid(&ruid, &euid, &suid) == 0); - PCHECK(sys_getresgid(&rgid, &egid, &sgid) == 0); - const bool uids_are_equal = (ruid == euid) && (ruid == suid); - const bool gids_are_equal = (rgid == egid) && (rgid == sgid); - if (!uids_are_equal || !gids_are_equal) return false; - if (resuid) *resuid = euid; - if (resgid) *resgid = egid; - return true; -} - -const int kExitSuccess = 0; - -#if defined(__clang__) -// Disable sanitizers that rely on TLS and may write to non-stack memory. -__attribute__((no_sanitize_address)) -__attribute__((no_sanitize_thread)) -__attribute__((no_sanitize_memory)) -#endif -int ChrootToSelfFdinfo(void*) { - // This function can be run from a vforked child, so it should not write to - // any memory other than the stack or errno. Reads from TLS may be different - // from in the parent process. - RAW_CHECK(sys_chroot("/proc/self/fdinfo/") == 0); - - // CWD is essentially an implicit file descriptor, so be careful to not - // leave it behind. - RAW_CHECK(chdir("/") == 0); - _exit(kExitSuccess); -} - -// chroot() to an empty dir that is "safe". To be safe, it must not contain -// any subdirectory (chroot-ing there would allow a chroot escape) and it must -// be impossible to create an empty directory there. -// We achieve this by doing the following: -// 1. We create a new process sharing file system information. -// 2. In the child, we chroot to /proc/self/fdinfo/ -// This is already "safe", since fdinfo/ does not contain another directory and -// one cannot create another directory there. -// 3. The process dies -// After (3) happens, the directory is not available anymore in /proc. -bool ChrootToSafeEmptyDir() { - // We need to chroot to a fdinfo that is unique to a process and have that - // process die. - // 1. We don't want to simply fork() because duplicating the page tables is - // slow with a big address space. - // 2. We do not use a regular thread (that would unshare CLONE_FILES) because - // when we are in a PID namespace, we cannot easily get a handle to the - // /proc/tid directory for the thread (since /proc may not be aware of the - // PID namespace). With a process, we can just use /proc/self. - pid_t pid = -1; - char stack_buf[PTHREAD_STACK_MIN] ALIGNAS(16); -#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ - defined(ARCH_CPU_MIPS_FAMILY) - // The stack grows downward. - void* stack = stack_buf + sizeof(stack_buf); -#else -#error "Unsupported architecture" -#endif - - int clone_flags = CLONE_FS | LINUX_SIGCHLD; - void* tls = nullptr; -#if defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM_FAMILY) - // Use CLONE_VM | CLONE_VFORK as an optimization to avoid copying page tables. - // Since clone writes to the new child's TLS before returning, we must set a - // new TLS to avoid corrupting the current process's TLS. On ARCH_CPU_X86, - // glibc performs syscalls by calling a function pointer in TLS, so we do not - // attempt this optimization. - clone_flags |= CLONE_VM | CLONE_VFORK | CLONE_SETTLS; - - char tls_buf[PTHREAD_STACK_MIN] = {0}; - tls = tls_buf; -#endif - - pid = clone(ChrootToSelfFdinfo, stack, clone_flags, nullptr, nullptr, tls, - nullptr); - PCHECK(pid != -1); - - int status = -1; - PCHECK(HANDLE_EINTR(waitpid(pid, &status, 0)) == pid); - - return WIFEXITED(status) && WEXITSTATUS(status) == kExitSuccess; -} - -// CHECK() that an attempt to move to a new user namespace raised an expected -// errno. -void CheckCloneNewUserErrno(int error) { - // EPERM can happen if already in a chroot. EUSERS if too many nested - // namespaces are used. EINVAL for kernels that don't support the feature. - // Valgrind will ENOSYS unshare(). - PCHECK(error == EPERM || error == EUSERS || error == EINVAL || - error == ENOSYS); -} - -// Converts a Capability to the corresponding Linux CAP_XXX value. -int CapabilityToKernelValue(Credentials::Capability cap) { - switch (cap) { - case Credentials::Capability::SYS_CHROOT: - return CAP_SYS_CHROOT; - case Credentials::Capability::SYS_ADMIN: - return CAP_SYS_ADMIN; - } - - LOG(FATAL) << "Invalid Capability: " << static_cast<int>(cap); - return 0; -} - -void SetGidAndUidMaps(gid_t gid, uid_t uid) { - if (NamespaceUtils::KernelSupportsDenySetgroups()) { - PCHECK(NamespaceUtils::DenySetgroups()); - } - DCHECK(GetRESIds(NULL, NULL)); - const char kGidMapFile[] = "/proc/self/gid_map"; - const char kUidMapFile[] = "/proc/self/uid_map"; - PCHECK(NamespaceUtils::WriteToIdMapFile(kGidMapFile, gid)); - PCHECK(NamespaceUtils::WriteToIdMapFile(kUidMapFile, uid)); - DCHECK(GetRESIds(NULL, NULL)); -} - -} // namespace. - -// static -bool Credentials::DropAllCapabilities(int proc_fd) { - if (!SetCapabilities(proc_fd, std::vector<Capability>())) { - return false; - } - - CHECK(!HasAnyCapability()); - return true; -} - -// static -bool Credentials::DropAllCapabilities() { - base::ScopedFD proc_fd(ProcUtil::OpenProc()); - return Credentials::DropAllCapabilities(proc_fd.get()); -} - -// static -bool Credentials::DropAllCapabilitiesOnCurrentThread() { - return SetCapabilitiesOnCurrentThread(std::vector<Capability>()); -} - -// static -bool Credentials::SetCapabilitiesOnCurrentThread( - const std::vector<Capability>& caps) { - struct cap_hdr hdr = {}; - hdr.version = _LINUX_CAPABILITY_VERSION_3; - struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; - - // Initially, cap has no capability flags set. Enable the effective and - // permitted flags only for the requested capabilities. - for (const Capability cap : caps) { - const int cap_num = CapabilityToKernelValue(cap); - const size_t index = CAP_TO_INDEX(cap_num); - const uint32_t mask = CAP_TO_MASK(cap_num); - data[index].effective |= mask; - data[index].permitted |= mask; - } - - return sys_capset(&hdr, data) == 0; -} - -// static -bool Credentials::SetCapabilities(int proc_fd, - const std::vector<Capability>& caps) { - DCHECK_LE(0, proc_fd); - -#if !defined(THREAD_SANITIZER) - // With TSAN, accept to break the security model as it is a testing - // configuration. - CHECK(ThreadHelpers::IsSingleThreaded(proc_fd)); -#endif - - return SetCapabilitiesOnCurrentThread(caps); -} - -bool Credentials::HasAnyCapability() { - struct cap_hdr hdr = {}; - hdr.version = _LINUX_CAPABILITY_VERSION_3; - struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; - - PCHECK(sys_capget(&hdr, data) == 0); - - for (size_t i = 0; i < arraysize(data); ++i) { - if (data[i].effective || data[i].permitted || data[i].inheritable) { - return true; - } - } - - return false; -} - -bool Credentials::HasCapability(Capability cap) { - struct cap_hdr hdr = {}; - hdr.version = _LINUX_CAPABILITY_VERSION_3; - struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; - - PCHECK(sys_capget(&hdr, data) == 0); - - const int cap_num = CapabilityToKernelValue(cap); - const size_t index = CAP_TO_INDEX(cap_num); - const uint32_t mask = CAP_TO_MASK(cap_num); - - return (data[index].effective | data[index].permitted | - data[index].inheritable) & - mask; -} - -// static -bool Credentials::CanCreateProcessInNewUserNS() { - // Valgrind will let clone(2) pass-through, but doesn't support unshare(), - // so always consider UserNS unsupported there. - if (IsRunningOnValgrind()) { - return false; - } - -#if defined(THREAD_SANITIZER) - // With TSAN, processes will always have threads running and can never - // enter a new user namespace with MoveToNewUserNS(). - return false; -#endif - - uid_t uid; - gid_t gid; - if (!GetRESIds(&uid, &gid)) { - return false; - } - - const pid_t pid = - base::ForkWithFlags(CLONE_NEWUSER | SIGCHLD, nullptr, nullptr); - - if (pid == -1) { - CheckCloneNewUserErrno(errno); - return false; - } - - // The parent process could have had threads. In the child, these threads - // have disappeared. - if (pid == 0) { - // unshare() requires the effective uid and gid to have a mapping in the - // parent namespace. - SetGidAndUidMaps(gid, uid); - - // Make sure we drop CAP_SYS_ADMIN. - CHECK(sandbox::Credentials::DropAllCapabilities()); - - // Ensure we have unprivileged use of CLONE_NEWUSER. Debian - // Jessie explicitly forbids this case. See: - // add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch - _exit(!!sys_unshare(CLONE_NEWUSER)); - } - - // Always reap the child. - int status = -1; - PCHECK(HANDLE_EINTR(waitpid(pid, &status, 0)) == pid); - - // clone(2) succeeded. Now return true only if the system grants - // unprivileged use of CLONE_NEWUSER as well. - return WIFEXITED(status) && WEXITSTATUS(status) == kExitSuccess; -} - -bool Credentials::MoveToNewUserNS() { - uid_t uid; - gid_t gid; - if (!GetRESIds(&uid, &gid)) { - // If all the uids (or gids) are not equal to each other, the security - // model will most likely confuse the caller, abort. - DVLOG(1) << "uids or gids differ!"; - return false; - } - int ret = sys_unshare(CLONE_NEWUSER); - if (ret) { - const int unshare_errno = errno; - VLOG(1) << "Looks like unprivileged CLONE_NEWUSER may not be available " - << "on this kernel."; - CheckCloneNewUserErrno(unshare_errno); - return false; - } - - // The current {r,e,s}{u,g}id is now an overflow id (c.f. - // /proc/sys/kernel/overflowuid). Setup the uid and gid maps. - SetGidAndUidMaps(gid, uid); - return true; -} - -bool Credentials::DropFileSystemAccess(int proc_fd) { - CHECK_LE(0, proc_fd); - - CHECK(ChrootToSafeEmptyDir()); - CHECK(!HasFileSystemAccess()); - CHECK(!ProcUtil::HasOpenDirectory(proc_fd)); - // We never let this function fail. - return true; -} - -bool Credentials::HasFileSystemAccess() { - return base::DirectoryExists(base::FilePath("/proc")); -} - -pid_t Credentials::ForkAndDropCapabilitiesInChild() { - pid_t pid = fork(); - if (pid != 0) { - return pid; - } - - // Since we just forked, we are single threaded. - PCHECK(DropAllCapabilitiesOnCurrentThread()); - return 0; -} - -} // namespace sandbox. diff --git a/sandbox/linux/services/credentials.h b/sandbox/linux/services/credentials.h deleted file mode 100644 index 157c8e75e8..0000000000 --- a/sandbox/linux/services/credentials.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2013 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_LINUX_SERVICES_CREDENTIALS_H_ -#define SANDBOX_LINUX_SERVICES_CREDENTIALS_H_ - -#include "build/build_config.h" -// Link errors are tedious to track, raise a compile-time error instead. -#if defined(OS_ANDROID) -#error "Android is not supported." -#endif // defined(OS_ANDROID). - -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "sandbox/linux/system_headers/capability.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// This class should be used to manipulate the current process' credentials. -// It is currently a stub used to manipulate POSIX.1e capabilities as -// implemented by the Linux kernel. -class SANDBOX_EXPORT Credentials { - public: - // For brevity, we only expose enums for the subset of capabilities we use. - // This can be expanded as the need arises. - enum class Capability { - SYS_CHROOT, - SYS_ADMIN, - }; - - // Drop all capabilities in the effective, inheritable and permitted sets for - // the current thread. For security reasons, since capabilities are - // per-thread, the caller is responsible for ensuring it is single-threaded - // when calling this API. - // |proc_fd| must be a file descriptor to /proc/ and remains owned by - // the caller. - static bool DropAllCapabilities(int proc_fd) WARN_UNUSED_RESULT; - // A similar API which assumes that it can open /proc/self/ by itself. - static bool DropAllCapabilities() WARN_UNUSED_RESULT; - // Sets the effective and permitted capability sets for the current thread to - // the list of capabiltiies in |caps|. All other capability flags are cleared. - static bool SetCapabilities(int proc_fd, - const std::vector<Capability>& caps) - WARN_UNUSED_RESULT; - - // Versions of the above functions which do not check that the process is - // single-threaded. After calling these functions, capabilities of other - // threads will not be changed. This is dangerous, do not use unless you nkow - // what you are doing. - static bool DropAllCapabilitiesOnCurrentThread() WARN_UNUSED_RESULT; - static bool SetCapabilitiesOnCurrentThread( - const std::vector<Capability>& caps) WARN_UNUSED_RESULT; - - // Returns true if the current thread has either the effective, permitted, or - // inheritable flag set for the given capability. - static bool HasCapability(Capability cap); - - // Return true iff there is any capability in any of the capabilities sets - // of the current thread. - static bool HasAnyCapability(); - - // Returns whether the kernel supports CLONE_NEWUSER and whether it would be - // possible to immediately move to a new user namespace. There is no point - // in using this method right before calling MoveToNewUserNS(), simply call - // MoveToNewUserNS() immediately. This method is only useful to test the - // ability to move to a user namespace ahead of time. - static bool CanCreateProcessInNewUserNS(); - - // Move the current process to a new "user namespace" as supported by Linux - // 3.8+ (CLONE_NEWUSER). - // The uid map will be set-up so that the perceived uid and gid will not - // change. - // If this call succeeds, the current process will be granted a full set of - // capabilities in the new namespace. - // This will fail if the process is not mono-threaded. - static bool MoveToNewUserNS() WARN_UNUSED_RESULT; - - // Remove the ability of the process to access the file system. File - // descriptors which are already open prior to calling this API remain - // available. - // The implementation currently uses chroot(2) and requires CAP_SYS_CHROOT. - // CAP_SYS_CHROOT can be acquired by using the MoveToNewUserNS() API. - // |proc_fd| must be a file descriptor to /proc/ and must be the only open - // directory file descriptor of the process. - // - // CRITICAL: - // - the caller must close |proc_fd| eventually or access to the file - // system can be recovered. - // - DropAllCapabilities() must be called to prevent escapes. - static bool DropFileSystemAccess(int proc_fd) WARN_UNUSED_RESULT; - - // This function returns true if the process can still access the filesystem. - static bool HasFileSystemAccess(); - - // Forks and drops capabilities in the child. - static pid_t ForkAndDropCapabilitiesInChild(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(Credentials); -}; - -} // namespace sandbox. - -#endif // SANDBOX_LINUX_SERVICES_CREDENTIALS_H_ diff --git a/sandbox/linux/services/credentials_unittest.cc b/sandbox/linux/services/credentials_unittest.cc deleted file mode 100644 index 41c04bbcc2..0000000000 --- a/sandbox/linux/services/credentials_unittest.cc +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright (c) 2012 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/linux/services/credentials.h" - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <sys/capability.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include <memory> -#include <vector> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "sandbox/linux/services/proc_util.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/capability.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace { - -struct CapFreeDeleter { - inline void operator()(cap_t cap) const { - int ret = cap_free(cap); - CHECK_EQ(0, ret); - } -}; - -// Wrapper to manage libcap2's cap_t type. -typedef std::unique_ptr<typeof(*((cap_t)0)), CapFreeDeleter> ScopedCap; - -bool WorkingDirectoryIsRoot() { - char current_dir[PATH_MAX]; - char* cwd = getcwd(current_dir, sizeof(current_dir)); - PCHECK(cwd); - if (strcmp("/", cwd)) return false; - - // The current directory is the root. Add a few paranoid checks. - struct stat current; - CHECK_EQ(0, stat(".", ¤t)); - struct stat parrent; - CHECK_EQ(0, stat("..", &parrent)); - CHECK_EQ(current.st_dev, parrent.st_dev); - CHECK_EQ(current.st_ino, parrent.st_ino); - CHECK_EQ(current.st_mode, parrent.st_mode); - CHECK_EQ(current.st_uid, parrent.st_uid); - CHECK_EQ(current.st_gid, parrent.st_gid); - return true; -} - -SANDBOX_TEST(Credentials, DropAllCaps) { - CHECK(Credentials::DropAllCapabilities()); - CHECK(!Credentials::HasAnyCapability()); -} - -SANDBOX_TEST(Credentials, MoveToNewUserNS) { - CHECK(Credentials::DropAllCapabilities()); - bool moved_to_new_ns = Credentials::MoveToNewUserNS(); - fprintf(stdout, - "Unprivileged CLONE_NEWUSER supported: %s\n", - moved_to_new_ns ? "true." : "false."); - fflush(stdout); - if (!moved_to_new_ns) { - fprintf(stdout, "This kernel does not support unprivileged namespaces. " - "USERNS tests will succeed without running.\n"); - fflush(stdout); - return; - } - CHECK(Credentials::HasAnyCapability()); - CHECK(Credentials::DropAllCapabilities()); - CHECK(!Credentials::HasAnyCapability()); -} - -SANDBOX_TEST(Credentials, CanCreateProcessInNewUserNS) { - CHECK(Credentials::DropAllCapabilities()); - bool user_ns_supported = Credentials::CanCreateProcessInNewUserNS(); - bool moved_to_new_ns = Credentials::MoveToNewUserNS(); - CHECK_EQ(user_ns_supported, moved_to_new_ns); -} - -SANDBOX_TEST(Credentials, UidIsPreserved) { - CHECK(Credentials::DropAllCapabilities()); - uid_t old_ruid, old_euid, old_suid; - gid_t old_rgid, old_egid, old_sgid; - PCHECK(0 == getresuid(&old_ruid, &old_euid, &old_suid)); - PCHECK(0 == getresgid(&old_rgid, &old_egid, &old_sgid)); - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) return; - uid_t new_ruid, new_euid, new_suid; - PCHECK(0 == getresuid(&new_ruid, &new_euid, &new_suid)); - CHECK(old_ruid == new_ruid); - CHECK(old_euid == new_euid); - CHECK(old_suid == new_suid); - - gid_t new_rgid, new_egid, new_sgid; - PCHECK(0 == getresgid(&new_rgid, &new_egid, &new_sgid)); - CHECK(old_rgid == new_rgid); - CHECK(old_egid == new_egid); - CHECK(old_sgid == new_sgid); -} - -bool NewUserNSCycle() { - if (!Credentials::MoveToNewUserNS() || - !Credentials::HasAnyCapability() || - !Credentials::DropAllCapabilities() || - Credentials::HasAnyCapability()) { - return false; - } - return true; -} - -SANDBOX_TEST(Credentials, NestedUserNS) { - CHECK(Credentials::DropAllCapabilities()); - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) return; - CHECK(Credentials::DropAllCapabilities()); - // As of 3.12, the kernel has a limit of 32. See create_user_ns(). - const int kNestLevel = 10; - for (int i = 0; i < kNestLevel; ++i) { - CHECK(NewUserNSCycle()) << "Creating new user NS failed at iteration " - << i << "."; - } -} - -// Test the WorkingDirectoryIsRoot() helper. -SANDBOX_TEST(Credentials, CanDetectRoot) { - PCHECK(0 == chdir("/proc/")); - CHECK(!WorkingDirectoryIsRoot()); - PCHECK(0 == chdir("/")); - CHECK(WorkingDirectoryIsRoot()); -} - -// Disabled on ASAN because of crbug.com/451603. -SANDBOX_TEST(Credentials, DISABLE_ON_ASAN(DropFileSystemAccessIsSafe)) { - CHECK(Credentials::HasFileSystemAccess()); - CHECK(Credentials::DropAllCapabilities()); - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) return; - CHECK(Credentials::DropFileSystemAccess(ProcUtil::OpenProc().get())); - CHECK(!Credentials::HasFileSystemAccess()); - CHECK(WorkingDirectoryIsRoot()); - CHECK(base::IsDirectoryEmpty(base::FilePath("/"))); - // We want the chroot to never have a subdirectory. A subdirectory - // could allow a chroot escape. - CHECK_NE(0, mkdir("/test", 0700)); -} - -// Check that after dropping filesystem access and dropping privileges -// it is not possible to regain capabilities. -SANDBOX_TEST(Credentials, DISABLE_ON_ASAN(CannotRegainPrivileges)) { - base::ScopedFD proc_fd(ProcUtil::OpenProc()); - CHECK(Credentials::DropAllCapabilities(proc_fd.get())); - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) return; - CHECK(Credentials::DropFileSystemAccess(proc_fd.get())); - CHECK(Credentials::DropAllCapabilities(proc_fd.get())); - - // The kernel should now prevent us from regaining capabilities because we - // are in a chroot. - CHECK(!Credentials::CanCreateProcessInNewUserNS()); - CHECK(!Credentials::MoveToNewUserNS()); -} - -SANDBOX_TEST(Credentials, SetCapabilities) { - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) - return; - - base::ScopedFD proc_fd(ProcUtil::OpenProc()); - - CHECK(Credentials::HasCapability(Credentials::Capability::SYS_ADMIN)); - CHECK(Credentials::HasCapability(Credentials::Capability::SYS_CHROOT)); - - std::vector<Credentials::Capability> caps; - caps.push_back(Credentials::Capability::SYS_CHROOT); - CHECK(Credentials::SetCapabilities(proc_fd.get(), caps)); - - CHECK(!Credentials::HasCapability(Credentials::Capability::SYS_ADMIN)); - CHECK(Credentials::HasCapability(Credentials::Capability::SYS_CHROOT)); - - const std::vector<Credentials::Capability> no_caps; - CHECK(Credentials::SetCapabilities(proc_fd.get(), no_caps)); - CHECK(!Credentials::HasAnyCapability()); -} - -SANDBOX_TEST(Credentials, SetCapabilitiesAndChroot) { - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) - return; - - base::ScopedFD proc_fd(ProcUtil::OpenProc()); - - CHECK(Credentials::HasCapability(Credentials::Capability::SYS_CHROOT)); - PCHECK(chroot("/") == 0); - - std::vector<Credentials::Capability> caps; - caps.push_back(Credentials::Capability::SYS_CHROOT); - CHECK(Credentials::SetCapabilities(proc_fd.get(), caps)); - PCHECK(chroot("/") == 0); - - CHECK(Credentials::DropAllCapabilities()); - PCHECK(chroot("/") == -1 && errno == EPERM); -} - -SANDBOX_TEST(Credentials, SetCapabilitiesMatchesLibCap2) { - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) - return; - - base::ScopedFD proc_fd(ProcUtil::OpenProc()); - - std::vector<Credentials::Capability> caps; - caps.push_back(Credentials::Capability::SYS_CHROOT); - CHECK(Credentials::SetCapabilities(proc_fd.get(), caps)); - - ScopedCap actual_cap(cap_get_proc()); - PCHECK(actual_cap != nullptr); - - ScopedCap expected_cap(cap_init()); - PCHECK(expected_cap != nullptr); - - const cap_value_t allowed_cap = CAP_SYS_CHROOT; - for (const cap_flag_t flag : {CAP_EFFECTIVE, CAP_PERMITTED}) { - PCHECK(cap_set_flag(expected_cap.get(), flag, 1, &allowed_cap, CAP_SET) == - 0); - } - - CHECK_EQ(0, cap_compare(expected_cap.get(), actual_cap.get())); -} - -volatile sig_atomic_t signal_handler_called; -void SignalHandler(int sig) { - signal_handler_called = 1; -} - -// glibc (and some other libcs) caches the PID and TID in TLS. This test -// verifies that these values are correct after DropFilesystemAccess. -// Disabled on ASAN because of crbug.com/451603. -SANDBOX_TEST(Credentials, DISABLE_ON_ASAN(DropFileSystemAccessPreservesTLS)) { - // Probably missing kernel support. - if (!Credentials::MoveToNewUserNS()) return; - CHECK(Credentials::DropFileSystemAccess(ProcUtil::OpenProc().get())); - - // The libc getpid implementation may return a cached PID. Ensure that - // it matches the PID returned from the getpid system call. - CHECK_EQ(sys_getpid(), getpid()); - - // raise uses the cached TID in glibc. - struct sigaction action = {}; - action.sa_handler = &SignalHandler; - PCHECK(sigaction(SIGUSR1, &action, nullptr) == 0); - - PCHECK(raise(SIGUSR1) == 0); - CHECK_EQ(1, signal_handler_called); -} - -} // namespace. - -} // namespace sandbox. diff --git a/sandbox/linux/services/init_process_reaper.cc b/sandbox/linux/services/init_process_reaper.cc deleted file mode 100644 index 2ff18b5dc2..0000000000 --- a/sandbox/linux/services/init_process_reaper.cc +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2013 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/linux/services/init_process_reaper.h" - -#include <signal.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "base/callback.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" - -namespace sandbox { - -namespace { - -void DoNothingSignalHandler(int signal) {} - -} // namespace - -bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback) { - int sync_fds[2]; - // We want to use send, so we can't use a pipe - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_fds)) { - PLOG(ERROR) << "Failed to create socketpair"; - return false; - } - pid_t child_pid = fork(); - if (child_pid == -1) { - int close_ret; - close_ret = IGNORE_EINTR(close(sync_fds[0])); - DPCHECK(!close_ret); - close_ret = IGNORE_EINTR(close(sync_fds[1])); - DPCHECK(!close_ret); - return false; - } - if (child_pid) { - // In the parent, assuming the role of an init process. - // The disposition for SIGCHLD cannot be SIG_IGN or wait() will only return - // once all of our childs are dead. Since we're init we need to reap childs - // as they come. - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = &DoNothingSignalHandler; - CHECK(sigaction(SIGCHLD, &action, NULL) == 0); - - int close_ret; - close_ret = IGNORE_EINTR(close(sync_fds[0])); - DPCHECK(!close_ret); - close_ret = shutdown(sync_fds[1], SHUT_RD); - DPCHECK(!close_ret); - if (post_fork_parent_callback) - post_fork_parent_callback->Run(); - // Tell the child to continue - CHECK(HANDLE_EINTR(send(sync_fds[1], "C", 1, MSG_NOSIGNAL)) == 1); - close_ret = IGNORE_EINTR(close(sync_fds[1])); - DPCHECK(!close_ret); - - for (;;) { - // Loop until we have reaped our one natural child - siginfo_t reaped_child_info; - int wait_ret = - HANDLE_EINTR(waitid(P_ALL, 0, &reaped_child_info, WEXITED)); - if (wait_ret) - _exit(1); - if (reaped_child_info.si_pid == child_pid) { - int exit_code = 0; - // We're done waiting - if (reaped_child_info.si_code == CLD_EXITED) { - exit_code = reaped_child_info.si_status; - } - // Exit with the same exit code as our child. Exit with 0 if we got - // signaled. - _exit(exit_code); - } - } - } else { - // The child needs to wait for the parent to run the callback to avoid a - // race condition. - int close_ret; - close_ret = IGNORE_EINTR(close(sync_fds[1])); - DPCHECK(!close_ret); - close_ret = shutdown(sync_fds[0], SHUT_WR); - DPCHECK(!close_ret); - char should_continue; - int read_ret = HANDLE_EINTR(read(sync_fds[0], &should_continue, 1)); - close_ret = IGNORE_EINTR(close(sync_fds[0])); - DPCHECK(!close_ret); - if (read_ret == 1) - return true; - else - return false; - } -} - -} // namespace sandbox. diff --git a/sandbox/linux/services/init_process_reaper.h b/sandbox/linux/services/init_process_reaper.h deleted file mode 100644 index 840f6fcda7..0000000000 --- a/sandbox/linux/services/init_process_reaper.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 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_LINUX_SERVICES_INIT_PROCESS_REAPER_H_ -#define SANDBOX_LINUX_SERVICES_INIT_PROCESS_REAPER_H_ - -#include "base/callback_forward.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// The current process will fork(). The parent will become a process reaper -// like init(1). The child will continue normally (after this function -// returns). -// If not NULL, |post_fork_parent_callback| will run in the parent almost -// immediately after fork(). -// Since this function calls fork(), it's very important that the caller has -// only one thread running. -SANDBOX_EXPORT bool CreateInitProcessReaper( - base::Closure* post_fork_parent_callback); - -} // namespace sandbox. - -#endif // SANDBOX_LINUX_SERVICES_INIT_PROCESS_REAPER_H_ diff --git a/sandbox/linux/services/namespace_sandbox.cc b/sandbox/linux/services/namespace_sandbox.cc deleted file mode 100644 index 00e59472ad..0000000000 --- a/sandbox/linux/services/namespace_sandbox.cc +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2015 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/linux/services/namespace_sandbox.h" - -#include <sched.h> -#include <signal.h> -#include <stddef.h> -#include <stdlib.h> -#include <sys/types.h> -#include <unistd.h> - -#include <string> -#include <utility> -#include <vector> - -#include "base/command_line.h" -#include "base/environment.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/launch.h" -#include "base/process/process.h" -#include "sandbox/linux/services/credentials.h" -#include "sandbox/linux/services/namespace_utils.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/system_headers/linux_signal.h" - -namespace sandbox { - -namespace { - -const char kSandboxUSERNSEnvironmentVarName[] = "SBX_USER_NS"; -const char kSandboxPIDNSEnvironmentVarName[] = "SBX_PID_NS"; -const char kSandboxNETNSEnvironmentVarName[] = "SBX_NET_NS"; - -#if !defined(OS_NACL_NONSFI) -class WriteUidGidMapDelegate : public base::LaunchOptions::PreExecDelegate { - public: - WriteUidGidMapDelegate() - : uid_(getuid()), - gid_(getgid()), - supports_deny_setgroups_( - NamespaceUtils::KernelSupportsDenySetgroups()) {} - - ~WriteUidGidMapDelegate() override {} - - void RunAsyncSafe() override { - if (supports_deny_setgroups_) { - RAW_CHECK(NamespaceUtils::DenySetgroups()); - } - RAW_CHECK(NamespaceUtils::WriteToIdMapFile("/proc/self/uid_map", uid_)); - RAW_CHECK(NamespaceUtils::WriteToIdMapFile("/proc/self/gid_map", gid_)); - } - - private: - const uid_t uid_; - const gid_t gid_; - const bool supports_deny_setgroups_; - DISALLOW_COPY_AND_ASSIGN(WriteUidGidMapDelegate); -}; - -void SetEnvironForNamespaceType(base::EnvironmentMap* environ, - base::NativeEnvironmentString env_var, - bool value) { - // An empty string causes the env var to be unset in the child process. - (*environ)[env_var] = value ? "1" : ""; -} -#endif // !defined(OS_NACL_NONSFI) - -// Linux supports up to 64 signals. This should be updated if that ever changes. -int g_signal_exit_codes[64]; - -void TerminationSignalHandler(int sig) { - // Return a special exit code so that the process is detected as terminated by - // a signal. - const size_t sig_idx = static_cast<size_t>(sig); - if (sig_idx < arraysize(g_signal_exit_codes)) { - _exit(g_signal_exit_codes[sig_idx]); - } - - _exit(NamespaceSandbox::SignalExitCode(sig)); -} - -} // namespace - -#if !defined(OS_NACL_NONSFI) -NamespaceSandbox::Options::Options() - : ns_types(CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET), - fail_on_unsupported_ns_type(false) {} - -NamespaceSandbox::Options::~Options() {} - -// static -base::Process NamespaceSandbox::LaunchProcess( - const base::CommandLine& cmdline, - const base::LaunchOptions& launch_options) { - return LaunchProcessWithOptions(cmdline.argv(), launch_options, Options()); -} - -// static -base::Process NamespaceSandbox::LaunchProcess( - const std::vector<std::string>& argv, - const base::LaunchOptions& launch_options) { - return LaunchProcessWithOptions(argv, launch_options, Options()); -} - -// static -base::Process NamespaceSandbox::LaunchProcessWithOptions( - const base::CommandLine& cmdline, - const base::LaunchOptions& launch_options, - const Options& ns_sandbox_options) { - return LaunchProcessWithOptions(cmdline.argv(), launch_options, - ns_sandbox_options); -} - -// static -base::Process NamespaceSandbox::LaunchProcessWithOptions( - const std::vector<std::string>& argv, - const base::LaunchOptions& launch_options, - const Options& ns_sandbox_options) { - // These fields may not be set by the caller. - CHECK(launch_options.pre_exec_delegate == nullptr); - CHECK_EQ(0, launch_options.clone_flags); - - int clone_flags = 0; - const int kSupportedTypes[] = {CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET}; - for (const int ns_type : kSupportedTypes) { - if ((ns_type & ns_sandbox_options.ns_types) == 0) { - continue; - } - - if (NamespaceUtils::KernelSupportsUnprivilegedNamespace(ns_type)) { - clone_flags |= ns_type; - } else if (ns_sandbox_options.fail_on_unsupported_ns_type) { - return base::Process(); - } - } - CHECK(clone_flags & CLONE_NEWUSER); - - WriteUidGidMapDelegate write_uid_gid_map_delegate; - - base::LaunchOptions launch_options_copy = launch_options; - launch_options_copy.pre_exec_delegate = &write_uid_gid_map_delegate; - launch_options_copy.clone_flags = clone_flags; - - const std::pair<int, const char*> clone_flag_environ[] = { - std::make_pair(CLONE_NEWUSER, kSandboxUSERNSEnvironmentVarName), - std::make_pair(CLONE_NEWPID, kSandboxPIDNSEnvironmentVarName), - std::make_pair(CLONE_NEWNET, kSandboxNETNSEnvironmentVarName), - }; - - base::EnvironmentMap* environ = &launch_options_copy.environ; - for (const auto& entry : clone_flag_environ) { - const int flag = entry.first; - const char* environ_name = entry.second; - SetEnvironForNamespaceType(environ, environ_name, clone_flags & flag); - } - - return base::LaunchProcess(argv, launch_options_copy); -} -#endif // !defined(OS_NACL_NONSFI) - -// static -pid_t NamespaceSandbox::ForkInNewPidNamespace(bool drop_capabilities_in_child) { - const pid_t pid = - base::ForkWithFlags(CLONE_NEWPID | LINUX_SIGCHLD, nullptr, nullptr); - if (pid < 0) { - return pid; - } - - if (pid == 0) { - DCHECK_EQ(1, getpid()); - if (drop_capabilities_in_child) { - // Since we just forked, we are single-threaded, so this should be safe. - CHECK(Credentials::DropAllCapabilitiesOnCurrentThread()); - } - return 0; - } - - return pid; -} - -// static -void NamespaceSandbox::InstallDefaultTerminationSignalHandlers() { - static const int kDefaultTermSignals[] = { - LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGABRT, LINUX_SIGQUIT, - LINUX_SIGPIPE, LINUX_SIGTERM, LINUX_SIGUSR1, LINUX_SIGUSR2, - }; - - for (const int sig : kDefaultTermSignals) { - InstallTerminationSignalHandler(sig, SignalExitCode(sig)); - } -} - -// static -bool NamespaceSandbox::InstallTerminationSignalHandler( - int sig, - int exit_code) { - struct sigaction old_action; - PCHECK(sys_sigaction(sig, nullptr, &old_action) == 0); - -#if !defined(OS_NACL_NONSFI) - if (old_action.sa_flags & SA_SIGINFO && - old_action.sa_sigaction != nullptr) { - return false; - } -#endif - - if (old_action.sa_handler != LINUX_SIG_DFL) { - return false; - } - - const size_t sig_idx = static_cast<size_t>(sig); - CHECK_LT(sig_idx, arraysize(g_signal_exit_codes)); - - DCHECK_GE(exit_code, 0); - DCHECK_LT(exit_code, 256); - - g_signal_exit_codes[sig_idx] = exit_code; - - struct sigaction action = {}; - action.sa_handler = &TerminationSignalHandler; - PCHECK(sys_sigaction(sig, &action, nullptr) == 0); - return true; -} - -// static -bool NamespaceSandbox::InNewUserNamespace() { - return getenv(kSandboxUSERNSEnvironmentVarName) != nullptr; -} - -// static -bool NamespaceSandbox::InNewPidNamespace() { - return getenv(kSandboxPIDNSEnvironmentVarName) != nullptr; -} - -// static -bool NamespaceSandbox::InNewNetNamespace() { - return getenv(kSandboxNETNSEnvironmentVarName) != nullptr; -} - -} // namespace sandbox diff --git a/sandbox/linux/services/namespace_sandbox.h b/sandbox/linux/services/namespace_sandbox.h deleted file mode 100644 index b5832fb5b4..0000000000 --- a/sandbox/linux/services/namespace_sandbox.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2015 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_LINUX_SERVICES_NAMESPACE_SANDBOX_H_ -#define SANDBOX_LINUX_SERVICES_NAMESPACE_SANDBOX_H_ - -#include <sys/types.h> - -#include <string> -#include <vector> - -#include "base/command_line.h" -#include "base/macros.h" -#include "base/process/launch.h" -#include "base/process/process.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// Helper class for starting a process inside a new user, PID, and network -// namespace. Before using a namespace sandbox, check for namespaces support -// using Credentials::CanCreateProcessInNewUserNS. -// -// A typical use for "A" launching a sandboxed process "B" would be: -// 1. A sets up a command line and launch options for process B. -// 2. A launches B with LaunchProcess. -// 3. B should be prepared to assume the role of init(1). In particular, apart -// from SIGKILL and SIGSTOP, B cannot receive any signal for which it does -// not have an explicit signal handler registered. -// If B dies, all the processes in the namespace will die. -// B can fork() and the parent can assume the role of init(1), by using -// CreateInitProcessReaper(). -// 4. B chroots using Credentials::MoveToNewUserNS() and -// Credentials::DropFileSystemAccess() -// 5. B drops capabilities gained by entering the new user namespace with -// Credentials::DropAllCapabilities(). -class SANDBOX_EXPORT NamespaceSandbox { - public: -#if !defined(OS_NACL_NONSFI) - struct Options { - Options(); - ~Options(); - - // Bitmask of namespace types. Must be some combination of CLONE_NEWUSER - // (required), CLONE_NEWPID, and CLONE_NEWNET. Defaults to all of the above. - int ns_types; - - // Fail if any of the namespace types are not supported. Defaults to false. - bool fail_on_unsupported_ns_type; - }; - - // Launch a new process inside its own user/PID/network namespaces (depending - // on kernel support). Requires at a minimum that user namespaces are - // supported (use Credentials::CanCreateProcessInNewUserNS to check this). - // - // pre_exec_delegate and clone_flags fields of LaunchOptions should be nullptr - // and 0, respectively, since this function makes a copy of options and - // overrides them. - static base::Process LaunchProcess(const base::CommandLine& cmdline, - const base::LaunchOptions& launch_options); - static base::Process LaunchProcess(const std::vector<std::string>& argv, - const base::LaunchOptions& launch_options); - - // Versions which take namespace sandbox options. These allow fine grained - // control over the types of namespaces used. - static base::Process LaunchProcessWithOptions( - const base::CommandLine& cmdline, - const base::LaunchOptions& launch_options, - const Options& ns_sandbox_options); - static base::Process LaunchProcessWithOptions( - const std::vector<std::string>& argv, - const base::LaunchOptions& launch_options, - const Options& ns_sandbox_options); -#endif // !defined(OS_NACL_NONSFI) - - // Forks a process in its own PID namespace. The child process is the init - // process inside of the PID namespace, so if the child needs to fork further, - // it should call CreateInitProcessReaper, which turns the init process into a - // reaper process. - // - // Otherwise, the child should setup handlers for signals which should - // terminate the process using InstallDefaultTerminationSignalHandlers or - // InstallTerminationSignalHandler. This works around the fact that init - // processes ignore such signals unless they have an explicit handler set. - // - // This function requries CAP_SYS_ADMIN. If |drop_capabilities_in_child| is - // true, then capabilities are dropped in the child. - static pid_t ForkInNewPidNamespace(bool drop_capabilities_in_child); - - // Installs a signal handler for: - // - // SIGHUP, SIGINT, SIGABRT, SIGQUIT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2 - // - // that exits with SignalExitCode(sig). These are signals whose default action - // is to terminate the program (apart from SIGILL, SIGFPE, and SIGSEGV, which - // will still terminate the process if e.g. an illegal instruction is - // encountered, etc.). - // - // If any of these already had a signal handler installed, this function will - // not override them. - static void InstallDefaultTerminationSignalHandlers(); - - // Installs a signal handler for |sig| which exits with |exit_code|. If a - // signal handler was already present for |sig|, does nothing and returns - // false. - static bool InstallTerminationSignalHandler(int sig, int exit_code); - - // Returns an exit code corresponding to the process being killed by sig. This - // is the same as exit code that NaCl's default signal handler uses. - static int SignalExitCode(int sig) { return -sig & 0xff; } - - // Returns whether the namespace sandbox created a new user, PID, and network - // namespace. In particular, InNewUserNamespace should return true iff the - // process was started via this class. - static bool InNewUserNamespace(); - static bool InNewPidNamespace(); - static bool InNewNetNamespace(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceSandbox); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_NAMESPACE_SANDBOX_H_ diff --git a/sandbox/linux/services/namespace_sandbox_unittest.cc b/sandbox/linux/services/namespace_sandbox_unittest.cc deleted file mode 100644 index c1acca678e..0000000000 --- a/sandbox/linux/services/namespace_sandbox_unittest.cc +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2015 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/linux/services/namespace_sandbox.h" - -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <string> -#include <utility> - -#include "base/command_line.h" -#include "base/files/file_enumerator.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/process/launch.h" -#include "base/process/process.h" -#include "base/test/multiprocess_test.h" -#include "sandbox/linux/services/credentials.h" -#include "sandbox/linux/services/namespace_utils.h" -#include "sandbox/linux/services/proc_util.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/multiprocess_func_list.h" - -namespace sandbox { - -namespace { - -bool RootDirectoryIsEmpty() { - base::FilePath root("/"); - int file_type = - base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES; - base::FileEnumerator enumerator_before(root, false, file_type); - return enumerator_before.Next().empty(); -} - -class NamespaceSandboxTest : public base::MultiProcessTest { - public: - void TestProc(const std::string& procname) { - TestProcWithOptions(procname, NamespaceSandbox::Options()); - } - - void TestProcWithOptions( - const std::string& procname, - const NamespaceSandbox::Options& ns_sandbox_options) { - if (!Credentials::CanCreateProcessInNewUserNS()) { - return; - } - - base::FileHandleMappingVector fds_to_remap = { - std::make_pair(STDOUT_FILENO, STDOUT_FILENO), - std::make_pair(STDERR_FILENO, STDERR_FILENO), - }; - base::LaunchOptions launch_options; - launch_options.fds_to_remap = &fds_to_remap; - - base::Process process = NamespaceSandbox::LaunchProcessWithOptions( - MakeCmdLine(procname), launch_options, ns_sandbox_options); - ASSERT_TRUE(process.IsValid()); - - const int kDummyExitCode = 42; - int exit_code = kDummyExitCode; - EXPECT_TRUE(process.WaitForExit(&exit_code)); - EXPECT_EQ(0, exit_code); - } -}; - -MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { - const bool in_user_ns = NamespaceSandbox::InNewUserNamespace(); - const bool in_pid_ns = NamespaceSandbox::InNewPidNamespace(); - const bool in_net_ns = NamespaceSandbox::InNewNetNamespace(); - CHECK(in_user_ns); - CHECK_EQ(in_pid_ns, - NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWPID)); - CHECK_EQ(in_net_ns, - NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWNET)); - if (in_pid_ns) { - CHECK_EQ(1, getpid()); - } - return 0; -} - -TEST_F(NamespaceSandboxTest, BasicUsage) { - TestProc("SimpleChildProcess"); -} - -MULTIPROCESS_TEST_MAIN(PidNsOnlyChildProcess) { - const bool in_user_ns = NamespaceSandbox::InNewUserNamespace(); - const bool in_pid_ns = NamespaceSandbox::InNewPidNamespace(); - const bool in_net_ns = NamespaceSandbox::InNewNetNamespace(); - CHECK(in_user_ns); - CHECK_EQ(in_pid_ns, - NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWPID)); - CHECK(!in_net_ns); - if (in_pid_ns) { - CHECK_EQ(1, getpid()); - } - return 0; -} - - -TEST_F(NamespaceSandboxTest, BasicUsageWithOptions) { - NamespaceSandbox::Options options; - options.ns_types = CLONE_NEWUSER | CLONE_NEWPID; - TestProcWithOptions("PidNsOnlyChildProcess", options); -} - -MULTIPROCESS_TEST_MAIN(ChrootMe) { - CHECK(!RootDirectoryIsEmpty()); - CHECK(sandbox::Credentials::MoveToNewUserNS()); - CHECK(sandbox::Credentials::DropFileSystemAccess(ProcUtil::OpenProc().get())); - CHECK(RootDirectoryIsEmpty()); - return 0; -} - -// Temporarily disabled on ASAN due to crbug.com/451603. -TEST_F(NamespaceSandboxTest, DISABLE_ON_ASAN(ChrootAndDropCapabilities)) { - TestProc("ChrootMe"); -} - -MULTIPROCESS_TEST_MAIN(NestedNamespaceSandbox) { - base::FileHandleMappingVector fds_to_remap = { - std::make_pair(STDOUT_FILENO, STDOUT_FILENO), - std::make_pair(STDERR_FILENO, STDERR_FILENO), - }; - base::LaunchOptions launch_options; - launch_options.fds_to_remap = &fds_to_remap; - base::Process process = NamespaceSandbox::LaunchProcess( - base::CommandLine(base::FilePath("/bin/true")), launch_options); - CHECK(process.IsValid()); - - const int kDummyExitCode = 42; - int exit_code = kDummyExitCode; - CHECK(process.WaitForExit(&exit_code)); - CHECK_EQ(0, exit_code); - return 0; -} - -TEST_F(NamespaceSandboxTest, NestedNamespaceSandbox) { - TestProc("NestedNamespaceSandbox"); -} - -const int kNormalExitCode = 0; - -// Ensure that CHECK(false) is distinguishable from _exit(kNormalExitCode). -// Allowing noise since CHECK(false) will write a stack trace to stderr. -SANDBOX_TEST_ALLOW_NOISE(ForkInNewPidNamespace, CheckDoesNotReturnZero) { - if (!Credentials::CanCreateProcessInNewUserNS()) { - return; - } - - CHECK(sandbox::Credentials::MoveToNewUserNS()); - const pid_t pid = NamespaceSandbox::ForkInNewPidNamespace( - /*drop_capabilities_in_child=*/true); - CHECK_GE(pid, 0); - - if (pid == 0) { - CHECK(false); - _exit(kNormalExitCode); - } - - int status; - PCHECK(waitpid(pid, &status, 0) == pid); - if (WIFEXITED(status)) { - CHECK_NE(kNormalExitCode, WEXITSTATUS(status)); - } -} - -SANDBOX_TEST(ForkInNewPidNamespace, BasicUsage) { - if (!Credentials::CanCreateProcessInNewUserNS()) { - return; - } - - CHECK(sandbox::Credentials::MoveToNewUserNS()); - const pid_t pid = NamespaceSandbox::ForkInNewPidNamespace( - /*drop_capabilities_in_child=*/true); - CHECK_GE(pid, 0); - - if (pid == 0) { - CHECK_EQ(1, getpid()); - CHECK(!Credentials::HasAnyCapability()); - _exit(kNormalExitCode); - } - - int status; - PCHECK(waitpid(pid, &status, 0) == pid); - CHECK(WIFEXITED(status)); - CHECK_EQ(kNormalExitCode, WEXITSTATUS(status)); -} - -SANDBOX_TEST(ForkInNewPidNamespace, ExitWithSignal) { - if (!Credentials::CanCreateProcessInNewUserNS()) { - return; - } - - CHECK(sandbox::Credentials::MoveToNewUserNS()); - const pid_t pid = NamespaceSandbox::ForkInNewPidNamespace( - /*drop_capabilities_in_child=*/true); - CHECK_GE(pid, 0); - - if (pid == 0) { - CHECK_EQ(1, getpid()); - CHECK(!Credentials::HasAnyCapability()); - CHECK(NamespaceSandbox::InstallTerminationSignalHandler( - SIGTERM, NamespaceSandbox::SignalExitCode(SIGTERM))); - while (true) { - raise(SIGTERM); - } - } - - int status; - PCHECK(waitpid(pid, &status, 0) == pid); - CHECK(WIFEXITED(status)); - CHECK_EQ(NamespaceSandbox::SignalExitCode(SIGTERM), WEXITSTATUS(status)); -} - -volatile sig_atomic_t signal_handler_called; -void ExitSuccessfully(int sig) { - signal_handler_called = 1; -} - -SANDBOX_TEST(InstallTerminationSignalHandler, DoesNotOverrideExistingHandlers) { - struct sigaction action = {}; - action.sa_handler = &ExitSuccessfully; - PCHECK(sigaction(SIGUSR1, &action, nullptr) == 0); - - NamespaceSandbox::InstallDefaultTerminationSignalHandlers(); - CHECK(!NamespaceSandbox::InstallTerminationSignalHandler( - SIGUSR1, NamespaceSandbox::SignalExitCode(SIGUSR1))); - - raise(SIGUSR1); - CHECK_EQ(1, signal_handler_called); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/services/namespace_utils.cc b/sandbox/linux/services/namespace_utils.cc deleted file mode 100644 index 97add26f8f..0000000000 --- a/sandbox/linux/services/namespace_utils.cc +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2015 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/linux/services/namespace_utils.h" - -#include <fcntl.h> -#include <sched.h> -#include <stddef.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include <string> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/launch.h" -#include "base/strings/safe_sprintf.h" -#include "base/third_party/valgrind/valgrind.h" - -namespace sandbox { - -namespace { -bool IsRunningOnValgrind() { - return RUNNING_ON_VALGRIND; -} - -const char kProcSelfSetgroups[] = "/proc/self/setgroups"; -} // namespace - -// static -bool NamespaceUtils::WriteToIdMapFile(const char* map_file, generic_id_t id) { - // This function needs to be async-signal-safe, as it may be called in between - // fork and exec. - - int fd = HANDLE_EINTR(open(map_file, O_WRONLY)); - if (fd == -1) { - return false; - } - - const generic_id_t inside_id = id; - const generic_id_t outside_id = id; - - char mapping[64]; - const ssize_t len = - base::strings::SafeSPrintf(mapping, "%d %d 1\n", inside_id, outside_id); - const ssize_t rc = HANDLE_EINTR(write(fd, mapping, len)); - RAW_CHECK(IGNORE_EINTR(close(fd)) == 0); - return rc == len; -} - -// static -bool NamespaceUtils::KernelSupportsUnprivilegedNamespace(int type) { - // Valgrind will let clone(2) pass-through, but doesn't support unshare(), - // so always consider namespaces unsupported there. - if (IsRunningOnValgrind()) { - return false; - } - - // As of Linux 3.8, /proc/self/ns/* files exist for all namespace types. Since - // user namespaces were added in 3.8, it is OK to rely on the existence of - // /proc/self/ns/*. - if (!base::PathExists(base::FilePath("/proc/self/ns/user"))) { - return false; - } - - const char* path; - switch (type) { - case CLONE_NEWUSER: - return true; - case CLONE_NEWIPC: - path = "/proc/self/ns/ipc"; - break; - case CLONE_NEWNET: - path = "/proc/self/ns/net"; - break; - case CLONE_NEWNS: - path = "/proc/self/ns/mnt"; - break; - case CLONE_NEWPID: - path = "/proc/self/ns/pid"; - break; - case CLONE_NEWUTS: - path = "/proc/self/ns/uts"; - break; - default: - NOTREACHED(); - return false; - } - - return base::PathExists(base::FilePath(path)); -} - -// static -bool NamespaceUtils::KernelSupportsDenySetgroups() { - return base::PathExists(base::FilePath(kProcSelfSetgroups)); -} - -// static -bool NamespaceUtils::DenySetgroups() { - // This function needs to be async-signal-safe. - int fd = HANDLE_EINTR(open(kProcSelfSetgroups, O_WRONLY)); - if (fd == -1) { - return false; - } - - static const char kDeny[] = "deny"; - const ssize_t len = sizeof(kDeny) - 1; - const ssize_t rc = HANDLE_EINTR(write(fd, kDeny, len)); - RAW_CHECK(IGNORE_EINTR(close(fd)) == 0); - return rc == len; -} - -} // namespace sandbox diff --git a/sandbox/linux/services/namespace_utils.h b/sandbox/linux/services/namespace_utils.h deleted file mode 100644 index ec5d24129a..0000000000 --- a/sandbox/linux/services/namespace_utils.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015 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_LINUX_SERVICES_NAMESPACE_UTILS_H_ -#define SANDBOX_LINUX_SERVICES_NAMESPACE_UTILS_H_ - -#include <sys/types.h> - -#include <type_traits> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// Utility functions for using Linux namepaces. -class SANDBOX_EXPORT NamespaceUtils { - public: - static_assert(std::is_same<uid_t, gid_t>::value, - "uid_t and gid_t must be the same type"); - // generic_id_t can be used for either uid_t or gid_t. - typedef uid_t generic_id_t; - - // Write a uid or gid mapping from |id| to |id| in |map_file|. This function - // is async-signal-safe. - static bool WriteToIdMapFile(const char* map_file, - generic_id_t id) WARN_UNUSED_RESULT; - - // Returns true if unprivileged namespaces of type |type| is supported - // (meaning that both CLONE_NEWUSER and type are are supported). |type| must - // be one of CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, - // CLONE_NEWUSER, or CLONE_NEWUTS. This relies on access to /proc, so it will - // not work from within a sandbox. - static bool KernelSupportsUnprivilegedNamespace(int type); - - // Returns true if the kernel supports denying setgroups in a user namespace. - // On kernels where this is supported, DenySetgroups must be called before a - // gid mapping can be added. - static bool KernelSupportsDenySetgroups(); - - // Disables setgroups() within the current user namespace. On Linux 3.18.2 and - // later, this is required in order to write to /proc/self/gid_map without - // having CAP_SETGID. Callers can determine whether is this needed with - // KernelSupportsDenySetgroups. This function is async-signal-safe. - static bool DenySetgroups() WARN_UNUSED_RESULT; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceUtils); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_NAMESPACE_UTILS_H_ diff --git a/sandbox/linux/services/namespace_utils_unittest.cc b/sandbox/linux/services/namespace_utils_unittest.cc deleted file mode 100644 index 41ed7e89a6..0000000000 --- a/sandbox/linux/services/namespace_utils_unittest.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2015 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/linux/services/namespace_utils.h" - -#include <errno.h> -#include <sched.h> -#include <sys/types.h> -#include <sys/wait.h> - -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/launch.h" -#include "sandbox/linux/services/credentials.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace { - -SANDBOX_TEST(NamespaceUtils, KernelSupportsUnprivilegedNamespace) { - const bool can_create_user_ns = Credentials::CanCreateProcessInNewUserNS(); - const bool supports_user_ns = - NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWUSER); - // can_create_user_ns implies supports_user_ns, but the converse is not - // necessarily true, as creating a user namespace can fail for various - // reasons. - if (can_create_user_ns) { - SANDBOX_ASSERT(supports_user_ns); - } -} - -SANDBOX_TEST(NamespaceUtils, WriteToIdMapFile) { - if (!Credentials::CanCreateProcessInNewUserNS()) { - return; - } - - const uid_t uid = getuid(); - const gid_t gid = getgid(); - - const bool supports_deny_setgroups = - NamespaceUtils::KernelSupportsDenySetgroups(); - - const pid_t pid = - base::ForkWithFlags(CLONE_NEWUSER | SIGCHLD, nullptr, nullptr); - ASSERT_NE(-1, pid); - if (pid == 0) { - if (supports_deny_setgroups) { - RAW_CHECK(NamespaceUtils::DenySetgroups()); - } - - RAW_CHECK(getuid() != uid); - RAW_CHECK(NamespaceUtils::WriteToIdMapFile("/proc/self/uid_map", uid)); - RAW_CHECK(getuid() == uid); - - RAW_CHECK(getgid() != gid); - RAW_CHECK(NamespaceUtils::WriteToIdMapFile("/proc/self/gid_map", gid)); - RAW_CHECK(getgid() == gid); - - _exit(0); - } - - int status = 42; - SANDBOX_ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); - SANDBOX_ASSERT_EQ(0, status); -} - -} // namespace. - -} // namespace sandbox. diff --git a/sandbox/linux/services/proc_util.cc b/sandbox/linux/services/proc_util.cc deleted file mode 100644 index b6d58de564..0000000000 --- a/sandbox/linux/services/proc_util.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2014 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/linux/services/proc_util.h" - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <memory> - -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/strings/string_number_conversions.h" - -namespace sandbox { -namespace { - -struct DIRCloser { - void operator()(DIR* d) const { - DCHECK(d); - PCHECK(0 == closedir(d)); - } -}; - -typedef std::unique_ptr<DIR, DIRCloser> ScopedDIR; - -base::ScopedFD OpenDirectory(const char* path) { - DCHECK(path); - base::ScopedFD directory_fd( - HANDLE_EINTR(open(path, O_RDONLY | O_DIRECTORY | O_CLOEXEC))); - PCHECK(directory_fd.is_valid()); - return directory_fd; -} - -} // namespace - -int ProcUtil::CountOpenFds(int proc_fd) { - DCHECK_LE(0, proc_fd); - int proc_self_fd = HANDLE_EINTR( - openat(proc_fd, "self/fd/", O_DIRECTORY | O_RDONLY | O_CLOEXEC)); - PCHECK(0 <= proc_self_fd); - - // Ownership of proc_self_fd is transferred here, it must not be closed - // or modified afterwards except via dir. - ScopedDIR dir(fdopendir(proc_self_fd)); - CHECK(dir); - - int count = 0; - struct dirent e; - struct dirent* de; - while (!readdir_r(dir.get(), &e, &de) && de) { - if (strcmp(e.d_name, ".") == 0 || strcmp(e.d_name, "..") == 0) { - continue; - } - - int fd_num; - CHECK(base::StringToInt(e.d_name, &fd_num)); - if (fd_num == proc_fd || fd_num == proc_self_fd) { - continue; - } - - ++count; - } - return count; -} - -bool ProcUtil::HasOpenDirectory(int proc_fd) { - DCHECK_LE(0, proc_fd); - int proc_self_fd = - openat(proc_fd, "self/fd/", O_DIRECTORY | O_RDONLY | O_CLOEXEC); - - PCHECK(0 <= proc_self_fd); - - // Ownership of proc_self_fd is transferred here, it must not be closed - // or modified afterwards except via dir. - ScopedDIR dir(fdopendir(proc_self_fd)); - CHECK(dir); - - struct dirent e; - struct dirent* de; - while (!readdir_r(dir.get(), &e, &de) && de) { - if (strcmp(e.d_name, ".") == 0 || strcmp(e.d_name, "..") == 0) { - continue; - } - - int fd_num; - CHECK(base::StringToInt(e.d_name, &fd_num)); - if (fd_num == proc_fd || fd_num == proc_self_fd) { - continue; - } - - struct stat s; - // It's OK to use proc_self_fd here, fstatat won't modify it. - CHECK(fstatat(proc_self_fd, e.d_name, &s, 0) == 0); - if (S_ISDIR(s.st_mode)) { - return true; - } - } - - // No open unmanaged directories found. - return false; -} - -bool ProcUtil::HasOpenDirectory() { - base::ScopedFD proc_fd( - HANDLE_EINTR(open("/proc/", O_DIRECTORY | O_RDONLY | O_CLOEXEC))); - return HasOpenDirectory(proc_fd.get()); -} - -// static -base::ScopedFD ProcUtil::OpenProc() { - return OpenDirectory("/proc/"); -} - -} // namespace sandbox diff --git a/sandbox/linux/services/proc_util.h b/sandbox/linux/services/proc_util.h deleted file mode 100644 index bc14c5ef2a..0000000000 --- a/sandbox/linux/services/proc_util.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2014 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_LINUX_SERVICES_PROC_UTIL_H_ -#define SANDBOX_LINUX_SERVICES_PROC_UTIL_H_ - -#include "base/files/scoped_file.h" -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -class SANDBOX_EXPORT ProcUtil { - public: - // Returns the number of file descriptors in the current process's FD - // table, excluding |proc_fd|, which should be a file descriptor for - // /proc/. - static int CountOpenFds(int proc_fd); - - // Checks whether the current process has any directory file descriptor open. - // Directory file descriptors are "capabilities" that would let a process use - // system calls such as openat() to bypass restrictions such as - // DropFileSystemAccess(). - // Sometimes it's useful to call HasOpenDirectory() after file system access - // has been dropped. In this case, |proc_fd| should be a file descriptor to - // /proc/. The file descriptor in |proc_fd| will be ignored by - // HasOpenDirectory() and remains owned by the caller. It is very important - // for the caller to close it. - static bool HasOpenDirectory(int proc_fd) WARN_UNUSED_RESULT; - static bool HasOpenDirectory() WARN_UNUSED_RESULT; - - // Open /proc/ or crash if not possible. - static base::ScopedFD OpenProc(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(ProcUtil); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_PROC_UTIL_H_ diff --git a/sandbox/linux/services/proc_util_unittest.cc b/sandbox/linux/services/proc_util_unittest.cc deleted file mode 100644 index bf25151956..0000000000 --- a/sandbox/linux/services/proc_util_unittest.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 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/linux/services/proc_util.h" - -#include <fcntl.h> -#include <unistd.h> - -#include "base/files/scoped_file.h" -#include "base/posix/eintr_wrapper.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -TEST(ProcUtil, CountOpenFds) { - base::ScopedFD proc_fd(open("/proc/", O_RDONLY | O_DIRECTORY)); - ASSERT_TRUE(proc_fd.is_valid()); - int fd_count = ProcUtil::CountOpenFds(proc_fd.get()); - int fd = open("/dev/null", O_RDONLY); - ASSERT_LE(0, fd); - EXPECT_EQ(fd_count + 1, ProcUtil::CountOpenFds(proc_fd.get())); - ASSERT_EQ(0, IGNORE_EINTR(close(fd))); - EXPECT_EQ(fd_count, ProcUtil::CountOpenFds(proc_fd.get())); -} - -TEST(ProcUtil, HasOpenDirectory) { - // No open directory should exist at startup. - EXPECT_FALSE(ProcUtil::HasOpenDirectory()); - { - // Have a "/proc" file descriptor around. - int proc_fd = open("/proc/", O_RDONLY | O_DIRECTORY); - base::ScopedFD proc_fd_closer(proc_fd); - EXPECT_TRUE(ProcUtil::HasOpenDirectory()); - } - EXPECT_FALSE(ProcUtil::HasOpenDirectory()); -} - -TEST(ProcUtil, HasOpenDirectoryWithFD) { - int proc_fd = open("/proc/", O_RDONLY | O_DIRECTORY); - base::ScopedFD proc_fd_closer(proc_fd); - ASSERT_LE(0, proc_fd); - - // Don't pass |proc_fd|, an open directory (proc_fd) should - // be detected. - EXPECT_TRUE(ProcUtil::HasOpenDirectory()); - // Pass |proc_fd| and no open directory should be detected. - EXPECT_FALSE(ProcUtil::HasOpenDirectory(proc_fd)); - - { - // Have a directory file descriptor around. - int open_directory_fd = open("/proc/self/", O_RDONLY | O_DIRECTORY); - base::ScopedFD open_directory_fd_closer(open_directory_fd); - EXPECT_TRUE(ProcUtil::HasOpenDirectory(proc_fd)); - } - - // The "/proc/" file descriptor should now be closed, |proc_fd| is the - // only directory file descriptor open. - EXPECT_FALSE(ProcUtil::HasOpenDirectory(proc_fd)); -} - -} // namespace sandbox diff --git a/sandbox/linux/services/resource_limits.cc b/sandbox/linux/services/resource_limits.cc deleted file mode 100644 index 1ec11295d1..0000000000 --- a/sandbox/linux/services/resource_limits.cc +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015 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/linux/services/resource_limits.h" - -#include <sys/resource.h> -#include <sys/time.h> - -#include <algorithm> - -namespace sandbox { - -// static -bool ResourceLimits::Lower(int resource, rlim_t limit) { - struct rlimit old_rlimit; - if (getrlimit(resource, &old_rlimit)) - return false; - // Make sure we don't raise the existing limit. - const struct rlimit new_rlimit = {std::min(old_rlimit.rlim_cur, limit), - std::min(old_rlimit.rlim_max, limit)}; - int rc = setrlimit(resource, &new_rlimit); - return rc == 0; -} - -} // namespace sandbox diff --git a/sandbox/linux/services/resource_limits.h b/sandbox/linux/services/resource_limits.h deleted file mode 100644 index 3464dab679..0000000000 --- a/sandbox/linux/services/resource_limits.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 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_LINUX_SERVICES_RESOURCE_LIMITS_H_ -#define SANDBOX_LINUX_SERVICES_RESOURCE_LIMITS_H_ - -#include <sys/resource.h> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// This class provides a small wrapper around setrlimit(). -class SANDBOX_EXPORT ResourceLimits { - public: - // Lower the soft and hard limit of |resource| to |limit|. If the current - // limit is lower than |limit|, keep it. - static bool Lower(int resource, rlim_t limit) WARN_UNUSED_RESULT; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(ResourceLimits); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_RESOURCE_LIMITS_H_ diff --git a/sandbox/linux/services/resource_limits_unittests.cc b/sandbox/linux/services/resource_limits_unittests.cc deleted file mode 100644 index 910c740f7b..0000000000 --- a/sandbox/linux/services/resource_limits_unittests.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 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/linux/services/resource_limits.h" - -#include <errno.h> -#include <sys/resource.h> -#include <sys/time.h> -#include <unistd.h> - -#include "base/logging.h" -#include "sandbox/linux/tests/test_utils.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace { - -// Fails on Android: crbug.com/459158 -#if !defined(OS_ANDROID) -#define MAYBE_NoFork DISABLE_ON_ASAN(NoFork) -#else -#define MAYBE_NoFork DISABLED_NoFork -#endif // OS_ANDROID - -// Not being able to fork breaks LeakSanitizer, so disable on -// all ASAN builds. -SANDBOX_TEST(ResourceLimits, MAYBE_NoFork) { - // Make sure that fork will fail with EAGAIN. - SANDBOX_ASSERT(ResourceLimits::Lower(RLIMIT_NPROC, 0)); - errno = 0; - pid_t pid = fork(); - // Reap any child if fork succeeded. - TestUtils::HandlePostForkReturn(pid); - SANDBOX_ASSERT_EQ(-1, pid); - CHECK_EQ(EAGAIN, errno); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/services/scoped_process.cc b/sandbox/linux/services/scoped_process.cc deleted file mode 100644 index 65af4873a4..0000000000 --- a/sandbox/linux/services/scoped_process.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2014 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/linux/services/scoped_process.h" - -#include <fcntl.h> -#include <signal.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "base/callback.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "build/build_config.h" -#include "sandbox/linux/services/syscall_wrappers.h" -#include "sandbox/linux/services/thread_helpers.h" - -namespace sandbox { - -namespace { - -const char kSynchronisationChar[] = "D"; - -void WaitForever() { - while(true) { - pause(); - } -} - -} // namespace - -ScopedProcess::ScopedProcess(const base::Closure& child_callback) - : child_process_id_(-1), process_id_(getpid()) { - PCHECK(0 == pipe(pipe_fds_)); -#if !defined(THREAD_SANITIZER) - // Make sure that we can safely fork(). - CHECK(ThreadHelpers::IsSingleThreaded()); -#endif - child_process_id_ = fork(); - PCHECK(0 <= child_process_id_); - - if (0 == child_process_id_) { - PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[0]))); - pipe_fds_[0] = -1; - child_callback.Run(); - // Notify the parent that the closure has run. - CHECK_EQ(1, HANDLE_EINTR(write(pipe_fds_[1], kSynchronisationChar, 1))); - WaitForever(); - NOTREACHED(); - _exit(1); - } - - PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[1]))); - pipe_fds_[1] = -1; -} - -ScopedProcess::~ScopedProcess() { - CHECK(IsOriginalProcess()); - if (child_process_id_ >= 0) { - PCHECK(0 == kill(child_process_id_, SIGKILL)); - siginfo_t process_info; - - PCHECK(0 == HANDLE_EINTR( - waitid(P_PID, child_process_id_, &process_info, WEXITED))); - } - if (pipe_fds_[0] >= 0) { - PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[0]))); - } - if (pipe_fds_[1] >= 0) { - PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[1]))); - } -} - -int ScopedProcess::WaitForExit(bool* got_signaled) { - DCHECK(got_signaled); - CHECK(IsOriginalProcess()); - siginfo_t process_info; - // WNOWAIT to make sure that the destructor can wait on the child. - int ret = HANDLE_EINTR( - waitid(P_PID, child_process_id_, &process_info, WEXITED | WNOWAIT)); - PCHECK(0 == ret) << "Did something else wait on the child?"; - - if (process_info.si_code == CLD_EXITED) { - *got_signaled = false; - } else if (process_info.si_code == CLD_KILLED || - process_info.si_code == CLD_DUMPED) { - *got_signaled = true; - } else { - CHECK(false) << "ScopedProcess needs to be extended for si_code " - << process_info.si_code; - } - return process_info.si_status; -} - -bool ScopedProcess::WaitForClosureToRun() { - char c = 0; - int ret = HANDLE_EINTR(read(pipe_fds_[0], &c, 1)); - PCHECK(ret >= 0); - if (0 == ret) - return false; - - CHECK_EQ(c, kSynchronisationChar[0]); - return true; -} - -// It would be problematic if after a fork(), another process would start using -// this object. -// This method allows to assert it is not happening. -bool ScopedProcess::IsOriginalProcess() { - // Make a direct syscall to bypass glibc caching of PIDs. - pid_t pid = sys_getpid(); - return pid == process_id_; -} - -} // namespace sandbox diff --git a/sandbox/linux/services/scoped_process.h b/sandbox/linux/services/scoped_process.h deleted file mode 100644 index bddbd5529b..0000000000 --- a/sandbox/linux/services/scoped_process.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 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_LINUX_SERVICES_SCOPED_PROCESS_H_ -#define SANDBOX_LINUX_SERVICES_SCOPED_PROCESS_H_ - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/process/process_handle.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// fork() a child process that will run a Closure. -// After the Closure has run, the child will pause forever. If this object -// is detroyed, the child will be destroyed, even if the closure did not -// finish running. It's ok to signal the child from outside of this class to -// destroy it. -// This class cannot be instanciated from a multi-threaded process, as it needs -// to fork(). -class SANDBOX_EXPORT ScopedProcess { - public: - // A new process will be created and |child_callback| will run in the child - // process. This callback is allowed to terminate the process or to simply - // return. If the callback returns, the process will wait forever. - explicit ScopedProcess(const base::Closure& child_callback); - ~ScopedProcess(); - - // Wait for the process to exit. - // |got_signaled| tells how to interpret the return value: either as an exit - // code, or as a signal number. - // When this returns, the process will still not have been reaped and will - // survive as a zombie for the lifetime of this object. This method can be - // called multiple times. - int WaitForExit(bool* got_signaled); - - // Wait for the |child_callback| passed at construction to run. Return false - // if |child_callback| did not finish running and we know it never will (for - // instance the child crashed or used _exit()). - bool WaitForClosureToRun(); - base::ProcessId GetPid() { return child_process_id_; } - - private: - bool IsOriginalProcess(); - - base::ProcessId child_process_id_; - base::ProcessId process_id_; - int pipe_fds_[2]; - DISALLOW_COPY_AND_ASSIGN(ScopedProcess); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_SCOPED_PROCESS_H_ diff --git a/sandbox/linux/services/scoped_process_unittest.cc b/sandbox/linux/services/scoped_process_unittest.cc deleted file mode 100644 index 86f97a8cf4..0000000000 --- a/sandbox/linux/services/scoped_process_unittest.cc +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2014 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/linux/services/scoped_process.h" - -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/threading/platform_thread.h" -#include "base/time/time.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace { - -void DoExit() { _exit(0); } - -void ExitWithCode(int exit_code) { _exit(exit_code); } - -void RaiseAndExit(int signal) { - PCHECK(0 == raise(signal)); - _exit(0); -} - -TEST(ScopedProcess, ScopedProcessNormalExit) { - const int kCustomExitCode = 12; - ScopedProcess process(base::Bind(&ExitWithCode, kCustomExitCode)); - bool got_signaled = true; - int exit_code = process.WaitForExit(&got_signaled); - EXPECT_FALSE(got_signaled); - EXPECT_EQ(kCustomExitCode, exit_code); - - // Verify that WaitForExit() can be called multiple times on the same - // process. - bool got_signaled2 = true; - int exit_code2 = process.WaitForExit(&got_signaled2); - EXPECT_FALSE(got_signaled2); - EXPECT_EQ(kCustomExitCode, exit_code2); -} - -// Disable this test on Android, SIGABRT is funky there. -TEST(ScopedProcess, DISABLE_ON_ANDROID(ScopedProcessAbort)) { - PCHECK(SIG_ERR != signal(SIGABRT, SIG_DFL)); - ScopedProcess process(base::Bind(&RaiseAndExit, SIGABRT)); - bool got_signaled = false; - int exit_code = process.WaitForExit(&got_signaled); - EXPECT_TRUE(got_signaled); - EXPECT_EQ(SIGABRT, exit_code); -} - -TEST(ScopedProcess, ScopedProcessSignaled) { - ScopedProcess process(base::Bind(&base::DoNothing)); - bool got_signaled = false; - ASSERT_EQ(0, kill(process.GetPid(), SIGKILL)); - int exit_code = process.WaitForExit(&got_signaled); - EXPECT_TRUE(got_signaled); - EXPECT_EQ(SIGKILL, exit_code); -} - -TEST(ScopedProcess, DiesForReal) { - int pipe_fds[2]; - ASSERT_EQ(0, pipe(pipe_fds)); - base::ScopedFD read_end_closer(pipe_fds[0]); - base::ScopedFD write_end_closer(pipe_fds[1]); - - { ScopedProcess process(base::Bind(&DoExit)); } - - // Close writing end of the pipe. - write_end_closer.reset(); - pipe_fds[1] = -1; - - ASSERT_EQ(0, fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK)); - char c; - // If the child process is dead for real, there will be no writing end - // for this pipe left and read will EOF instead of returning EWOULDBLOCK. - ASSERT_EQ(0, read(pipe_fds[0], &c, 1)); -} - -TEST(ScopedProcess, SynchronizationBasic) { - ScopedProcess process1(base::Bind(&base::DoNothing)); - EXPECT_TRUE(process1.WaitForClosureToRun()); - - ScopedProcess process2(base::Bind(&DoExit)); - // The closure didn't finish running normally. This case is simple enough - // that process.WaitForClosureToRun() should return false, even though the - // API does not guarantees that it will return at all. - EXPECT_FALSE(process2.WaitForClosureToRun()); -} - -void SleepInMsAndWriteOneByte(int time_to_sleep, int fd) { - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(time_to_sleep)); - CHECK(1 == write(fd, "1", 1)); -} - -TEST(ScopedProcess, SynchronizationWorks) { - int pipe_fds[2]; - ASSERT_EQ(0, pipe(pipe_fds)); - base::ScopedFD read_end_closer(pipe_fds[0]); - base::ScopedFD write_end_closer(pipe_fds[1]); - - // Start a process with a closure that takes a little bit to run. - ScopedProcess process( - base::Bind(&SleepInMsAndWriteOneByte, 100, pipe_fds[1])); - EXPECT_TRUE(process.WaitForClosureToRun()); - - // Verify that the closure did, indeed, run. - ASSERT_EQ(0, fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK)); - char c = 0; - EXPECT_EQ(1, read(pipe_fds[0], &c, 1)); - EXPECT_EQ('1', c); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/services/syscall_wrappers.cc b/sandbox/linux/services/syscall_wrappers.cc deleted file mode 100644 index 9c7727cee5..0000000000 --- a/sandbox/linux/services/syscall_wrappers.cc +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2014 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/linux/services/syscall_wrappers.h" - -#include <pthread.h> -#include <sched.h> -#include <setjmp.h> -#include <sys/resource.h> -#include <sys/syscall.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <cstring> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/third_party/valgrind/valgrind.h" -#include "build/build_config.h" -#include "sandbox/linux/system_headers/capability.h" -#include "sandbox/linux/system_headers/linux_signal.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -namespace sandbox { - -pid_t sys_getpid(void) { - return syscall(__NR_getpid); -} - -pid_t sys_gettid(void) { - return syscall(__NR_gettid); -} - -ssize_t sys_write(int fd, const char* buffer, size_t buffer_size) { - return syscall(__NR_write, fd, buffer, buffer_size); -} - -long sys_clone(unsigned long flags, - std::nullptr_t child_stack, - pid_t* ptid, - pid_t* ctid, - std::nullptr_t tls) { - const bool clone_tls_used = flags & CLONE_SETTLS; - const bool invalid_ctid = - (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid; - const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid; - - // We do not support CLONE_VM. - const bool clone_vm_used = flags & CLONE_VM; - if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) { - RAW_LOG(FATAL, "Invalid usage of sys_clone"); - } - - if (ptid) MSAN_UNPOISON(ptid, sizeof(*ptid)); - if (ctid) MSAN_UNPOISON(ctid, sizeof(*ctid)); - // See kernel/fork.c in Linux. There is different ordering of sys_clone - // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options. -#if defined(ARCH_CPU_X86_64) - return syscall(__NR_clone, flags, child_stack, ptid, ctid, tls); -#elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \ - defined(ARCH_CPU_MIPS_FAMILY) - // CONFIG_CLONE_BACKWARDS defined. - return syscall(__NR_clone, flags, child_stack, ptid, tls, ctid); -#endif -} - -long sys_clone(unsigned long flags) { - return sys_clone(flags, nullptr, nullptr, nullptr, nullptr); -} - -void sys_exit_group(int status) { - syscall(__NR_exit_group, status); -} - -int sys_seccomp(unsigned int operation, - unsigned int flags, - const struct sock_fprog* args) { - return syscall(__NR_seccomp, operation, flags, args); -} - -int sys_prlimit64(pid_t pid, - int resource, - const struct rlimit64* new_limit, - struct rlimit64* old_limit) { - int res = syscall(__NR_prlimit64, pid, resource, new_limit, old_limit); - if (res == 0 && old_limit) MSAN_UNPOISON(old_limit, sizeof(*old_limit)); - return res; -} - -int sys_capget(cap_hdr* hdrp, cap_data* datap) { - int res = syscall(__NR_capget, hdrp, datap); - if (res == 0) { - if (hdrp) MSAN_UNPOISON(hdrp, sizeof(*hdrp)); - if (datap) MSAN_UNPOISON(datap, sizeof(*datap)); - } - return res; -} - -int sys_capset(cap_hdr* hdrp, const cap_data* datap) { - return syscall(__NR_capset, hdrp, datap); -} - -int sys_getresuid(uid_t* ruid, uid_t* euid, uid_t* suid) { - int res; -#if defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARMEL) - // On 32-bit x86 or 32-bit arm, getresuid supports 16bit values only. - // Use getresuid32 instead. - res = syscall(__NR_getresuid32, ruid, euid, suid); -#else - res = syscall(__NR_getresuid, ruid, euid, suid); -#endif - if (res == 0) { - if (ruid) MSAN_UNPOISON(ruid, sizeof(*ruid)); - if (euid) MSAN_UNPOISON(euid, sizeof(*euid)); - if (suid) MSAN_UNPOISON(suid, sizeof(*suid)); - } - return res; -} - -int sys_getresgid(gid_t* rgid, gid_t* egid, gid_t* sgid) { - int res; -#if defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARMEL) - // On 32-bit x86 or 32-bit arm, getresgid supports 16bit values only. - // Use getresgid32 instead. - res = syscall(__NR_getresgid32, rgid, egid, sgid); -#else - res = syscall(__NR_getresgid, rgid, egid, sgid); -#endif - if (res == 0) { - if (rgid) MSAN_UNPOISON(rgid, sizeof(*rgid)); - if (egid) MSAN_UNPOISON(egid, sizeof(*egid)); - if (sgid) MSAN_UNPOISON(sgid, sizeof(*sgid)); - } - return res; -} - -int sys_chroot(const char* path) { - return syscall(__NR_chroot, path); -} - -int sys_unshare(int flags) { - return syscall(__NR_unshare, flags); -} - -int sys_sigprocmask(int how, const sigset_t* set, std::nullptr_t oldset) { - // In some toolchain (in particular Android and PNaCl toolchain), - // sigset_t is 32 bits, but the Linux ABI uses more. - LinuxSigSet linux_value; - std::memset(&linux_value, 0, sizeof(LinuxSigSet)); - std::memcpy(&linux_value, set, std::min(sizeof(sigset_t), - sizeof(LinuxSigSet))); - - return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr, - sizeof(linux_value)); -} - -// When this is built with PNaCl toolchain, we should always use sys_sigaction -// below, because sigaction() provided by the toolchain is incompatible with -// Linux's ABI. -#if !defined(OS_NACL_NONSFI) -int sys_sigaction(int signum, - const struct sigaction* act, - struct sigaction* oldact) { - return sigaction(signum, act, oldact); -} -#else -#if defined(ARCH_CPU_X86_FAMILY) - -// On x86_64, sa_restorer is required. We specify it on x86 as well in order to -// support kernels with VDSO disabled. -#if !defined(SA_RESTORER) -#define SA_RESTORER 0x04000000 -#endif - -// XSTR(__NR_foo) expands to a string literal containing the value value of -// __NR_foo. -#define STR(x) #x -#define XSTR(x) STR(x) - -// rt_sigreturn is a special system call that interacts with the user land -// stack. Thus, here prologue must not be created, which implies syscall() -// does not work properly, too. Note that rt_sigreturn does not return. -// TODO(rickyz): These assembly functions may still break stack unwinding on -// nonsfi NaCl builds. -#if defined(ARCH_CPU_X86_64) - -extern "C" { - void sys_rt_sigreturn(); -} - -asm( - ".text\n" - "sys_rt_sigreturn:\n" - "mov $" XSTR(__NR_rt_sigreturn) ", %eax\n" - "syscall\n"); - -#elif defined(ARCH_CPU_X86) -extern "C" { - void sys_sigreturn(); - void sys_rt_sigreturn(); -} - -asm( - ".text\n" - "sys_rt_sigreturn:\n" - "mov $" XSTR(__NR_rt_sigreturn) ", %eax\n" - "int $0x80\n" - - "sys_sigreturn:\n" - "pop %eax\n" - "mov $" XSTR(__NR_sigreturn) ", %eax\n" - "int $0x80\n"); -#else -#error "Unsupported architecture." -#endif - -#undef STR -#undef XSTR - -#endif - -int sys_sigaction(int signum, - const struct sigaction* act, - struct sigaction* oldact) { - LinuxSigAction linux_act = {}; - if (act) { - linux_act.kernel_handler = act->sa_handler; - std::memcpy(&linux_act.sa_mask, &act->sa_mask, - std::min(sizeof(linux_act.sa_mask), sizeof(act->sa_mask))); - linux_act.sa_flags = act->sa_flags; - -#if defined(ARCH_CPU_X86_FAMILY) - if (!(linux_act.sa_flags & SA_RESTORER)) { - linux_act.sa_flags |= SA_RESTORER; -#if defined(ARCH_CPU_X86_64) - linux_act.sa_restorer = sys_rt_sigreturn; -#elif defined(ARCH_CPU_X86) - linux_act.sa_restorer = - linux_act.sa_flags & SA_SIGINFO ? sys_rt_sigreturn : sys_sigreturn; -#else -#error "Unsupported architecture." -#endif - } -#endif - } - - LinuxSigAction linux_oldact = {}; - int result = syscall(__NR_rt_sigaction, signum, act ? &linux_act : nullptr, - oldact ? &linux_oldact : nullptr, - sizeof(LinuxSigSet)); - - if (result == 0 && oldact) { - oldact->sa_handler = linux_oldact.kernel_handler; - sigemptyset(&oldact->sa_mask); - std::memcpy(&oldact->sa_mask, &linux_oldact.sa_mask, - std::min(sizeof(linux_act.sa_mask), sizeof(act->sa_mask))); - oldact->sa_flags = linux_oldact.sa_flags; - } - return result; -} - -#endif // defined(MEMORY_SANITIZER) - -} // namespace sandbox diff --git a/sandbox/linux/services/syscall_wrappers.h b/sandbox/linux/services/syscall_wrappers.h deleted file mode 100644 index 1975bfbd88..0000000000 --- a/sandbox/linux/services/syscall_wrappers.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2014 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_LINUX_SERVICES_SYSCALL_WRAPPERS_H_ -#define SANDBOX_LINUX_SERVICES_SYSCALL_WRAPPERS_H_ - -#include <signal.h> -#include <stdint.h> -#include <sys/types.h> - -#include <cstddef> - -#include "sandbox/sandbox_export.h" - -struct sock_fprog; -struct rlimit64; -struct cap_hdr; -struct cap_data; - -namespace sandbox { - -// Provide direct system call wrappers for a few common system calls. -// These are guaranteed to perform a system call and do not rely on things such -// as caching the current pid (c.f. getpid()) unless otherwise specified. - -SANDBOX_EXPORT pid_t sys_getpid(void); - -SANDBOX_EXPORT pid_t sys_gettid(void); - -SANDBOX_EXPORT ssize_t sys_write(int fd, - const char* buffer, - size_t buffer_size); - -SANDBOX_EXPORT long sys_clone(unsigned long flags); - -// |regs| is not supported and must be passed as nullptr. |child_stack| must be -// nullptr, since otherwise this function cannot safely return. As a -// consequence, this function does not support CLONE_VM. -SANDBOX_EXPORT long sys_clone(unsigned long flags, - std::nullptr_t child_stack, - pid_t* ptid, - pid_t* ctid, - std::nullptr_t regs); - -SANDBOX_EXPORT void sys_exit_group(int status); - -// The official system call takes |args| as void* (in order to be extensible), -// but add more typing for the cases that are currently used. -SANDBOX_EXPORT int sys_seccomp(unsigned int operation, - unsigned int flags, - const struct sock_fprog* args); - -// Some libcs do not expose a prlimit64 wrapper. -SANDBOX_EXPORT int sys_prlimit64(pid_t pid, - int resource, - const struct rlimit64* new_limit, - struct rlimit64* old_limit); - -// Some libcs do not expose capget/capset wrappers. We want to use these -// directly in order to avoid pulling in libcap2. -SANDBOX_EXPORT int sys_capget(struct cap_hdr* hdrp, struct cap_data* datap); -SANDBOX_EXPORT int sys_capset(struct cap_hdr* hdrp, - const struct cap_data* datap); - -// Some libcs do not expose getresuid/getresgid wrappers. -SANDBOX_EXPORT int sys_getresuid(uid_t* ruid, uid_t* euid, uid_t* suid); -SANDBOX_EXPORT int sys_getresgid(gid_t* rgid, gid_t* egid, gid_t* sgid); - -// Some libcs do not expose a chroot wrapper. -SANDBOX_EXPORT int sys_chroot(const char* path); - -// Some libcs do not expose a unshare wrapper. -SANDBOX_EXPORT int sys_unshare(int flags); - -// Some libcs do not expose a sigprocmask. Note that oldset must be a nullptr, -// because of some ABI gap between toolchain's and Linux's. -SANDBOX_EXPORT int sys_sigprocmask(int how, - const sigset_t* set, - std::nullptr_t oldset); - -// Some libcs do not expose a sigaction(). -SANDBOX_EXPORT int sys_sigaction(int signum, - const struct sigaction* act, - struct sigaction* oldact); - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_SYSCALL_WRAPPERS_H_ diff --git a/sandbox/linux/services/syscall_wrappers_unittest.cc b/sandbox/linux/services/syscall_wrappers_unittest.cc deleted file mode 100644 index 34ac740930..0000000000 --- a/sandbox/linux/services/syscall_wrappers_unittest.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2014 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/linux/services/syscall_wrappers.h" - -#include <stdint.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <cstring> - -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/third_party/valgrind/valgrind.h" -#include "build/build_config.h" -#include "sandbox/linux/system_headers/linux_signal.h" -#include "sandbox/linux/tests/test_utils.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace { - -TEST(SyscallWrappers, BasicSyscalls) { - EXPECT_EQ(getpid(), sys_getpid()); -} - -TEST(SyscallWrappers, CloneBasic) { - pid_t child = sys_clone(SIGCHLD); - TestUtils::HandlePostForkReturn(child); - EXPECT_LT(0, child); -} - -TEST(SyscallWrappers, CloneParentSettid) { - pid_t ptid = 0; - pid_t child = sys_clone(CLONE_PARENT_SETTID | SIGCHLD, nullptr, &ptid, - nullptr, nullptr); - TestUtils::HandlePostForkReturn(child); - EXPECT_LT(0, child); - EXPECT_EQ(child, ptid); -} - -TEST(SyscallWrappers, CloneChildSettid) { - pid_t ctid = 0; - pid_t pid = - sys_clone(CLONE_CHILD_SETTID | SIGCHLD, nullptr, nullptr, &ctid, nullptr); - - const int kSuccessExit = 0; - if (0 == pid) { - // In child. - if (sys_getpid() == ctid) - _exit(kSuccessExit); - _exit(1); - } - - ASSERT_NE(-1, pid); - int status = 0; - ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); - ASSERT_TRUE(WIFEXITED(status)); - EXPECT_EQ(kSuccessExit, WEXITSTATUS(status)); -} - -TEST(SyscallWrappers, GetRESUid) { - uid_t ruid, euid, suid; - uid_t sys_ruid, sys_euid, sys_suid; - ASSERT_EQ(0, getresuid(&ruid, &euid, &suid)); - ASSERT_EQ(0, sys_getresuid(&sys_ruid, &sys_euid, &sys_suid)); - EXPECT_EQ(ruid, sys_ruid); - EXPECT_EQ(euid, sys_euid); - EXPECT_EQ(suid, sys_suid); -} - -TEST(SyscallWrappers, GetRESGid) { - gid_t rgid, egid, sgid; - gid_t sys_rgid, sys_egid, sys_sgid; - ASSERT_EQ(0, getresgid(&rgid, &egid, &sgid)); - ASSERT_EQ(0, sys_getresgid(&sys_rgid, &sys_egid, &sys_sgid)); - EXPECT_EQ(rgid, sys_rgid); - EXPECT_EQ(egid, sys_egid); - EXPECT_EQ(sgid, sys_sgid); -} - -TEST(SyscallWrappers, LinuxSigSet) { - sigset_t sigset; - ASSERT_EQ(0, sigemptyset(&sigset)); - ASSERT_EQ(0, sigaddset(&sigset, LINUX_SIGSEGV)); - ASSERT_EQ(0, sigaddset(&sigset, LINUX_SIGBUS)); - uint64_t linux_sigset = 0; - std::memcpy(&linux_sigset, &sigset, - std::min(sizeof(sigset), sizeof(linux_sigset))); - EXPECT_EQ((1ULL << (LINUX_SIGSEGV - 1)) | (1ULL << (LINUX_SIGBUS - 1)), - linux_sigset); -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/services/thread_helpers.cc b/sandbox/linux/services/thread_helpers.cc deleted file mode 100644 index 20752c8d57..0000000000 --- a/sandbox/linux/services/thread_helpers.cc +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2014 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/linux/services/thread_helpers.h" - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <string> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/platform_thread.h" -#include "base/threading/thread.h" -#include "sandbox/linux/services/proc_util.h" - -namespace sandbox { - -namespace { - -const char kAssertSingleThreadedError[] = - "Current process is not mono-threaded!"; -const char kAssertThreadDoesNotAppearInProcFS[] = - "Started thread does not appear in /proc"; -const char kAssertThreadDoesNotDisappearInProcFS[] = - "Stopped thread does not disappear in /proc"; - -bool IsSingleThreadedImpl(int proc_fd) { - CHECK_LE(0, proc_fd); - struct stat task_stat; - int fstat_ret = fstatat(proc_fd, "self/task/", &task_stat, 0); - PCHECK(0 == fstat_ret); - - // At least "..", "." and the current thread should be present. - CHECK_LE(3UL, task_stat.st_nlink); - // Counting threads via /proc/self/task could be racy. For the purpose of - // determining if the current proces is monothreaded it works: if at any - // time it becomes monothreaded, it'll stay so. - return task_stat.st_nlink == 3; -} - -bool IsThreadPresentInProcFS(int proc_fd, - const std::string& thread_id_dir_str) { - struct stat task_stat; - const int fstat_ret = - fstatat(proc_fd, thread_id_dir_str.c_str(), &task_stat, 0); - if (fstat_ret < 0) { - PCHECK(ENOENT == errno); - return false; - } - return true; -} - -bool IsNotThreadPresentInProcFS(int proc_fd, - const std::string& thread_id_dir_str) { - return !IsThreadPresentInProcFS(proc_fd, thread_id_dir_str); -} - -// Run |cb| in a loop until it returns false. Every time |cb| runs, sleep -// for an exponentially increasing amount of time. |cb| is expected to return -// false very quickly and this will crash if it doesn't happen within ~64ms on -// Debug builds (2s on Release builds). -// This is guaranteed to not sleep more than twice as much as the bare minimum -// amount of time. -void RunWhileTrue(const base::Callback<bool(void)>& cb, const char* message) { -#if defined(NDEBUG) - // In Release mode, crash after 30 iterations, which means having spent - // roughly 2s in - // nanosleep(2) cumulatively. - const unsigned int kMaxIterations = 30U; -#else - // In practice, this never goes through more than a couple iterations. In - // debug mode, crash after 64ms (+ eventually 25 times the granularity of - // the clock) in nanosleep(2). This ensures that this is not becoming too - // slow. - const unsigned int kMaxIterations = 25U; -#endif - - // Run |cb| with an exponential back-off, sleeping 2^iterations nanoseconds - // in nanosleep(2). - // Note: the clock may not allow for nanosecond granularity, in this case the - // first iterations would sleep a tiny bit more instead, which would not - // change the calculations significantly. - for (unsigned int i = 0; i < kMaxIterations; ++i) { - if (!cb.Run()) { - return; - } - - // Increase the waiting time exponentially. - struct timespec ts = {0, 1L << i /* nanoseconds */}; - PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts))); - } - - LOG(FATAL) << message << " (iterations: " << kMaxIterations << ")"; - - NOTREACHED(); -} - -bool IsMultiThreaded(int proc_fd) { - return !ThreadHelpers::IsSingleThreaded(proc_fd); -} - -enum class ThreadAction { Start, Stop }; - -bool ChangeThreadStateAndWatchProcFS( - int proc_fd, base::Thread* thread, ThreadAction action) { - DCHECK_LE(0, proc_fd); - DCHECK(thread); - DCHECK(action == ThreadAction::Start || action == ThreadAction::Stop); - - base::Callback<bool(void)> cb; - const char* message; - - if (action == ThreadAction::Start) { - // Should start the thread before calling thread_id(). - if (!thread->Start()) - return false; - } - - const base::PlatformThreadId thread_id = thread->GetThreadId(); - const std::string thread_id_dir_str = - "self/task/" + base::IntToString(thread_id) + "/"; - - if (action == ThreadAction::Stop) { - // The target thread should exist in /proc. - DCHECK(IsThreadPresentInProcFS(proc_fd, thread_id_dir_str)); - thread->Stop(); - } - - // The kernel is at liberty to wake the thread id futex before updating - // /proc. Start() above or following Stop(), the thread is started or joined, - // but entries in /proc may not have been updated. - if (action == ThreadAction::Start) { - cb = base::Bind(&IsNotThreadPresentInProcFS, proc_fd, thread_id_dir_str); - message = kAssertThreadDoesNotAppearInProcFS; - } else { - cb = base::Bind(&IsThreadPresentInProcFS, proc_fd, thread_id_dir_str); - message = kAssertThreadDoesNotDisappearInProcFS; - } - RunWhileTrue(cb, message); - - DCHECK_EQ(action == ThreadAction::Start, - IsThreadPresentInProcFS(proc_fd, thread_id_dir_str)); - - return true; -} - -} // namespace - -// static -bool ThreadHelpers::IsSingleThreaded(int proc_fd) { - DCHECK_LE(0, proc_fd); - return IsSingleThreadedImpl(proc_fd); -} - -// static -bool ThreadHelpers::IsSingleThreaded() { - base::ScopedFD task_fd(ProcUtil::OpenProc()); - return IsSingleThreaded(task_fd.get()); -} - -// static -void ThreadHelpers::AssertSingleThreaded(int proc_fd) { - DCHECK_LE(0, proc_fd); - const base::Callback<bool(void)> cb = base::Bind(&IsMultiThreaded, proc_fd); - RunWhileTrue(cb, kAssertSingleThreadedError); -} - -void ThreadHelpers::AssertSingleThreaded() { - base::ScopedFD task_fd(ProcUtil::OpenProc()); - AssertSingleThreaded(task_fd.get()); -} - -// static -bool ThreadHelpers::StartThreadAndWatchProcFS(int proc_fd, - base::Thread* thread) { - return ChangeThreadStateAndWatchProcFS(proc_fd, thread, ThreadAction::Start); -} - -// static -bool ThreadHelpers::StopThreadAndWatchProcFS(int proc_fd, - base::Thread* thread) { - return ChangeThreadStateAndWatchProcFS(proc_fd, thread, ThreadAction::Stop); -} - -// static -const char* ThreadHelpers::GetAssertSingleThreadedErrorMessageForTests() { - return kAssertSingleThreadedError; -} - -} // namespace sandbox diff --git a/sandbox/linux/services/thread_helpers.h b/sandbox/linux/services/thread_helpers.h deleted file mode 100644 index 73e041aa1b..0000000000 --- a/sandbox/linux/services/thread_helpers.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 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_LINUX_SERVICES_THREAD_HELPERS_H_ -#define SANDBOX_LINUX_SERVICES_THREAD_HELPERS_H_ - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace base { class Thread; } - -namespace sandbox { - -class SANDBOX_EXPORT ThreadHelpers { - public: - // Checks whether the current process is single threaded. |proc_fd| - // must be a file descriptor to /proc/ and remains owned by the - // caller. - static bool IsSingleThreaded(int proc_fd); - static bool IsSingleThreaded(); - - // Crashes if the current process is not single threaded. This will wait - // on /proc to be updated. In the case where this doesn't crash, this will - // return promptly. In the case where this does crash, this will first wait - // for a few ms in Debug mode, a few seconds in Release mode. - static void AssertSingleThreaded(int proc_fd); - static void AssertSingleThreaded(); - - // Starts |thread| and ensure that it has an entry in /proc/self/task/ from - // the point of view of the current thread. - static bool StartThreadAndWatchProcFS(int proc_fd, base::Thread* thread); - - // Stops |thread| and ensure that it does not have an entry in - // /proc/self/task/ from the point of view of the current thread. This is - // the way to stop threads before calling IsSingleThreaded(). - static bool StopThreadAndWatchProcFS(int proc_fd, base::Thread* thread); - - static const char* GetAssertSingleThreadedErrorMessageForTests(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadHelpers); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_THREAD_HELPERS_H_ diff --git a/sandbox/linux/services/thread_helpers_unittests.cc b/sandbox/linux/services/thread_helpers_unittests.cc deleted file mode 100644 index fe1080bf9e..0000000000 --- a/sandbox/linux/services/thread_helpers_unittests.cc +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2014 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/linux/services/thread_helpers.h" - -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/process_metrics.h" -#include "base/threading/platform_thread.h" -#include "base/threading/thread.h" -#include "build/build_config.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::PlatformThread; - -namespace sandbox { - -namespace { - -// These tests fail under ThreadSanitizer, see http://crbug.com/342305 -#if !defined(THREAD_SANITIZER) - -int GetRaceTestIterations() { - if (IsRunningOnValgrind()) { - return 2; - } else { - return 1000; - } -} - -class ScopedProc { - public: - ScopedProc() : fd_(-1) { - fd_ = open("/proc/", O_RDONLY | O_DIRECTORY); - CHECK_LE(0, fd_); - } - - ~ScopedProc() { PCHECK(0 == IGNORE_EINTR(close(fd_))); } - - int fd() { return fd_; } - - private: - int fd_; - DISALLOW_COPY_AND_ASSIGN(ScopedProc); -}; - -TEST(ThreadHelpers, IsSingleThreadedBasic) { - ScopedProc proc_fd; - ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - ASSERT_TRUE(ThreadHelpers::IsSingleThreaded()); - - base::Thread thread("sandbox_tests"); - ASSERT_TRUE(ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread)); - ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - ASSERT_FALSE(ThreadHelpers::IsSingleThreaded()); - // Explicitly stop the thread here to not pollute the next test. - ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.fd(), &thread)); -} - -SANDBOX_TEST(ThreadHelpers, AssertSingleThreaded) { - ScopedProc proc_fd; - SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded()); - - ThreadHelpers::AssertSingleThreaded(proc_fd.fd()); - ThreadHelpers::AssertSingleThreaded(); -} - -TEST(ThreadHelpers, IsSingleThreadedIterated) { - ScopedProc proc_fd; - ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - - // Iterate to check for race conditions. - for (int i = 0; i < GetRaceTestIterations(); ++i) { - base::Thread thread("sandbox_tests"); - ASSERT_TRUE( - ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread)); - ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - // Explicitly stop the thread here to not pollute the next test. - ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.fd(), &thread)); - } -} - -TEST(ThreadHelpers, IsSingleThreadedStartAndStop) { - ScopedProc proc_fd; - ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - - base::Thread thread("sandbox_tests"); - // This is testing for a race condition, so iterate. - // Manually, this has been tested with more that 1M iterations. - for (int i = 0; i < GetRaceTestIterations(); ++i) { - ASSERT_TRUE( - ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread)); - ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - - ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.fd(), &thread)); - ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); - ASSERT_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle())); - } -} - -SANDBOX_TEST(ThreadHelpers, AssertSingleThreadedAfterThreadStopped) { - ScopedProc proc_fd; - SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded()); - - base::Thread thread1("sandbox_tests"); - base::Thread thread2("sandbox_tests"); - - for (int i = 0; i < GetRaceTestIterations(); ++i) { - SANDBOX_ASSERT( - ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread1)); - SANDBOX_ASSERT( - ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread2)); - SANDBOX_ASSERT(!ThreadHelpers::IsSingleThreaded()); - - thread1.Stop(); - thread2.Stop(); - // This will wait on /proc/ to reflect the state of threads in the - // process. - ThreadHelpers::AssertSingleThreaded(); - SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded()); - } -} - -// Only run this test in Debug mode, where AssertSingleThreaded() will return -// in less than 64ms. -#if !defined(NDEBUG) -SANDBOX_DEATH_TEST( - ThreadHelpers, - AssertSingleThreadedDies, - DEATH_MESSAGE( - ThreadHelpers::GetAssertSingleThreadedErrorMessageForTests())) { - base::Thread thread1("sandbox_tests"); - SANDBOX_ASSERT(thread1.Start()); - ThreadHelpers::AssertSingleThreaded(); -} -#endif // !defined(NDEBUG) - -#endif // !defined(THREAD_SANITIZER) - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/services/yama.cc b/sandbox/linux/services/yama.cc deleted file mode 100644 index 6831cd9c55..0000000000 --- a/sandbox/linux/services/yama.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2014 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/linux/services/yama.h" - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <sys/prctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" - -#if !defined(PR_SET_PTRACER_ANY) -#define PR_SET_PTRACER_ANY ((unsigned long)-1) -#endif - -#if !defined(PR_SET_PTRACER) -#define PR_SET_PTRACER 0x59616d61 -#endif - -namespace sandbox { - -namespace { - -// Enable or disable the Yama ptracers restrictions. -// Return false if Yama is not present on this kernel. -bool SetYamaPtracersRestriction(bool enable_restrictions) { - unsigned long set_ptracer_arg; - if (enable_restrictions) { - set_ptracer_arg = 0; - } else { - set_ptracer_arg = PR_SET_PTRACER_ANY; - } - - const int ret = prctl(PR_SET_PTRACER, set_ptracer_arg); - const int prctl_errno = errno; - - if (0 == ret) { - return true; - } else { - // ENOSYS or EINVAL means Yama is not in the current kernel. - CHECK(ENOSYS == prctl_errno || EINVAL == prctl_errno); - return false; - } -} - -bool CanAccessProcFS() { - static const char kProcfsKernelSysPath[] = "/proc/sys/kernel/"; - int ret = access(kProcfsKernelSysPath, F_OK); - if (ret) { - return false; - } - return true; -} - -} // namespace - -// static -bool Yama::RestrictPtracersToAncestors() { - return SetYamaPtracersRestriction(true /* enable_restrictions */); -} - -// static -bool Yama::DisableYamaRestrictions() { - return SetYamaPtracersRestriction(false /* enable_restrictions */); -} - -// static -int Yama::GetStatus() { - if (!CanAccessProcFS()) { - return 0; - } - - static const char kPtraceScopePath[] = "/proc/sys/kernel/yama/ptrace_scope"; - - base::ScopedFD yama_scope(HANDLE_EINTR(open(kPtraceScopePath, O_RDONLY))); - - if (!yama_scope.is_valid()) { - const int open_errno = errno; - DCHECK(ENOENT == open_errno); - // The status is known, yama is not present. - return STATUS_KNOWN; - } - - char yama_scope_value = 0; - ssize_t num_read = HANDLE_EINTR(read(yama_scope.get(), &yama_scope_value, 1)); - PCHECK(1 == num_read); - - switch (yama_scope_value) { - case '0': - return STATUS_KNOWN | STATUS_PRESENT; - case '1': - return STATUS_KNOWN | STATUS_PRESENT | STATUS_ENFORCING; - case '2': - case '3': - return STATUS_KNOWN | STATUS_PRESENT | STATUS_ENFORCING | - STATUS_STRICT_ENFORCING; - default: - NOTREACHED(); - return 0; - } -} - -// static -bool Yama::IsPresent() { return GetStatus() & STATUS_PRESENT; } - -// static -bool Yama::IsEnforcing() { return GetStatus() & STATUS_ENFORCING; } - -} // namespace sandbox diff --git a/sandbox/linux/services/yama.h b/sandbox/linux/services/yama.h deleted file mode 100644 index e6c5c45b2a..0000000000 --- a/sandbox/linux/services/yama.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2014 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_LINUX_SERVICES_YAMA_H_ -#define SANDBOX_LINUX_SERVICES_YAMA_H_ - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -// Yama is a LSM kernel module which can restrict ptrace(). -// This class provides ways to detect if Yama is present and enabled -// and to restrict which processes can ptrace the current process. -class SANDBOX_EXPORT Yama { - public: - // This enum should be used to set or check a bitmask. - // A value of 0 would indicate that the status is not known. - enum GlobalStatus { - STATUS_KNOWN = 1 << 0, - STATUS_PRESENT = 1 << 1, - STATUS_ENFORCING = 1 << 2, - // STATUS_STRICT_ENFORCING corresponds to either mode 2 or mode 3 of Yama. - // Ptrace could be entirely denied, or restricted to CAP_SYS_PTRACE - // and PTRACE_TRACEME. - STATUS_STRICT_ENFORCING = 1 << 3 - }; - - // Restrict who can ptrace() the current process to its ancestors. - // If this succeeds, then Yama is available on this kernel. - // However, Yama may not be enforcing at this time. - static bool RestrictPtracersToAncestors(); - - // Disable Yama restrictions for the current process. - // This will fail if Yama is not available on this kernel. - // This is meant for testing only. If you need this, implement - // a per-pid authorization instead. - static bool DisableYamaRestrictions(); - - // Checks if Yama is currently in enforcing mode for the machine (not the - // current process). This requires access to the filesystem and will use - // /proc/sys/kernel/yama/ptrace_scope. - static int GetStatus(); - - // Helper for checking for STATUS_PRESENT in GetStatus(). - static bool IsPresent(); - // Helper for checkking for STATUS_ENFORCING in GetStatus(). - static bool IsEnforcing(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(Yama); -}; - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_YAMA_H_ diff --git a/sandbox/linux/services/yama_unittests.cc b/sandbox/linux/services/yama_unittests.cc deleted file mode 100644 index 0e8355d08e..0000000000 --- a/sandbox/linux/services/yama_unittests.cc +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2014 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 <errno.h> -#include <fcntl.h> -#include <sys/ptrace.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" -#include "base/posix/eintr_wrapper.h" -#include "base/strings/string_util.h" -#include "base/sys_info.h" -#include "sandbox/linux/services/scoped_process.h" -#include "sandbox/linux/services/yama.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace { - -bool HasLinux32Bug() { -#if defined(__i386__) - // On 3.2 kernels, yama doesn't work for 32-bit binaries on 64-bit kernels. - // This is fixed in 3.4. - bool is_kernel_64bit = - base::SysInfo::OperatingSystemArchitecture() == "x86_64"; - bool is_linux = base::SysInfo::OperatingSystemName() == "Linux"; - bool is_3_dot_2 = base::StartsWith( - base::SysInfo::OperatingSystemVersion(), "3.2", - base::CompareCase::INSENSITIVE_ASCII); - if (is_kernel_64bit && is_linux && is_3_dot_2) - return true; -#endif // defined(__i386__) - return false; -} - -bool CanPtrace(pid_t pid) { - int ret; - ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL); - if (ret == -1) { - CHECK_EQ(EPERM, errno); - return false; - } - // Wait for the process to be stopped so that it can be detached. - siginfo_t process_info; - int wait_ret = HANDLE_EINTR(waitid(P_PID, pid, &process_info, WSTOPPED)); - PCHECK(0 == wait_ret); - PCHECK(0 == ptrace(PTRACE_DETACH, pid, NULL, NULL)); - return true; -} - -// _exit(0) if pid can be ptraced by the current process. -// _exit(1) otherwise. -void ExitZeroIfCanPtrace(pid_t pid) { - if (CanPtrace(pid)) { - _exit(0); - } else { - _exit(1); - } -} - -bool CanSubProcessPtrace(pid_t pid) { - ScopedProcess process(base::Bind(&ExitZeroIfCanPtrace, pid)); - bool signaled; - int exit_code = process.WaitForExit(&signaled); - CHECK(!signaled); - return 0 == exit_code; -} - -// The tests below assume that the system-level configuration will not change -// while they run. - -TEST(Yama, GetStatus) { - int status1 = Yama::GetStatus(); - - // Check that the value is a possible bitmask. - ASSERT_LE(0, status1); - ASSERT_GE(Yama::STATUS_KNOWN | Yama::STATUS_PRESENT | Yama::STATUS_ENFORCING | - Yama::STATUS_STRICT_ENFORCING, - status1); - - // The status should not just be a random value. - int status2 = Yama::GetStatus(); - EXPECT_EQ(status1, status2); - - // This test is not running sandboxed, there is no reason to not know the - // status. - EXPECT_NE(0, Yama::STATUS_KNOWN & status1); - - if (status1 & Yama::STATUS_STRICT_ENFORCING) { - // If Yama is strictly enforcing, it is also enforcing. - EXPECT_TRUE(status1 & Yama::STATUS_ENFORCING); - } - - if (status1 & Yama::STATUS_ENFORCING) { - // If Yama is enforcing, Yama is present. - EXPECT_NE(0, status1 & Yama::STATUS_PRESENT); - } - - // Verify that the helper functions work as intended. - EXPECT_EQ(static_cast<bool>(status1 & Yama::STATUS_ENFORCING), - Yama::IsEnforcing()); - EXPECT_EQ(static_cast<bool>(status1 & Yama::STATUS_PRESENT), - Yama::IsPresent()); - - fprintf(stdout, - "Yama present: %s - enforcing: %s\n", - Yama::IsPresent() ? "Y" : "N", - Yama::IsEnforcing() ? "Y" : "N"); -} - -SANDBOX_TEST(Yama, RestrictPtraceSucceedsWhenYamaPresent) { - // This call will succeed iff Yama is present. - bool restricted = Yama::RestrictPtracersToAncestors(); - CHECK_EQ(restricted, Yama::IsPresent()); -} - -// Attempts to enable or disable Yama restrictions. -void SetYamaRestrictions(bool enable_restriction) { - if (enable_restriction) { - Yama::RestrictPtracersToAncestors(); - } else { - Yama::DisableYamaRestrictions(); - } -} - -TEST(Yama, RestrictPtraceWorks) { - if (HasLinux32Bug()) - return; - - ScopedProcess process1(base::Bind(&SetYamaRestrictions, true)); - ASSERT_TRUE(process1.WaitForClosureToRun()); - - if (Yama::IsEnforcing()) { - // A sibling process cannot ptrace process1. - ASSERT_FALSE(CanSubProcessPtrace(process1.GetPid())); - } - - if (!(Yama::GetStatus() & Yama::STATUS_STRICT_ENFORCING)) { - // However, parent can ptrace process1. - ASSERT_TRUE(CanPtrace(process1.GetPid())); - - // A sibling can ptrace process2 which disables any Yama protection. - ScopedProcess process2(base::Bind(&SetYamaRestrictions, false)); - ASSERT_TRUE(process2.WaitForClosureToRun()); - ASSERT_TRUE(CanSubProcessPtrace(process2.GetPid())); - } -} - -SANDBOX_TEST(Yama, RestrictPtraceIsDefault) { - if (!Yama::IsPresent() || HasLinux32Bug()) - return; - - CHECK(Yama::DisableYamaRestrictions()); - ScopedProcess process1(base::Bind(&base::DoNothing)); - - if (Yama::IsEnforcing()) { - // Check that process1 is protected by Yama, even though it has - // been created from a process that disabled Yama. - CHECK(!CanSubProcessPtrace(process1.GetPid())); - } -} - -} // namespace - -} // namespace sandbox diff --git a/sandbox/linux/suid/client/DEPS b/sandbox/linux/suid/client/DEPS deleted file mode 100644 index 99a337d772..0000000000 --- a/sandbox/linux/suid/client/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+sandbox/linux/services", -] diff --git a/sandbox/linux/suid/common/sandbox.h b/sandbox/linux/suid/common/sandbox.h deleted file mode 100644 index 52ef10cdc0..0000000000 --- a/sandbox/linux/suid/common/sandbox.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SUID_SANDBOX_H_ -#define SANDBOX_LINUX_SUID_SANDBOX_H_ - -#if defined(__cplusplus) -namespace sandbox { -#endif - -// These are command line switches that may be used by other programs -// (e.g. Chrome) to construct a command line for the sandbox. -static const char kSuidSandboxGetApiSwitch[] = "--get-api"; -static const char kAdjustOOMScoreSwitch[] = "--adjust-oom-score"; - -static const char kSandboxDescriptorEnvironmentVarName[] = "SBX_D"; -static const char kSandboxHelperPidEnvironmentVarName[] = "SBX_HELPER_PID"; - -static const int kSUIDSandboxApiNumber = 1; -static const char kSandboxEnvironmentApiRequest[] = "SBX_CHROME_API_RQ"; -static const char kSandboxEnvironmentApiProvides[] = "SBX_CHROME_API_PRV"; - -// This number must be kept in sync with common/zygote_commands_linux.h -static const int kZygoteIdFd = 7; - -// These are the magic byte values which the sandboxed process uses to request -// that it be chrooted. -static const char kMsgChrootMe = 'C'; -static const char kMsgChrootSuccessful = 'O'; - -// These are set if we have respectively switched to a new PID or NET namespace -// by going through the setuid binary helper. -static const char kSandboxPIDNSEnvironmentVarName[] = "SBX_PID_NS"; -static const char kSandboxNETNSEnvironmentVarName[] = "SBX_NET_NS"; - -#if defined(__cplusplus) -} // namespace sandbox -#endif - -#endif // SANDBOX_LINUX_SUID_SANDBOX_H_ diff --git a/sandbox/linux/suid/common/suid_unsafe_environment_variables.h b/sandbox/linux/suid/common/suid_unsafe_environment_variables.h deleted file mode 100644 index e955e0c9c4..0000000000 --- a/sandbox/linux/suid/common/suid_unsafe_environment_variables.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2012 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. - -// This is a list of environment variables which the ELF loader unsets when -// loading a SUID binary. Because they are unset rather than just ignored, they -// aren't passed to child processes of SUID processes either. -// -// We need to save these environment variables before running a SUID sandbox -// and restore them before running child processes (but after dropping root). -// -// List gathered from glibc sources (00ebd7ed58df389a78e41dece058048725cb585e): -// sysdeps/unix/sysv/linux/i386/dl-librecon.h -// sysdeps/generic/unsecvars.h - -#ifndef SANDBOX_LINUX_SUID_COMMON_SUID_UNSAFE_ENVIRONMENT_VARIABLES_H_ -#define SANDBOX_LINUX_SUID_COMMON_SUID_UNSAFE_ENVIRONMENT_VARIABLES_H_ - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> // malloc -#include <string.h> // memcpy - -static const char* const kSUIDUnsafeEnvironmentVariables[] = { - "LD_AOUT_LIBRARY_PATH", - "LD_AOUT_PRELOAD", - "GCONV_PATH", - "GETCONF_DIR", - "HOSTALIASES", - "LD_AUDIT", - "LD_DEBUG", - "LD_DEBUG_OUTPUT", - "LD_DYNAMIC_WEAK", - "LD_LIBRARY_PATH", - "LD_ORIGIN_PATH", - "LD_PRELOAD", - "LD_PROFILE", - "LD_SHOW_AUXV", - "LD_USE_LOAD_BIAS", - "LOCALDOMAIN", - "LOCPATH", - "MALLOC_TRACE", - "NIS_PATH", - "NLSPATH", - "RESOLV_HOST_CONF", - "RES_OPTIONS", - "TMPDIR", - "TZDIR", - NULL, -}; - -// Return a malloc allocated string containing the 'saved' environment variable -// name for a given environment variable. -static inline char* SandboxSavedEnvironmentVariable(const char* envvar) { - const size_t envvar_len = strlen(envvar); - const size_t kMaxSizeT = (size_t) -1; - - if (envvar_len > kMaxSizeT - 1 - 8) - return NULL; - - const size_t saved_envvarlen = envvar_len + 1 /* NUL terminator */ + - 8 /* strlen("SANDBOX_") */; - char* const saved_envvar = (char*) malloc(saved_envvarlen); - if (!saved_envvar) - return NULL; - - memcpy(saved_envvar, "SANDBOX_", 8); - memcpy(saved_envvar + 8, envvar, envvar_len); - saved_envvar[8 + envvar_len] = 0; - - return saved_envvar; -} - -#endif // SANDBOX_LINUX_SUID_COMMON_SUID_UNSAFE_ENVIRONMENT_VARIABLES_H_ diff --git a/sandbox/linux/suid/process_util.h b/sandbox/linux/suid/process_util.h deleted file mode 100644 index 10071d3e00..0000000000 --- a/sandbox/linux/suid/process_util.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2012 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. - -// The following is duplicated from base/process_utils.h. -// We shouldn't link against C++ code in a setuid binary. - -#ifndef SANDBOX_LINUX_SUID_PROCESS_UTIL_H_ -#define SANDBOX_LINUX_SUID_PROCESS_UTIL_H_ - -#include <stdbool.h> -#include <stdint.h> -#include <sys/types.h> - -// This adjusts /proc/process/oom_score_adj so the Linux OOM killer -// will prefer certain process types over others. The range for the -// adjustment is [-1000, 1000], with [0, 1000] being user accessible. -// -// If the Linux system isn't new enough to use oom_score_adj, then we -// try to set the older oom_adj value instead, scaling the score to -// the required range of [0, 15]. This may result in some aliasing of -// values, of course. -bool AdjustOOMScore(pid_t process, int score); - -// This adjusts /sys/kernel/mm/chromeos-low_mem/margin so that -// the kernel notifies us that we are low on memory when less than -// |margin_mb| megabytes are available. Setting |margin_mb| to -1 -// turns off low memory notification. -bool AdjustLowMemoryMargin(int64_t margin_mb); - -#endif // SANDBOX_LINUX_SUID_PROCESS_UTIL_H_ diff --git a/sandbox/linux/suid/process_util_linux.c b/sandbox/linux/suid/process_util_linux.c deleted file mode 100644 index d28d5766c3..0000000000 --- a/sandbox/linux/suid/process_util_linux.c +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2012 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. - -// The following is the C version of code from base/process_utils_linux.cc. -// We shouldn't link against C++ code in a setuid binary. - -// Needed for O_DIRECTORY, must be defined before fcntl.h is included -// (and it can be included earlier than the explicit #include below -// in some versions of glibc). -#define _GNU_SOURCE - -#include "sandbox/linux/suid/process_util.h" - -#include <fcntl.h> -#include <inttypes.h> -#include <limits.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -// Ranges for the current (oom_score_adj) and previous (oom_adj) -// flavors of OOM score. -static const int kMaxOomScore = 1000; -static const int kMaxOldOomScore = 15; - -// NOTE: This is not the only version of this function in the source: -// the base library (in process_util_linux.cc) also has its own C++ version. -bool AdjustOOMScore(pid_t process, int score) { - if (score < 0 || score > kMaxOomScore) - return false; - - char oom_adj[27]; // "/proc/" + log_10(2**64) + "\0" - // 6 + 20 + 1 = 27 - snprintf(oom_adj, sizeof(oom_adj), "/proc/%" PRIdMAX, (intmax_t)process); - - const int dirfd = open(oom_adj, O_RDONLY | O_DIRECTORY); - if (dirfd < 0) - return false; - - struct stat statbuf; - if (fstat(dirfd, &statbuf) < 0) { - close(dirfd); - return false; - } - if (getuid() != statbuf.st_uid) { - close(dirfd); - return false; - } - - int fd = openat(dirfd, "oom_score_adj", O_WRONLY); - if (fd < 0) { - // We failed to open oom_score_adj, so let's try for the older - // oom_adj file instead. - fd = openat(dirfd, "oom_adj", O_WRONLY); - if (fd < 0) { - // Nope, that doesn't work either. - close(dirfd); - return false; - } else { - // If we're using the old oom_adj file, the allowed range is now - // [0, kMaxOldOomScore], so we scale the score. This may result in some - // aliasing of values, of course. - score = score * kMaxOldOomScore / kMaxOomScore; - } - } - close(dirfd); - - char buf[11]; // 0 <= |score| <= kMaxOomScore; using log_10(2**32) + 1 size - snprintf(buf, sizeof(buf), "%d", score); - size_t len = strlen(buf); - - ssize_t bytes_written = write(fd, buf, len); - close(fd); - return (bytes_written == (ssize_t)len); -} diff --git a/sandbox/linux/suid/sandbox.c b/sandbox/linux/suid/sandbox.c deleted file mode 100644 index b655d1c79c..0000000000 --- a/sandbox/linux/suid/sandbox.c +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright (c) 2012 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. - -// https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox.md - -#include "sandbox/linux/suid/common/sandbox.h" - -#define _GNU_SOURCE -#include <asm/unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <sched.h> -#include <signal.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/prctl.h> -#include <sys/resource.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/vfs.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "sandbox/linux/suid/common/suid_unsafe_environment_variables.h" -#include "sandbox/linux/suid/process_util.h" - -#if !defined(CLONE_NEWPID) -#define CLONE_NEWPID 0x20000000 -#endif -#if !defined(CLONE_NEWNET) -#define CLONE_NEWNET 0x40000000 -#endif - -static bool DropRoot(); - -#define HANDLE_EINTR(x) TEMP_FAILURE_RETRY(x) - -static void FatalError(const char* msg, ...) - __attribute__((noreturn, format(printf, 1, 2))); - -static void FatalError(const char* msg, ...) { - va_list ap; - va_start(ap, msg); - - vfprintf(stderr, msg, ap); - fprintf(stderr, ": %s\n", strerror(errno)); - fflush(stderr); - va_end(ap); - _exit(1); -} - -static void ExitWithErrorSignalHandler(int signal) { - const char msg[] = "\nThe setuid sandbox got signaled, exiting.\n"; - if (-1 == write(2, msg, sizeof(msg) - 1)) { - // Do nothing. - } - - _exit(1); -} - -// We will chroot() to the helper's /proc/self directory. Anything there will -// not exist anymore if we make sure to wait() for the helper. -// -// /proc/self/fdinfo or /proc/self/fd are especially safe and will be empty -// even if the helper survives as a zombie. -// -// There is very little reason to use fdinfo/ instead of fd/ but we are -// paranoid. fdinfo/ only exists since 2.6.22 so we allow fallback to fd/ -#define SAFE_DIR "/proc/self/fdinfo" -#define SAFE_DIR2 "/proc/self/fd" - -static bool SpawnChrootHelper() { - int sv[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) { - perror("socketpair"); - return false; - } - - char* safedir = NULL; - struct stat sdir_stat; - if (!stat(SAFE_DIR, &sdir_stat) && S_ISDIR(sdir_stat.st_mode)) { - safedir = SAFE_DIR; - } else if (!stat(SAFE_DIR2, &sdir_stat) && S_ISDIR(sdir_stat.st_mode)) { - safedir = SAFE_DIR2; - } else { - fprintf(stderr, "Could not find %s\n", SAFE_DIR2); - return false; - } - - const pid_t pid = syscall(__NR_clone, CLONE_FS | SIGCHLD, 0, 0, 0); - - if (pid == -1) { - perror("clone"); - close(sv[0]); - close(sv[1]); - return false; - } - - if (pid == 0) { - // We share our files structure with an untrusted process. As a security in - // depth measure, we make sure that we can't open anything by mistake. - // TODO(agl): drop CAP_SYS_RESOURCE / use SECURE_NOROOT - - const struct rlimit nofile = {0, 0}; - if (setrlimit(RLIMIT_NOFILE, &nofile)) - FatalError("Setting RLIMIT_NOFILE"); - - if (close(sv[1])) - FatalError("close"); - - // wait for message - char msg; - ssize_t bytes; - do { - bytes = read(sv[0], &msg, 1); - } while (bytes == -1 && errno == EINTR); - - if (bytes == 0) - _exit(0); - if (bytes != 1) - FatalError("read"); - - // do chrooting - if (msg != kMsgChrootMe) - FatalError("Unknown message from sandboxed process"); - - // sanity check - if (chdir(safedir)) - FatalError("Cannot chdir into /proc/ directory"); - - if (chroot(safedir)) - FatalError("Cannot chroot into /proc/ directory"); - - if (chdir("/")) - FatalError("Cannot chdir to / after chroot"); - - const char reply = kMsgChrootSuccessful; - do { - bytes = write(sv[0], &reply, 1); - } while (bytes == -1 && errno == EINTR); - - if (bytes != 1) - FatalError("Writing reply"); - - _exit(0); - // We now become a zombie. /proc/self/fd(info) is now an empty dir and we - // are chrooted there. - // Our (unprivileged) parent should not even be able to open "." or "/" - // since they would need to pass the ptrace() check. If our parent wait() - // for us, our root directory will completely disappear. - } - - if (close(sv[0])) { - close(sv[1]); - perror("close"); - return false; - } - - // In the parent process, we install an environment variable containing the - // number of the file descriptor. - char desc_str[64]; - int printed = snprintf(desc_str, sizeof(desc_str), "%u", sv[1]); - if (printed < 0 || printed >= (int)sizeof(desc_str)) { - fprintf(stderr, "Failed to snprintf\n"); - return false; - } - - if (setenv(kSandboxDescriptorEnvironmentVarName, desc_str, 1)) { - perror("setenv"); - close(sv[1]); - return false; - } - - // We also install an environment variable containing the pid of the child - char helper_pid_str[64]; - printed = snprintf(helper_pid_str, sizeof(helper_pid_str), "%u", pid); - if (printed < 0 || printed >= (int)sizeof(helper_pid_str)) { - fprintf(stderr, "Failed to snprintf\n"); - return false; - } - - if (setenv(kSandboxHelperPidEnvironmentVarName, helper_pid_str, 1)) { - perror("setenv"); - close(sv[1]); - return false; - } - - return true; -} - -// Block until child_pid exits, then exit. Try to preserve the exit code. -static void WaitForChildAndExit(pid_t child_pid) { - int exit_code = -1; - siginfo_t reaped_child_info; - - // Don't "Core" on SIGABRT. SIGABRT is sent by the Chrome OS session manager - // when things are hanging. - // Here, the current process is going to waitid() and _exit(), so there is no - // point in generating a crash report. The child process is the one - // blocking us. - if (signal(SIGABRT, ExitWithErrorSignalHandler) == SIG_ERR) { - FatalError("Failed to change signal handler"); - } - - int wait_ret = - HANDLE_EINTR(waitid(P_PID, child_pid, &reaped_child_info, WEXITED)); - - if (!wait_ret && reaped_child_info.si_pid == child_pid) { - if (reaped_child_info.si_code == CLD_EXITED) { - exit_code = reaped_child_info.si_status; - } else { - // Exit with code 0 if the child got signaled. - exit_code = 0; - } - } - _exit(exit_code); -} - -static bool MoveToNewNamespaces() { - // These are the sets of flags which we'll try, in order. - const int kCloneExtraFlags[] = {CLONE_NEWPID | CLONE_NEWNET, CLONE_NEWPID, }; - - // We need to close kZygoteIdFd before the child can continue. We use this - // socketpair to tell the child when to continue; - int sync_fds[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_fds)) { - FatalError("Failed to create a socketpair"); - } - - for (size_t i = 0; i < sizeof(kCloneExtraFlags) / sizeof(kCloneExtraFlags[0]); - i++) { - pid_t pid = syscall(__NR_clone, SIGCHLD | kCloneExtraFlags[i], 0, 0, 0); - const int clone_errno = errno; - - if (pid > 0) { - if (!DropRoot()) { - FatalError("Could not drop privileges"); - } else { - if (close(sync_fds[0]) || shutdown(sync_fds[1], SHUT_RD)) - FatalError("Could not close socketpair"); - // The kZygoteIdFd needs to be closed in the parent before - // Zygote gets started. - if (close(kZygoteIdFd)) - FatalError("close"); - // Tell our child to continue - if (HANDLE_EINTR(send(sync_fds[1], "C", 1, MSG_NOSIGNAL)) != 1) - FatalError("send"); - if (close(sync_fds[1])) - FatalError("close"); - // We want to keep a full process tree and we don't want our childs to - // be reparented to (the outer PID namespace) init. So we wait for it. - WaitForChildAndExit(pid); - } - // NOTREACHED - FatalError("Not reached"); - } - - if (pid == 0) { - if (close(sync_fds[1]) || shutdown(sync_fds[0], SHUT_WR)) - FatalError("Could not close socketpair"); - - // Wait for the parent to confirm it closed kZygoteIdFd before we - // continue - char should_continue; - if (HANDLE_EINTR(read(sync_fds[0], &should_continue, 1)) != 1) - FatalError("Read on socketpair"); - if (close(sync_fds[0])) - FatalError("close"); - - if (kCloneExtraFlags[i] & CLONE_NEWPID) { - setenv(kSandboxPIDNSEnvironmentVarName, "", 1 /* overwrite */); - } else { - unsetenv(kSandboxPIDNSEnvironmentVarName); - } - - if (kCloneExtraFlags[i] & CLONE_NEWNET) { - setenv(kSandboxNETNSEnvironmentVarName, "", 1 /* overwrite */); - } else { - unsetenv(kSandboxNETNSEnvironmentVarName); - } - - break; - } - - // If EINVAL then the system doesn't support the requested flags, so - // continue to try a different set. - // On any other errno value the system *does* support these flags but - // something went wrong, hence we bail with an error message rather then - // provide less security. - if (errno != EINVAL) { - fprintf(stderr, "Failed to move to new namespace:"); - if (kCloneExtraFlags[i] & CLONE_NEWPID) { - fprintf(stderr, " PID namespaces supported,"); - } - if (kCloneExtraFlags[i] & CLONE_NEWNET) { - fprintf(stderr, " Network namespace supported,"); - } - fprintf(stderr, " but failed: errno = %s\n", strerror(clone_errno)); - return false; - } - } - - // If the system doesn't support NEWPID then we carry on anyway. - return true; -} - -static bool DropRoot() { - if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)) { - perror("prctl(PR_SET_DUMPABLE)"); - return false; - } - - if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) { - perror("Still dumpable after prctl(PR_SET_DUMPABLE)"); - return false; - } - - gid_t rgid, egid, sgid; - if (getresgid(&rgid, &egid, &sgid)) { - perror("getresgid"); - return false; - } - - if (setresgid(rgid, rgid, rgid)) { - perror("setresgid"); - return false; - } - - uid_t ruid, euid, suid; - if (getresuid(&ruid, &euid, &suid)) { - perror("getresuid"); - return false; - } - - if (setresuid(ruid, ruid, ruid)) { - perror("setresuid"); - return false; - } - - return true; -} - -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. - - for (i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) { - const char* const envvar = kSUIDUnsafeEnvironmentVariables[i]; - char* const saved_envvar = SandboxSavedEnvironmentVariable(envvar); - if (!saved_envvar) - return false; - - const char* const value = getenv(saved_envvar); - if (value) { - setenv(envvar, value, 1 /* overwrite */); - unsetenv(saved_envvar); - } - - free(saved_envvar); - } - - return true; -} - -bool CheckAndExportApiVersion() { - // Check the environment to see if a specific API version was requested. - // assume version 0 if none. - int api_number = -1; - char* api_string = getenv(kSandboxEnvironmentApiRequest); - if (!api_string) { - api_number = 0; - } else { - errno = 0; - char* endptr = NULL; - long long_api_number = strtol(api_string, &endptr, 10); - if (!endptr || *endptr || errno != 0 || long_api_number < INT_MIN || - long_api_number > INT_MAX) { - return false; - } - api_number = long_api_number; - } - - // Warn only for now. - if (api_number != kSUIDSandboxApiNumber) { - fprintf( - stderr, - "The setuid sandbox provides API version %d, " - "but you need %d\n" - "Please read " - "https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md." - "\n\n", - kSUIDSandboxApiNumber, - api_number); - } - - // Export our version so that the sandboxed process can verify it did not - // use an old sandbox. - char version_string[64]; - snprintf(version_string, sizeof(version_string), "%d", kSUIDSandboxApiNumber); - if (setenv(kSandboxEnvironmentApiProvides, version_string, 1)) { - perror("setenv"); - return false; - } - - return true; -} - -int main(int argc, char** argv) { - if (argc <= 1) { - if (argc <= 0) { - return 1; - } - - fprintf(stderr, "Usage: %s <renderer process> <args...>\n", argv[0]); - return 1; - } - - // Allow someone to query our API version - if (argc == 2 && 0 == strcmp(argv[1], kSuidSandboxGetApiSwitch)) { - printf("%d\n", kSUIDSandboxApiNumber); - return 0; - } - - // We cannot adjust /proc/pid/oom_adj for sandboxed renderers - // because those files are owned by root. So we need a helper here. - if (argc == 4 && (0 == strcmp(argv[1], kAdjustOOMScoreSwitch))) { - char* endptr = NULL; - long score; - errno = 0; - unsigned long pid_ul = strtoul(argv[2], &endptr, 10); - if (pid_ul == ULONG_MAX || !endptr || *endptr || errno != 0) - return 1; - pid_t pid = pid_ul; - endptr = NULL; - errno = 0; - score = strtol(argv[3], &endptr, 10); - if (score == LONG_MAX || score == LONG_MIN || !endptr || *endptr || - errno != 0) { - return 1; - } - return AdjustOOMScore(pid, score); - } - - // Protect the core setuid sandbox functionality with an API version - if (!CheckAndExportApiVersion()) { - return 1; - } - - if (geteuid() != 0) { - fprintf(stderr, - "The setuid sandbox is not running as root. Common causes:\n" - " * An unprivileged process using ptrace on it, like a debugger.\n" - " * A parent process set prctl(PR_SET_NO_NEW_PRIVS, ...)\n"); - } - - if (!MoveToNewNamespaces()) - return 1; - if (!SpawnChrootHelper()) - return 1; - if (!DropRoot()) - return 1; - if (!SetupChildEnvironment()) - return 1; - - execv(argv[1], &argv[1]); - FatalError("execv failed"); - - return 1; -} diff --git a/sandbox/linux/syscall_broker/DEPS b/sandbox/linux/syscall_broker/DEPS deleted file mode 100644 index 70d9b18aa1..0000000000 --- a/sandbox/linux/syscall_broker/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+sandbox/linux/system_headers", -] diff --git a/sandbox/linux/syscall_broker/broker_channel.cc b/sandbox/linux/syscall_broker/broker_channel.cc deleted file mode 100644 index fa0f7615fc..0000000000 --- a/sandbox/linux/syscall_broker/broker_channel.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2014 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/linux/syscall_broker/broker_channel.h" - -#include <sys/socket.h> -#include <sys/types.h> - -#include "base/logging.h" - -namespace sandbox { - -namespace syscall_broker { - -// static -void BrokerChannel::CreatePair(EndPoint* reader, EndPoint* writer) { - DCHECK(reader); - DCHECK(writer); - int socket_pair[2]; - // Use SOCK_SEQPACKET, to preserve message boundaries but we also want to be - // notified (recvmsg should return and not block) when the connection has - // been broken which could mean that the other end has been closed. - PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socket_pair)); - - reader->reset(socket_pair[0]); - PCHECK(0 == shutdown(reader->get(), SHUT_WR)); - - writer->reset(socket_pair[1]); - PCHECK(0 == shutdown(writer->get(), SHUT_RD)); -} - -} // namespace syscall_broker - -} // namespace sandbox diff --git a/sandbox/linux/syscall_broker/broker_channel.h b/sandbox/linux/syscall_broker/broker_channel.h deleted file mode 100644 index 2abdba413a..0000000000 --- a/sandbox/linux/syscall_broker/broker_channel.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 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_LINUX_SYSCALL_BROKER_BROKER_CHANNEL_H_ -#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_CHANNEL_H_ - -#include "base/files/scoped_file.h" -#include "base/macros.h" - -namespace sandbox { - -namespace syscall_broker { - -// A small class to create a pipe-like communication channel. It is based on a -// SOCK_SEQPACKET unix socket, which is connection-based and guaranteed to -// preserve message boundaries. -class BrokerChannel { - public: - typedef base::ScopedFD EndPoint; - static void CreatePair(EndPoint* reader, EndPoint* writer); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(BrokerChannel); -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_CHANNEL_H_ diff --git a/sandbox/linux/syscall_broker/broker_client.cc b/sandbox/linux/syscall_broker/broker_client.cc deleted file mode 100644 index 36c92cd073..0000000000 --- a/sandbox/linux/syscall_broker/broker_client.cc +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2014 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/linux/syscall_broker/broker_client.h" - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <utility> - -#include "base/logging.h" -#include "base/pickle.h" -#include "base/posix/unix_domain_socket_linux.h" -#include "build/build_config.h" -#include "sandbox/linux/syscall_broker/broker_channel.h" -#include "sandbox/linux/syscall_broker/broker_common.h" -#include "sandbox/linux/syscall_broker/broker_policy.h" - -#if defined(OS_ANDROID) && !defined(MSG_CMSG_CLOEXEC) -#define MSG_CMSG_CLOEXEC 0x40000000 -#endif - -namespace sandbox { - -namespace syscall_broker { - -// Make a remote system call over IPC for syscalls that take a path and flags -// as arguments, currently open() and access(). -// Will return -errno like a real system call. -// This function needs to be async signal safe. -int BrokerClient::PathAndFlagsSyscall(IPCCommand syscall_type, - const char* pathname, - int flags) const { - int recvmsg_flags = 0; - RAW_CHECK(syscall_type == COMMAND_OPEN || syscall_type == COMMAND_ACCESS); - if (!pathname) - return -EFAULT; - - // For this "remote system call" to work, we need to handle any flag that - // cannot be sent over a Unix socket in a special way. - // See the comments around kCurrentProcessOpenFlagsMask. - if (syscall_type == COMMAND_OPEN && (flags & kCurrentProcessOpenFlagsMask)) { - // This implementation only knows about O_CLOEXEC, someone needs to look at - // this code if other flags are added. - RAW_CHECK(kCurrentProcessOpenFlagsMask == O_CLOEXEC); - recvmsg_flags |= MSG_CMSG_CLOEXEC; - flags &= ~O_CLOEXEC; - } - - // There is no point in forwarding a request that we know will be denied. - // Of course, the real security check needs to be on the other side of the - // IPC. - if (fast_check_in_client_) { - if (syscall_type == COMMAND_OPEN && - !broker_policy_.GetFileNameIfAllowedToOpen( - pathname, flags, NULL /* file_to_open */, - NULL /* unlink_after_open */)) { - return -broker_policy_.denied_errno(); - } - if (syscall_type == COMMAND_ACCESS && - !broker_policy_.GetFileNameIfAllowedToAccess(pathname, flags, NULL)) { - return -broker_policy_.denied_errno(); - } - } - - base::Pickle write_pickle; - write_pickle.WriteInt(syscall_type); - write_pickle.WriteString(pathname); - write_pickle.WriteInt(flags); - RAW_CHECK(write_pickle.size() <= kMaxMessageLength); - - int returned_fd = -1; - uint8_t reply_buf[kMaxMessageLength]; - - // Send a request (in write_pickle) as well that will include a new - // temporary socketpair (created internally by SendRecvMsg()). - // Then read the reply on this new socketpair in reply_buf and put an - // eventual attached file descriptor in |returned_fd|. - ssize_t msg_len = base::UnixDomainSocket::SendRecvMsgWithFlags( - ipc_channel_.get(), reply_buf, sizeof(reply_buf), recvmsg_flags, - &returned_fd, write_pickle); - if (msg_len <= 0) { - if (!quiet_failures_for_tests_) - RAW_LOG(ERROR, "Could not make request to broker process"); - return -ENOMEM; - } - - base::Pickle read_pickle(reinterpret_cast<char*>(reply_buf), msg_len); - base::PickleIterator iter(read_pickle); - int return_value = -1; - // Now deserialize the return value and eventually return the file - // descriptor. - if (iter.ReadInt(&return_value)) { - switch (syscall_type) { - case COMMAND_ACCESS: - // We should never have a fd to return. - RAW_CHECK(returned_fd == -1); - return return_value; - case COMMAND_OPEN: - if (return_value < 0) { - RAW_CHECK(returned_fd == -1); - return return_value; - } else { - // We have a real file descriptor to return. - RAW_CHECK(returned_fd >= 0); - return returned_fd; - } - default: - RAW_LOG(ERROR, "Unsupported command"); - return -ENOSYS; - } - } else { - RAW_LOG(ERROR, "Could not read pickle"); - NOTREACHED(); - return -ENOMEM; - } -} - -BrokerClient::BrokerClient(const BrokerPolicy& broker_policy, - BrokerChannel::EndPoint ipc_channel, - bool fast_check_in_client, - bool quiet_failures_for_tests) - : broker_policy_(broker_policy), - ipc_channel_(std::move(ipc_channel)), - fast_check_in_client_(fast_check_in_client), - quiet_failures_for_tests_(quiet_failures_for_tests) {} - -BrokerClient::~BrokerClient() { -} - -int BrokerClient::Access(const char* pathname, int mode) const { - return PathAndFlagsSyscall(COMMAND_ACCESS, pathname, mode); -} - -int BrokerClient::Open(const char* pathname, int flags) const { - return PathAndFlagsSyscall(COMMAND_OPEN, pathname, flags); -} - -} // namespace syscall_broker - -} // namespace sandbox diff --git a/sandbox/linux/syscall_broker/broker_client.h b/sandbox/linux/syscall_broker/broker_client.h deleted file mode 100644 index 2dfef8150c..0000000000 --- a/sandbox/linux/syscall_broker/broker_client.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2014 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_LINUX_SYSCALL_BROKER_BROKER_CLIENT_H_ -#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_CLIENT_H_ - -#include "base/macros.h" -#include "sandbox/linux/syscall_broker/broker_channel.h" -#include "sandbox/linux/syscall_broker/broker_common.h" - -namespace sandbox { - -namespace syscall_broker { - -class BrokerPolicy; - -// This class can be embedded in a sandboxed process and can be -// used to perform certain system calls in another, presumably -// non-sandboxed process (which embeds BrokerHost). -// A key feature of this class is the ability to use some of its methods in a -// thread-safe and async-signal safe way. The goal is to be able to use it to -// replace the open() or access() system calls happening anywhere in a process -// (as allowed for instance by seccomp-bpf's SIGSYS mechanism). -class BrokerClient { - public: - // |policy| needs to match the policy used by BrokerHost. This - // allows to predict some of the requests which will be denied - // and save an IPC round trip. - // |ipc_channel| needs to be a suitable SOCK_SEQPACKET unix socket. - // |fast_check_in_client| should be set to true and - // |quiet_failures_for_tests| to false unless you are writing tests. - BrokerClient(const BrokerPolicy& policy, - BrokerChannel::EndPoint ipc_channel, - bool fast_check_in_client, - bool quiet_failures_for_tests); - ~BrokerClient(); - - // Can be used in place of access(). - // X_OK will always return an error in practice since the broker process - // doesn't support execute permissions. - // It's similar to the access() system call and will return -errno on errors. - // This is async signal safe. - int Access(const char* pathname, int mode) const; - // Can be used in place of open(). - // The implementation only supports certain white listed flags and will - // return -EPERM on other flags. - // It's similar to the open() system call and will return -errno on errors. - // This is async signal safe. - int Open(const char* pathname, int flags) const; - - // Get the file descriptor used for IPC. This is used for tests. - int GetIPCDescriptor() const { return ipc_channel_.get(); } - - private: - const BrokerPolicy& broker_policy_; - const BrokerChannel::EndPoint ipc_channel_; - const bool fast_check_in_client_; // Whether to forward a request that we - // know will be denied to the broker. (Used - // for tests). - const bool quiet_failures_for_tests_; // Disable certain error message when - // testing for failures. - - int PathAndFlagsSyscall(IPCCommand syscall_type, - const char* pathname, - int flags) const; - - DISALLOW_COPY_AND_ASSIGN(BrokerClient); -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_CLIENT_H_ diff --git a/sandbox/linux/syscall_broker/broker_common.h b/sandbox/linux/syscall_broker/broker_common.h deleted file mode 100644 index 25aafa7ed2..0000000000 --- a/sandbox/linux/syscall_broker/broker_common.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 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_LINUX_SYSCALL_BROKER_BROKER_COMMON_H_ -#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_COMMON_H_ - -#include <fcntl.h> -#include <stddef.h> - -namespace sandbox { - -namespace syscall_broker { - -const size_t kMaxMessageLength = 4096; - -// Some flags are local to the current process and cannot be sent over a Unix -// socket. They need special treatment from the client. -// O_CLOEXEC is tricky because in theory another thread could call execve() -// before special treatment is made on the client, so a client needs to call -// recvmsg(2) with MSG_CMSG_CLOEXEC. -// To make things worse, there are two CLOEXEC related flags, FD_CLOEXEC (see -// F_GETFD in fcntl(2)) and O_CLOEXEC (see F_GETFL in fcntl(2)). O_CLOEXEC -// doesn't affect the semantics on execve(), it's merely a note that the -// descriptor was originally opened with O_CLOEXEC as a flag. And it is sent -// over unix sockets just fine, so a receiver that would (incorrectly) look at -// O_CLOEXEC instead of FD_CLOEXEC may be tricked in thinking that the file -// descriptor will or won't be closed on execve(). -const int kCurrentProcessOpenFlagsMask = O_CLOEXEC; - -enum IPCCommand { - COMMAND_INVALID = 0, - COMMAND_OPEN, - COMMAND_ACCESS, -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_COMMON_H_ diff --git a/sandbox/linux/syscall_broker/broker_file_permission.cc b/sandbox/linux/syscall_broker/broker_file_permission.cc deleted file mode 100644 index 3907344446..0000000000 --- a/sandbox/linux/syscall_broker/broker_file_permission.cc +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2014 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/linux/syscall_broker/broker_file_permission.h" - -#include <fcntl.h> -#include <stddef.h> -#include <string.h> - -#include <string> - -#include "base/logging.h" -#include "sandbox/linux/syscall_broker/broker_common.h" - -namespace sandbox { - -namespace syscall_broker { - -// Async signal safe -bool BrokerFilePermission::ValidatePath(const char* path) { - if (!path) - return false; - - const size_t len = strlen(path); - // No empty paths - if (len == 0) - return false; - // Paths must be absolute and not relative - if (path[0] != '/') - return false; - // No trailing / (but "/" is valid) - if (len > 1 && path[len - 1] == '/') - return false; - // No trailing /.. - if (len >= 3 && path[len - 3] == '/' && path[len - 2] == '.' && - path[len - 1] == '.') - return false; - // No /../ anywhere - for (size_t i = 0; i < len; i++) { - if (path[i] == '/' && (len - i) > 3) { - if (path[i + 1] == '.' && path[i + 2] == '.' && path[i + 3] == '/') { - return false; - } - } - } - return true; -} - -// Async signal safe -// Calls std::string::c_str(), strncmp and strlen. All these -// methods are async signal safe in common standard libs. -// TODO(leecam): remove dependency on std::string -bool BrokerFilePermission::MatchPath(const char* requested_filename) const { - const char* path = path_.c_str(); - if ((recursive_ && strncmp(requested_filename, path, strlen(path)) == 0)) { - // Note: This prefix match will allow any path under the whitelisted - // path, for any number of directory levels. E.g. if the whitelisted - // path is /good/ then the following will be permitted by the policy. - // /good/file1 - // /good/folder/file2 - // /good/folder/folder2/file3 - // If an attacker could make 'folder' a symlink to ../../ they would have - // access to the entire filesystem. - // Whitelisting with multiple depths is useful, e.g /proc/ but - // the system needs to ensure symlinks can not be created! - // That said if an attacker can convert any of the absolute paths - // to a symlink they can control any file on the system also. - return true; - } else if (strcmp(requested_filename, path) == 0) { - return true; - } - return false; -} - -// Async signal safe. -// External call to std::string::c_str() is -// called in MatchPath. -// TODO(leecam): remove dependency on std::string -bool BrokerFilePermission::CheckAccess(const char* requested_filename, - int mode, - const char** file_to_access) const { - // First, check if |mode| is existence, ability to read or ability - // to write. We do not support X_OK. - if (mode != F_OK && mode & ~(R_OK | W_OK)) { - return false; - } - - if (!ValidatePath(requested_filename)) - return false; - - if (!MatchPath(requested_filename)) { - return false; - } - bool allowed = false; - switch (mode) { - case F_OK: - if (allow_read_ || allow_write_) - allowed = true; - break; - case R_OK: - if (allow_read_) - allowed = true; - break; - case W_OK: - if (allow_write_) - allowed = true; - break; - case R_OK | W_OK: - if (allow_read_ && allow_write_) - allowed = true; - break; - default: - return false; - } - - if (allowed && file_to_access) { - if (!recursive_) - *file_to_access = path_.c_str(); - else - *file_to_access = requested_filename; - } - return allowed; -} - -// Async signal safe. -// External call to std::string::c_str() is -// called in MatchPath. -// TODO(leecam): remove dependency on std::string -bool BrokerFilePermission::CheckOpen(const char* requested_filename, - int flags, - const char** file_to_open, - bool* unlink_after_open) const { - if (!ValidatePath(requested_filename)) - return false; - - if (!MatchPath(requested_filename)) { - return false; - } - - // First, check the access mode is valid. - const int access_mode = flags & O_ACCMODE; - if (access_mode != O_RDONLY && access_mode != O_WRONLY && - access_mode != O_RDWR) { - return false; - } - - // Check if read is allowed - if (!allow_read_ && (access_mode == O_RDONLY || access_mode == O_RDWR)) { - return false; - } - - // Check if write is allowed - if (!allow_write_ && (access_mode == O_WRONLY || access_mode == O_RDWR)) { - return false; - } - - // Check if file creation is allowed. - if (!allow_create_ && (flags & O_CREAT)) { - return false; - } - - // If O_CREAT is present, ensure O_EXCL - if ((flags & O_CREAT) && !(flags & O_EXCL)) { - return false; - } - - // If this file is to be unlinked, ensure it's created. - if (unlink_ && !(flags & O_CREAT)) { - return false; - } - - // Some flags affect the behavior of the current process. We don't support - // them and don't allow them for now. - if (flags & kCurrentProcessOpenFlagsMask) { - return false; - } - - // Now check that all the flags are known to us. - const int creation_and_status_flags = flags & ~O_ACCMODE; - - const int known_flags = O_APPEND | O_ASYNC | O_CLOEXEC | O_CREAT | O_DIRECT | - O_DIRECTORY | O_EXCL | O_LARGEFILE | O_NOATIME | - O_NOCTTY | O_NOFOLLOW | O_NONBLOCK | O_NDELAY | - O_SYNC | O_TRUNC; - - const int unknown_flags = ~known_flags; - const bool has_unknown_flags = creation_and_status_flags & unknown_flags; - - if (has_unknown_flags) - return false; - - if (file_to_open) { - if (!recursive_) - *file_to_open = path_.c_str(); - else - *file_to_open = requested_filename; - } - if (unlink_after_open) - *unlink_after_open = unlink_; - - return true; -} - -const char* BrokerFilePermission::GetErrorMessageForTests() { - static char kInvalidBrokerFileString[] = "Invalid BrokerFilePermission"; - return kInvalidBrokerFileString; -} - -BrokerFilePermission::BrokerFilePermission(const std::string& path, - bool recursive, - bool unlink, - bool allow_read, - bool allow_write, - bool allow_create) - : path_(path), - recursive_(recursive), - unlink_(unlink), - allow_read_(allow_read), - allow_write_(allow_write), - allow_create_(allow_create) { - // Validate this permission and die if invalid! - - // Must have enough length for a '/' - CHECK(path_.length() > 0) << GetErrorMessageForTests(); - // Whitelisted paths must be absolute. - CHECK(path_[0] == '/') << GetErrorMessageForTests(); - - // Don't allow unlinking on creation without create permission - if (unlink_) { - CHECK(allow_create) << GetErrorMessageForTests(); - } - const char last_char = *(path_.rbegin()); - // Recursive paths must have a trailing slash - if (recursive_) { - CHECK(last_char == '/') << GetErrorMessageForTests(); - } else { - CHECK(last_char != '/') << GetErrorMessageForTests(); - } -} - -} // namespace syscall_broker - -} // namespace sandbox
\ No newline at end of file diff --git a/sandbox/linux/syscall_broker/broker_file_permission.h b/sandbox/linux/syscall_broker/broker_file_permission.h deleted file mode 100644 index ddc62d5629..0000000000 --- a/sandbox/linux/syscall_broker/broker_file_permission.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2014 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_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_ -#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_ - -#include <string> - -#include "base/macros.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -namespace syscall_broker { - -// BrokerFilePermission defines a path for whitelisting. -// Pick the correct static factory method to create a permission. -// CheckOpen and CheckAccess are async signal safe. -// Constuction and Destruction are not async signal safe. -// |path| is the path to be whitelisted. -class SANDBOX_EXPORT BrokerFilePermission { - public: - ~BrokerFilePermission() {} - BrokerFilePermission(const BrokerFilePermission&) = default; - BrokerFilePermission& operator=(const BrokerFilePermission&) = default; - - static BrokerFilePermission ReadOnly(const std::string& path) { - return BrokerFilePermission(path, false, false, true, false, false); - } - - static BrokerFilePermission ReadOnlyRecursive(const std::string& path) { - return BrokerFilePermission(path, true, false, true, false, false); - } - - static BrokerFilePermission WriteOnly(const std::string& path) { - return BrokerFilePermission(path, false, false, false, true, false); - } - - static BrokerFilePermission ReadWrite(const std::string& path) { - return BrokerFilePermission(path, false, false, true, true, false); - } - - static BrokerFilePermission ReadWriteCreate(const std::string& path) { - return BrokerFilePermission(path, false, false, true, true, true); - } - - static BrokerFilePermission ReadWriteCreateUnlink(const std::string& path) { - return BrokerFilePermission(path, false, true, true, true, true); - } - - static BrokerFilePermission ReadWriteCreateUnlinkRecursive( - const std::string& path) { - return BrokerFilePermission(path, true, true, true, true, true); - } - - // Returns true if |requested_filename| is allowed to be opened - // by this permission. - // If |file_to_open| is not NULL it is set to point to either - // the |requested_filename| in the case of a recursive match, - // or a pointer the matched path in the whitelist if an absolute - // match. - // If not NULL |unlink_after_open| is set to point to true if the - // caller should unlink the path after opening. - // Async signal safe if |file_to_open| is NULL. - bool CheckOpen(const char* requested_filename, - int flags, - const char** file_to_open, - bool* unlink_after_open) const; - // Returns true if |requested_filename| is allowed to be accessed - // by this permission as per access(2). - // If |file_to_open| is not NULL it is set to point to either - // the |requested_filename| in the case of a recursive match, - // or a pointer to the matched path in the whitelist if an absolute - // match. - // |mode| is per mode argument of access(2). - // Async signal safe if |file_to_access| is NULL - bool CheckAccess(const char* requested_filename, - int mode, - const char** file_to_access) const; - - private: - friend class BrokerFilePermissionTester; - BrokerFilePermission(const std::string& path, - bool recursive, - bool unlink, - bool allow_read, - bool allow_write, - bool allow_create); - - // ValidatePath checks |path| and returns true if these conditions are met - // * Greater than 0 length - // * Is an absolute path - // * No trailing slash - // * No /../ path traversal - static bool ValidatePath(const char* path); - - // MatchPath returns true if |requested_filename| is covered by this instance - bool MatchPath(const char* requested_filename) const; - - // Used in by BrokerFilePermissionTester for tests. - static const char* GetErrorMessageForTests(); - - // These are not const as std::vector requires copy-assignment and this class - // is stored in vectors. All methods are marked const so - // the compiler will still enforce no changes outside of the constructor. - std::string path_; - bool recursive_; // Allow everything under this path. |path| must be a dir. - bool unlink_; // unlink after opening. - bool allow_read_; - bool allow_write_; - bool allow_create_; -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_
\ No newline at end of file diff --git a/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc b/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc deleted file mode 100644 index 83840779f9..0000000000 --- a/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright 2014 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/linux/syscall_broker/broker_file_permission.h" - -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "sandbox/linux/tests/test_utils.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace syscall_broker { - -class BrokerFilePermissionTester { - public: - static bool ValidatePath(const char* path) { - return BrokerFilePermission::ValidatePath(path); - } - static const char* GetErrorMessage() { - return BrokerFilePermission::GetErrorMessageForTests(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(BrokerFilePermissionTester); -}; - -namespace { - -// Creation tests are DEATH tests as a bad permission causes termination. -SANDBOX_TEST(BrokerFilePermission, CreateGood) { - const char kPath[] = "/tmp/good"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnly(kPath); -} - -SANDBOX_TEST(BrokerFilePermission, CreateGoodRecursive) { - const char kPath[] = "/tmp/good/"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnlyRecursive(kPath); -} - -// In official builds, CHECK(x) causes a SIGTRAP on the architectures where the -// sanbox is enabled (that are x86, x86_64, arm64 and 32-bit arm processes -// running on a arm64 kernel). -#if defined(OFFICIAL_BUILD) -#define DEATH_BY_CHECK(msg) DEATH_BY_SIGNAL(SIGTRAP) -#else -#define DEATH_BY_CHECK(msg) DEATH_MESSAGE(msg) -#endif - -SANDBOX_DEATH_TEST( - BrokerFilePermission, - CreateBad, - DEATH_BY_CHECK(BrokerFilePermissionTester::GetErrorMessage())) { - const char kPath[] = "/tmp/bad/"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnly(kPath); -} - -SANDBOX_DEATH_TEST( - BrokerFilePermission, - CreateBadRecursive, - DEATH_BY_CHECK(BrokerFilePermissionTester::GetErrorMessage())) { - const char kPath[] = "/tmp/bad"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnlyRecursive(kPath); -} - -SANDBOX_DEATH_TEST( - BrokerFilePermission, - CreateBadNotAbs, - DEATH_BY_CHECK(BrokerFilePermissionTester::GetErrorMessage())) { - const char kPath[] = "tmp/bad"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnly(kPath); -} - -SANDBOX_DEATH_TEST( - BrokerFilePermission, - CreateBadEmpty, - DEATH_BY_CHECK(BrokerFilePermissionTester::GetErrorMessage())) { - const char kPath[] = ""; - BrokerFilePermission perm = BrokerFilePermission::ReadOnly(kPath); -} - -// CheckPerm tests |path| against |perm| given |access_flags|. -// If |create| is true then file creation is tested for success. -void CheckPerm(const BrokerFilePermission& perm, - const char* path, - int access_flags, - bool create) { - const char* file_to_open = NULL; - - ASSERT_FALSE(perm.CheckAccess(path, X_OK, NULL)); - ASSERT_TRUE(perm.CheckAccess(path, F_OK, NULL)); - // check bad perms - switch (access_flags) { - case O_RDONLY: - ASSERT_TRUE(perm.CheckOpen(path, O_RDONLY, &file_to_open, NULL)); - ASSERT_FALSE(perm.CheckOpen(path, O_WRONLY, &file_to_open, NULL)); - ASSERT_FALSE(perm.CheckOpen(path, O_RDWR, &file_to_open, NULL)); - ASSERT_TRUE(perm.CheckAccess(path, R_OK, NULL)); - ASSERT_FALSE(perm.CheckAccess(path, W_OK, NULL)); - break; - case O_WRONLY: - ASSERT_FALSE(perm.CheckOpen(path, O_RDONLY, &file_to_open, NULL)); - ASSERT_TRUE(perm.CheckOpen(path, O_WRONLY, &file_to_open, NULL)); - ASSERT_FALSE(perm.CheckOpen(path, O_RDWR, &file_to_open, NULL)); - ASSERT_FALSE(perm.CheckAccess(path, R_OK, NULL)); - ASSERT_TRUE(perm.CheckAccess(path, W_OK, NULL)); - break; - case O_RDWR: - ASSERT_TRUE(perm.CheckOpen(path, O_RDONLY, &file_to_open, NULL)); - ASSERT_TRUE(perm.CheckOpen(path, O_WRONLY, &file_to_open, NULL)); - ASSERT_TRUE(perm.CheckOpen(path, O_RDWR, &file_to_open, NULL)); - ASSERT_TRUE(perm.CheckAccess(path, R_OK, NULL)); - ASSERT_TRUE(perm.CheckAccess(path, W_OK, NULL)); - break; - default: - // Bad test case - NOTREACHED(); - } - -// O_SYNC can be defined as (__O_SYNC|O_DSYNC) -#ifdef O_DSYNC - const int kSyncFlag = O_SYNC & ~O_DSYNC; -#else - const int kSyncFlag = O_SYNC; -#endif - - const int kNumberOfBitsInOAccMode = 2; - static_assert(O_ACCMODE == ((1 << kNumberOfBitsInOAccMode) - 1), - "incorrect number of bits"); - // check every possible flag and act accordingly. - // Skipping AccMode bits as they are present in every case. - for (int i = kNumberOfBitsInOAccMode; i < 32; i++) { - int flag = 1 << i; - switch (flag) { - case O_APPEND: - case O_ASYNC: - case O_DIRECT: - case O_DIRECTORY: -#ifdef O_DSYNC - case O_DSYNC: -#endif - case O_EXCL: - case O_LARGEFILE: - case O_NOATIME: - case O_NOCTTY: - case O_NOFOLLOW: - case O_NONBLOCK: -#if (O_NONBLOCK != O_NDELAY) - case O_NDELAY: -#endif - case kSyncFlag: - case O_TRUNC: - ASSERT_TRUE( - perm.CheckOpen(path, access_flags | flag, &file_to_open, NULL)); - break; - case O_CLOEXEC: - case O_CREAT: - default: - ASSERT_FALSE( - perm.CheckOpen(path, access_flags | flag, &file_to_open, NULL)); - } - } - if (create) { - bool unlink; - ASSERT_TRUE(perm.CheckOpen(path, O_CREAT | O_EXCL | access_flags, - &file_to_open, &unlink)); - ASSERT_FALSE(unlink); - } else { - ASSERT_FALSE(perm.CheckOpen(path, O_CREAT | O_EXCL | access_flags, - &file_to_open, NULL)); - } -} - -TEST(BrokerFilePermission, ReadOnly) { - const char kPath[] = "/tmp/good"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnly(kPath); - CheckPerm(perm, kPath, O_RDONLY, false); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerFilePermission, ReadOnlyRecursive) { - const char kPath[] = "/tmp/good/"; - const char kPathFile[] = "/tmp/good/file"; - BrokerFilePermission perm = BrokerFilePermission::ReadOnlyRecursive(kPath); - CheckPerm(perm, kPathFile, O_RDONLY, false); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerFilePermission, WriteOnly) { - const char kPath[] = "/tmp/good"; - BrokerFilePermission perm = BrokerFilePermission::WriteOnly(kPath); - CheckPerm(perm, kPath, O_WRONLY, false); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerFilePermission, ReadWrite) { - const char kPath[] = "/tmp/good"; - BrokerFilePermission perm = BrokerFilePermission::ReadWrite(kPath); - CheckPerm(perm, kPath, O_RDWR, false); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerFilePermission, ReadWriteCreate) { - const char kPath[] = "/tmp/good"; - BrokerFilePermission perm = BrokerFilePermission::ReadWriteCreate(kPath); - CheckPerm(perm, kPath, O_RDWR, true); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -void CheckUnlink(BrokerFilePermission& perm, - const char* path, - int access_flags) { - bool unlink; - ASSERT_FALSE(perm.CheckOpen(path, access_flags, NULL, &unlink)); - ASSERT_FALSE(perm.CheckOpen(path, access_flags | O_CREAT, NULL, &unlink)); - ASSERT_TRUE( - perm.CheckOpen(path, access_flags | O_CREAT | O_EXCL, NULL, &unlink)); - ASSERT_TRUE(unlink); -} - -TEST(BrokerFilePermission, ReadWriteCreateUnlink) { - const char kPath[] = "/tmp/good"; - BrokerFilePermission perm = - BrokerFilePermission::ReadWriteCreateUnlink(kPath); - CheckUnlink(perm, kPath, O_RDWR); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerFilePermission, ReadWriteCreateUnlinkRecursive) { - const char kPath[] = "/tmp/good/"; - const char kPathFile[] = "/tmp/good/file"; - BrokerFilePermission perm = - BrokerFilePermission::ReadWriteCreateUnlinkRecursive(kPath); - CheckUnlink(perm, kPathFile, O_RDWR); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerFilePermission, ValidatePath) { - EXPECT_TRUE(BrokerFilePermissionTester::ValidatePath("/path")); - EXPECT_TRUE(BrokerFilePermissionTester::ValidatePath("/")); - EXPECT_TRUE(BrokerFilePermissionTester::ValidatePath("/..path")); - - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("")); - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("bad")); - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("/bad/")); - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("bad/")); - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("/bad/..")); - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("/bad/../bad")); - EXPECT_FALSE(BrokerFilePermissionTester::ValidatePath("/../bad")); -} - -} // namespace - -} // namespace syscall_broker - -} // namespace sandbox diff --git a/sandbox/linux/syscall_broker/broker_host.cc b/sandbox/linux/syscall_broker/broker_host.cc deleted file mode 100644 index dd61dac621..0000000000 --- a/sandbox/linux/syscall_broker/broker_host.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2014 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/linux/syscall_broker/broker_host.h" - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include <string> -#include <utility> -#include <vector> - -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/pickle.h" -#include "base/posix/eintr_wrapper.h" -#include "base/posix/unix_domain_socket_linux.h" -#include "base/third_party/valgrind/valgrind.h" -#include "sandbox/linux/syscall_broker/broker_common.h" -#include "sandbox/linux/syscall_broker/broker_policy.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -namespace sandbox { - -namespace syscall_broker { - -namespace { - -bool IsRunningOnValgrind() { - return RUNNING_ON_VALGRIND; -} - -// A little open(2) wrapper to handle some oddities for us. In the general case -// make a direct system call since we want to keep in control of the broker -// process' system calls profile to be able to loosely sandbox it. -int sys_open(const char* pathname, int flags) { - // Hardcode mode to rw------- when creating files. - int mode; - if (flags & O_CREAT) { - mode = 0600; - } else { - mode = 0; - } - if (IsRunningOnValgrind()) { - // Valgrind does not support AT_FDCWD, just use libc's open() in this case. - return open(pathname, flags, mode); - } else { - return syscall(__NR_openat, AT_FDCWD, pathname, flags, mode); - } -} - -// Open |requested_filename| with |flags| if allowed by our policy. -// Write the syscall return value (-errno) to |write_pickle| and append -// a file descriptor to |opened_files| if relevant. -void OpenFileForIPC(const BrokerPolicy& policy, - const std::string& requested_filename, - int flags, - base::Pickle* write_pickle, - std::vector<int>* opened_files) { - DCHECK(write_pickle); - DCHECK(opened_files); - const char* file_to_open = NULL; - bool unlink_after_open = false; - const bool safe_to_open_file = policy.GetFileNameIfAllowedToOpen( - requested_filename.c_str(), flags, &file_to_open, &unlink_after_open); - - if (safe_to_open_file) { - CHECK(file_to_open); - int opened_fd = sys_open(file_to_open, flags); - if (opened_fd < 0) { - write_pickle->WriteInt(-errno); - } else { - // Success. - if (unlink_after_open) { - unlink(file_to_open); - } - opened_files->push_back(opened_fd); - write_pickle->WriteInt(0); - } - } else { - write_pickle->WriteInt(-policy.denied_errno()); - } -} - -// Perform access(2) on |requested_filename| with mode |mode| if allowed by our -// policy. Write the syscall return value (-errno) to |write_pickle|. -void AccessFileForIPC(const BrokerPolicy& policy, - const std::string& requested_filename, - int mode, - base::Pickle* write_pickle) { - DCHECK(write_pickle); - const char* file_to_access = NULL; - const bool safe_to_access_file = policy.GetFileNameIfAllowedToAccess( - requested_filename.c_str(), mode, &file_to_access); - - if (safe_to_access_file) { - CHECK(file_to_access); - int access_ret = access(file_to_access, mode); - int access_errno = errno; - if (!access_ret) - write_pickle->WriteInt(0); - else - write_pickle->WriteInt(-access_errno); - } else { - write_pickle->WriteInt(-policy.denied_errno()); - } -} - -// Handle a |command_type| request contained in |iter| and send the reply -// on |reply_ipc|. -// Currently COMMAND_OPEN and COMMAND_ACCESS are supported. -bool HandleRemoteCommand(const BrokerPolicy& policy, - IPCCommand command_type, - int reply_ipc, - base::PickleIterator iter) { - // Currently all commands have two arguments: filename and flags. - std::string requested_filename; - int flags = 0; - if (!iter.ReadString(&requested_filename) || !iter.ReadInt(&flags)) - return false; - - base::Pickle write_pickle; - std::vector<int> opened_files; - - switch (command_type) { - case COMMAND_ACCESS: - AccessFileForIPC(policy, requested_filename, flags, &write_pickle); - break; - case COMMAND_OPEN: - OpenFileForIPC( - policy, requested_filename, flags, &write_pickle, &opened_files); - break; - default: - LOG(ERROR) << "Invalid IPC command"; - break; - } - - CHECK_LE(write_pickle.size(), kMaxMessageLength); - ssize_t sent = base::UnixDomainSocket::SendMsg( - reply_ipc, write_pickle.data(), write_pickle.size(), opened_files); - - // Close anything we have opened in this process. - for (std::vector<int>::iterator it = opened_files.begin(); - it != opened_files.end(); - ++it) { - int ret = IGNORE_EINTR(close(*it)); - DCHECK(!ret) << "Could not close file descriptor"; - } - - if (sent <= 0) { - LOG(ERROR) << "Could not send IPC reply"; - return false; - } - return true; -} - -} // namespace - -BrokerHost::BrokerHost(const BrokerPolicy& broker_policy, - BrokerChannel::EndPoint ipc_channel) - : broker_policy_(broker_policy), ipc_channel_(std::move(ipc_channel)) {} - -BrokerHost::~BrokerHost() { -} - -// Handle a request on the IPC channel ipc_channel_. -// A request should have a file descriptor attached on which we will reply and -// that we will then close. -// A request should start with an int that will be used as the command type. -BrokerHost::RequestStatus BrokerHost::HandleRequest() const { - std::vector<base::ScopedFD> fds; - char buf[kMaxMessageLength]; - errno = 0; - const ssize_t msg_len = base::UnixDomainSocket::RecvMsg( - ipc_channel_.get(), buf, sizeof(buf), &fds); - - if (msg_len == 0 || (msg_len == -1 && errno == ECONNRESET)) { - // EOF from the client, or the client died, we should die. - return RequestStatus::LOST_CLIENT; - } - - // The client should send exactly one file descriptor, on which we - // will write the reply. - if (msg_len < 0 || fds.size() != 1 || fds[0].get() < 0) { - PLOG(ERROR) << "Error reading message from the client"; - return RequestStatus::FAILURE; - } - - base::ScopedFD temporary_ipc(std::move(fds[0])); - - base::Pickle pickle(buf, msg_len); - base::PickleIterator iter(pickle); - int command_type; - if (iter.ReadInt(&command_type)) { - bool command_handled = false; - // Go through all the possible IPC messages. - switch (command_type) { - case COMMAND_ACCESS: - case COMMAND_OPEN: - // We reply on the file descriptor sent to us via the IPC channel. - command_handled = HandleRemoteCommand( - broker_policy_, static_cast<IPCCommand>(command_type), - temporary_ipc.get(), iter); - break; - default: - NOTREACHED(); - break; - } - - if (command_handled) { - return RequestStatus::SUCCESS; - } else { - return RequestStatus::FAILURE; - } - - NOTREACHED(); - } - - LOG(ERROR) << "Error parsing IPC request"; - return RequestStatus::FAILURE; -} - -} // namespace syscall_broker - -} // namespace sandbox diff --git a/sandbox/linux/syscall_broker/broker_host.h b/sandbox/linux/syscall_broker/broker_host.h deleted file mode 100644 index 9866507d1c..0000000000 --- a/sandbox/linux/syscall_broker/broker_host.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 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_LINUX_SYSCALL_BROKER_BROKER_HOST_H_ -#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_HOST_H_ - -#include "base/macros.h" -#include "sandbox/linux/syscall_broker/broker_channel.h" - -namespace sandbox { - -namespace syscall_broker { - -class BrokerPolicy; - -// The BrokerHost class should be embedded in a (presumably not sandboxed) -// process. It will honor IPC requests from a BrokerClient sent over -// |ipc_channel| according to |broker_policy|. -class BrokerHost { - public: - enum class RequestStatus { LOST_CLIENT = 0, SUCCESS, FAILURE }; - - BrokerHost(const BrokerPolicy& broker_policy, - BrokerChannel::EndPoint ipc_channel); - ~BrokerHost(); - - RequestStatus HandleRequest() const; - - private: - const BrokerPolicy& broker_policy_; - const BrokerChannel::EndPoint ipc_channel_; - - DISALLOW_COPY_AND_ASSIGN(BrokerHost); -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_HOST_H_ diff --git a/sandbox/linux/syscall_broker/broker_policy.cc b/sandbox/linux/syscall_broker/broker_policy.cc deleted file mode 100644 index cd09245d37..0000000000 --- a/sandbox/linux/syscall_broker/broker_policy.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2014 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/linux/syscall_broker/broker_policy.h" - -#include <fcntl.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#include <string> -#include <vector> - -#include "base/logging.h" -#include "sandbox/linux/syscall_broker/broker_common.h" - -namespace sandbox { -namespace syscall_broker { - -BrokerPolicy::BrokerPolicy(int denied_errno, - const std::vector<BrokerFilePermission>& permissions) - : denied_errno_(denied_errno), - permissions_(permissions), - num_of_permissions_(permissions.size()) { - // The spec guarantees vectors store their elements contiguously - // so set up a pointer to array of element so it can be used - // in async signal safe code instead of vector operations. - if (num_of_permissions_ > 0) { - permissions_array_ = &permissions_[0]; - } else { - permissions_array_ = NULL; - } -} - -BrokerPolicy::~BrokerPolicy() { -} - -// Check if calling access() should be allowed on |requested_filename| with -// mode |requested_mode|. -// Note: access() being a system call to check permissions, this can get a bit -// confusing. We're checking if calling access() should even be allowed with -// the same policy we would use for open(). -// If |file_to_access| is not NULL, we will return the matching pointer from -// the whitelist. For paranoia a caller should then use |file_to_access|. See -// GetFileNameIfAllowedToOpen() for more explanation. -// return true if calling access() on this file should be allowed, false -// otherwise. -// Async signal safe if and only if |file_to_access| is NULL. -bool BrokerPolicy::GetFileNameIfAllowedToAccess( - const char* requested_filename, - int requested_mode, - const char** file_to_access) const { - if (file_to_access && *file_to_access) { - // Make sure that callers never pass a non-empty string. In case callers - // wrongly forget to check the return value and look at the string - // instead, this could catch bugs. - RAW_LOG(FATAL, "*file_to_access should be NULL"); - return false; - } - for (size_t i = 0; i < num_of_permissions_; i++) { - if (permissions_array_[i].CheckAccess(requested_filename, requested_mode, - file_to_access)) { - return true; - } - } - return false; -} - -// Check if |requested_filename| can be opened with flags |requested_flags|. -// If |file_to_open| is not NULL, we will return the matching pointer from the -// whitelist. For paranoia, a caller should then use |file_to_open| rather -// than |requested_filename|, so that it never attempts to open an -// attacker-controlled file name, even if an attacker managed to fool the -// string comparison mechanism. -// Return true if opening should be allowed, false otherwise. -// Async signal safe if and only if |file_to_open| is NULL. -bool BrokerPolicy::GetFileNameIfAllowedToOpen(const char* requested_filename, - int requested_flags, - const char** file_to_open, - bool* unlink_after_open) const { - if (file_to_open && *file_to_open) { - // Make sure that callers never pass a non-empty string. In case callers - // wrongly forget to check the return value and look at the string - // instead, this could catch bugs. - RAW_LOG(FATAL, "*file_to_open should be NULL"); - return false; - } - for (size_t i = 0; i < num_of_permissions_; i++) { - if (permissions_array_[i].CheckOpen(requested_filename, requested_flags, - file_to_open, unlink_after_open)) { - return true; - } - } - return false; -} - -} // namespace syscall_broker - -} // namespace sandbox diff --git a/sandbox/linux/syscall_broker/broker_policy.h b/sandbox/linux/syscall_broker/broker_policy.h deleted file mode 100644 index 58bc29a76e..0000000000 --- a/sandbox/linux/syscall_broker/broker_policy.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2014 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_LINUX_SYSCALL_BROKER_BROKER_POLICY_H_ -#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_POLICY_H_ - -#include <stddef.h> - -#include <string> -#include <vector> - -#include "base/macros.h" - -#include "sandbox/linux/syscall_broker/broker_file_permission.h" - -namespace sandbox { -namespace syscall_broker { - -// BrokerPolicy allows to define the security policy enforced by a -// BrokerHost. The BrokerHost will evaluate requests sent over its -// IPC channel according to the BrokerPolicy. -// Some of the methods of this class can be used in an async-signal safe -// way. -class BrokerPolicy { - public: - // |denied_errno| is the error code returned when IPC requests for system - // calls such as open() or access() are denied because a file is not in the - // whitelist. EACCESS would be a typical value. - // |permissions| is a list of BrokerPermission objects that define - // what the broker will allow. - BrokerPolicy(int denied_errno, - const std::vector<BrokerFilePermission>& permissions); - - ~BrokerPolicy(); - - // Check if calling access() should be allowed on |requested_filename| with - // mode |requested_mode|. - // Note: access() being a system call to check permissions, this can get a bit - // confusing. We're checking if calling access() should even be allowed with - // If |file_to_open| is not NULL, a pointer to the path will be returned. - // In the case of a recursive match, this will be the requested_filename, - // otherwise it will return the matching pointer from the - // whitelist. For paranoia a caller should then use |file_to_access|. See - // GetFileNameIfAllowedToOpen() for more explanation. - // return true if calling access() on this file should be allowed, false - // otherwise. - // Async signal safe if and only if |file_to_access| is NULL. - bool GetFileNameIfAllowedToAccess(const char* requested_filename, - int requested_mode, - const char** file_to_access) const; - - // Check if |requested_filename| can be opened with flags |requested_flags|. - // If |file_to_open| is not NULL, a pointer to the path will be returned. - // In the case of a recursive match, this will be the requested_filename, - // otherwise it will return the matching pointer from the - // whitelist. For paranoia, a caller should then use |file_to_open| rather - // than |requested_filename|, so that it never attempts to open an - // attacker-controlled file name, even if an attacker managed to fool the - // string comparison mechanism. - // |unlink_after_open| if not NULL will be set to point to true if the - // policy requests the caller unlink the path after opening. - // Return true if opening should be allowed, false otherwise. - // Async signal safe if and only if |file_to_open| is NULL. - bool GetFileNameIfAllowedToOpen(const char* requested_filename, - int requested_flags, - const char** file_to_open, - bool* unlink_after_open) const; - int denied_errno() const { return denied_errno_; } - - private: - const int denied_errno_; - // The permissions_ vector is used as storage for the BrokerFilePermission - // objects but is not referenced outside of the constructor as - // vectors are unfriendly in async signal safe code. - const std::vector<BrokerFilePermission> permissions_; - // permissions_array_ is set up to point to the backing store of - // permissions_ and is used in async signal safe methods. - const BrokerFilePermission* permissions_array_; - const size_t num_of_permissions_; - - DISALLOW_COPY_AND_ASSIGN(BrokerPolicy); -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_POLICY_H_ diff --git a/sandbox/linux/syscall_broker/broker_process.cc b/sandbox/linux/syscall_broker/broker_process.cc deleted file mode 100644 index 30713cedcc..0000000000 --- a/sandbox/linux/syscall_broker/broker_process.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2012 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/linux/syscall_broker/broker_process.h" - -#include <fcntl.h> -#include <signal.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <algorithm> -#include <string> -#include <utility> -#include <vector> - -#include "base/callback.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/process_metrics.h" -#include "build/build_config.h" -#include "sandbox/linux/syscall_broker/broker_channel.h" -#include "sandbox/linux/syscall_broker/broker_client.h" -#include "sandbox/linux/syscall_broker/broker_host.h" - -namespace sandbox { - -namespace syscall_broker { - -BrokerProcess::BrokerProcess( - int denied_errno, - const std::vector<syscall_broker::BrokerFilePermission>& permissions, - bool fast_check_in_client, - bool quiet_failures_for_tests) - : initialized_(false), - fast_check_in_client_(fast_check_in_client), - quiet_failures_for_tests_(quiet_failures_for_tests), - broker_pid_(-1), - policy_(denied_errno, permissions) { -} - -BrokerProcess::~BrokerProcess() { - if (initialized_) { - if (broker_client_.get()) { - // Closing the socket should be enough to notify the child to die, - // unless it has been duplicated. - CloseChannel(); - } - PCHECK(0 == kill(broker_pid_, SIGKILL)); - siginfo_t process_info; - // Reap the child. - int ret = HANDLE_EINTR(waitid(P_PID, broker_pid_, &process_info, WEXITED)); - PCHECK(0 == ret); - } -} - -bool BrokerProcess::Init( - const base::Callback<bool(void)>& broker_process_init_callback) { - CHECK(!initialized_); - BrokerChannel::EndPoint ipc_reader; - BrokerChannel::EndPoint ipc_writer; - BrokerChannel::CreatePair(&ipc_reader, &ipc_writer); - -#if !defined(THREAD_SANITIZER) - DCHECK_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle())); -#endif - int child_pid = fork(); - if (child_pid == -1) { - return false; - } - if (child_pid) { - // We are the parent and we have just forked our broker process. - ipc_reader.reset(); - broker_pid_ = child_pid; - broker_client_.reset(new BrokerClient(policy_, std::move(ipc_writer), - fast_check_in_client_, - quiet_failures_for_tests_)); - initialized_ = true; - return true; - } else { - // We are the broker process. Make sure to close the writer's end so that - // we get notified if the client disappears. - ipc_writer.reset(); - CHECK(broker_process_init_callback.Run()); - BrokerHost broker_host(policy_, std::move(ipc_reader)); - for (;;) { - switch (broker_host.HandleRequest()) { - case BrokerHost::RequestStatus::LOST_CLIENT: - _exit(1); - case BrokerHost::RequestStatus::SUCCESS: - case BrokerHost::RequestStatus::FAILURE: - continue; - } - } - _exit(1); - } - NOTREACHED(); - return false; -} - -void BrokerProcess::CloseChannel() { - broker_client_.reset(); -} - -int BrokerProcess::Access(const char* pathname, int mode) const { - RAW_CHECK(initialized_); - return broker_client_->Access(pathname, mode); -} - -int BrokerProcess::Open(const char* pathname, int flags) const { - RAW_CHECK(initialized_); - return broker_client_->Open(pathname, flags); -} - -} // namespace syscall_broker - -} // namespace sandbox. diff --git a/sandbox/linux/syscall_broker/broker_process.h b/sandbox/linux/syscall_broker/broker_process.h deleted file mode 100644 index 3c0c8090cf..0000000000 --- a/sandbox/linux/syscall_broker/broker_process.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SERVICES_BROKER_PROCESS_H_ -#define SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/pickle.h" -#include "base/process/process.h" -#include "sandbox/linux/syscall_broker/broker_policy.h" -#include "sandbox/sandbox_export.h" - -namespace sandbox { - -namespace syscall_broker { - -class BrokerClient; -class BrokerFilePermission; - -// Create a new "broker" process to which we can send requests via an IPC -// channel by forking the current process. -// This is a low level IPC mechanism that is suitable to be called from a -// signal handler. -// A process would typically create a broker process before entering -// sandboxing. -// 1. BrokerProcess open_broker(read_whitelist, write_whitelist); -// 2. CHECK(open_broker.Init(NULL)); -// 3. Enable sandbox. -// 4. Use open_broker.Open() to open files. -class SANDBOX_EXPORT BrokerProcess { - public: - // |denied_errno| is the error code returned when methods such as Open() - // or Access() are invoked on a file which is not in the whitelist. EACCESS - // would be a typical value. - // |allowed_r_files| and |allowed_w_files| are white lists of files that can - // be opened later via the Open() API, respectively for reading and writing. - // A file available read-write should be listed in both. - // |fast_check_in_client| and |quiet_failures_for_tests| are reserved for - // unit tests, don't use it. - - BrokerProcess( - int denied_errno, - const std::vector<syscall_broker::BrokerFilePermission>& permissions, - bool fast_check_in_client = true, - bool quiet_failures_for_tests = false); - - ~BrokerProcess(); - // Will initialize the broker process. There should be no threads at this - // point, since we need to fork(). - // broker_process_init_callback will be called in the new broker process, - // after fork() returns. - bool Init(const base::Callback<bool(void)>& broker_process_init_callback); - - // Can be used in place of access(). Will be async signal safe. - // X_OK will always return an error in practice since the broker process - // doesn't support execute permissions. - // It's similar to the access() system call and will return -errno on errors. - int Access(const char* pathname, int mode) const; - // Can be used in place of open(). Will be async signal safe. - // The implementation only supports certain white listed flags and will - // return -EPERM on other flags. - // It's similar to the open() system call and will return -errno on errors. - int Open(const char* pathname, int flags) const; - - int broker_pid() const { return broker_pid_; } - - private: - friend class BrokerProcessTestHelper; - - // Close the IPC channel with the other party. This should only be used - // by tests an none of the class methods should be used afterwards. - void CloseChannel(); - - bool initialized_; // Whether we've been through Init() yet. - const bool fast_check_in_client_; - const bool quiet_failures_for_tests_; - pid_t broker_pid_; // The PID of the broker (child). - syscall_broker::BrokerPolicy policy_; // The sandboxing policy. - std::unique_ptr<syscall_broker::BrokerClient> broker_client_; - - DISALLOW_COPY_AND_ASSIGN(BrokerProcess); -}; - -} // namespace syscall_broker - -} // namespace sandbox - -#endif // SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_ diff --git a/sandbox/linux/syscall_broker/broker_process_unittest.cc b/sandbox/linux/syscall_broker/broker_process_unittest.cc deleted file mode 100644 index 229764a8b8..0000000000 --- a/sandbox/linux/syscall_broker/broker_process_unittest.cc +++ /dev/null @@ -1,666 +0,0 @@ -// Copyright (c) 2012 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/linux/syscall_broker/broker_process.h" - -#include <errno.h> -#include <fcntl.h> -#include <poll.h> -#include <stddef.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <algorithm> -#include <memory> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/posix/unix_domain_socket_linux.h" -#include "sandbox/linux/syscall_broker/broker_client.h" -#include "sandbox/linux/tests/scoped_temporary_file.h" -#include "sandbox/linux/tests/test_utils.h" -#include "sandbox/linux/tests/unit_tests.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sandbox { - -namespace syscall_broker { - -class BrokerProcessTestHelper { - public: - static void CloseChannel(BrokerProcess* broker) { broker->CloseChannel(); } - // Get the client's IPC descriptor to send IPC requests directly. - // TODO(jln): refator tests to get rid of this. - static int GetIPCDescriptor(const BrokerProcess* broker) { - return broker->broker_client_->GetIPCDescriptor(); - } -}; - -namespace { - -bool NoOpCallback() { - return true; -} - -} // namespace - -TEST(BrokerProcess, CreateAndDestroy) { - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly("/proc/cpuinfo")); - - std::unique_ptr<BrokerProcess> open_broker( - new BrokerProcess(EPERM, permissions)); - ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); - - ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); - // Destroy the broker and check it has exited properly. - open_broker.reset(); - ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); -} - -TEST(BrokerProcess, TestOpenAccessNull) { - std::vector<BrokerFilePermission> empty; - BrokerProcess open_broker(EPERM, empty); - ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); - - int fd = open_broker.Open(NULL, O_RDONLY); - ASSERT_EQ(fd, -EFAULT); - - int ret = open_broker.Access(NULL, F_OK); - ASSERT_EQ(ret, -EFAULT); -} - -void TestOpenFilePerms(bool fast_check_in_client, int denied_errno) { - const char kR_WhiteListed[] = "/proc/DOESNOTEXIST1"; - // We can't debug the init process, and shouldn't be able to access - // its auxv file. - const char kR_WhiteListedButDenied[] = "/proc/1/auxv"; - const char kW_WhiteListed[] = "/proc/DOESNOTEXIST2"; - const char kRW_WhiteListed[] = "/proc/DOESNOTEXIST3"; - const char k_NotWhitelisted[] = "/proc/DOESNOTEXIST4"; - - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly(kR_WhiteListed)); - permissions.push_back( - BrokerFilePermission::ReadOnly(kR_WhiteListedButDenied)); - permissions.push_back(BrokerFilePermission::WriteOnly(kW_WhiteListed)); - permissions.push_back(BrokerFilePermission::ReadWrite(kRW_WhiteListed)); - - BrokerProcess open_broker(denied_errno, permissions, fast_check_in_client); - ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); - - int fd = -1; - fd = open_broker.Open(kR_WhiteListed, O_RDONLY); - ASSERT_EQ(fd, -ENOENT); - fd = open_broker.Open(kR_WhiteListed, O_WRONLY); - ASSERT_EQ(fd, -denied_errno); - fd = open_broker.Open(kR_WhiteListed, O_RDWR); - ASSERT_EQ(fd, -denied_errno); - int ret = -1; - ret = open_broker.Access(kR_WhiteListed, F_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kR_WhiteListed, R_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kR_WhiteListed, W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kR_WhiteListed, R_OK | W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kR_WhiteListed, X_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kR_WhiteListed, R_OK | X_OK); - ASSERT_EQ(ret, -denied_errno); - - // Android sometimes runs tests as root. - // This part of the test requires a process that doesn't have - // CAP_DAC_OVERRIDE. We check against a root euid as a proxy for that. - if (geteuid()) { - fd = open_broker.Open(kR_WhiteListedButDenied, O_RDONLY); - // The broker process will allow this, but the normal permission system - // won't. - ASSERT_EQ(fd, -EACCES); - fd = open_broker.Open(kR_WhiteListedButDenied, O_WRONLY); - ASSERT_EQ(fd, -denied_errno); - fd = open_broker.Open(kR_WhiteListedButDenied, O_RDWR); - ASSERT_EQ(fd, -denied_errno); - ret = open_broker.Access(kR_WhiteListedButDenied, F_OK); - // The normal permission system will let us check that the file exists. - ASSERT_EQ(ret, 0); - ret = open_broker.Access(kR_WhiteListedButDenied, R_OK); - ASSERT_EQ(ret, -EACCES); - ret = open_broker.Access(kR_WhiteListedButDenied, W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kR_WhiteListedButDenied, R_OK | W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kR_WhiteListedButDenied, X_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kR_WhiteListedButDenied, R_OK | X_OK); - ASSERT_EQ(ret, -denied_errno); - } - - fd = open_broker.Open(kW_WhiteListed, O_RDONLY); - ASSERT_EQ(fd, -denied_errno); - fd = open_broker.Open(kW_WhiteListed, O_WRONLY); - ASSERT_EQ(fd, -ENOENT); - fd = open_broker.Open(kW_WhiteListed, O_RDWR); - ASSERT_EQ(fd, -denied_errno); - ret = open_broker.Access(kW_WhiteListed, F_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kW_WhiteListed, R_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kW_WhiteListed, W_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kW_WhiteListed, R_OK | W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kW_WhiteListed, X_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kW_WhiteListed, R_OK | X_OK); - ASSERT_EQ(ret, -denied_errno); - - fd = open_broker.Open(kRW_WhiteListed, O_RDONLY); - ASSERT_EQ(fd, -ENOENT); - fd = open_broker.Open(kRW_WhiteListed, O_WRONLY); - ASSERT_EQ(fd, -ENOENT); - fd = open_broker.Open(kRW_WhiteListed, O_RDWR); - ASSERT_EQ(fd, -ENOENT); - ret = open_broker.Access(kRW_WhiteListed, F_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kRW_WhiteListed, R_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kRW_WhiteListed, W_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kRW_WhiteListed, R_OK | W_OK); - ASSERT_EQ(ret, -ENOENT); - ret = open_broker.Access(kRW_WhiteListed, X_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(kRW_WhiteListed, R_OK | X_OK); - ASSERT_EQ(ret, -denied_errno); - - fd = open_broker.Open(k_NotWhitelisted, O_RDONLY); - ASSERT_EQ(fd, -denied_errno); - fd = open_broker.Open(k_NotWhitelisted, O_WRONLY); - ASSERT_EQ(fd, -denied_errno); - fd = open_broker.Open(k_NotWhitelisted, O_RDWR); - ASSERT_EQ(fd, -denied_errno); - ret = open_broker.Access(k_NotWhitelisted, F_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(k_NotWhitelisted, R_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(k_NotWhitelisted, W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(k_NotWhitelisted, R_OK | W_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(k_NotWhitelisted, X_OK); - ASSERT_EQ(ret, -denied_errno); - ret = open_broker.Access(k_NotWhitelisted, R_OK | X_OK); - ASSERT_EQ(ret, -denied_errno); - - // We have some extra sanity check for clearly wrong values. - fd = open_broker.Open(kRW_WhiteListed, O_RDONLY | O_WRONLY | O_RDWR); - ASSERT_EQ(fd, -denied_errno); - - // It makes no sense to allow O_CREAT in a 2-parameters open. Ensure this - // is denied. - fd = open_broker.Open(kRW_WhiteListed, O_RDWR | O_CREAT); - ASSERT_EQ(fd, -denied_errno); -} - -// Run the same thing twice. The second time, we make sure that no security -// check is performed on the client. -TEST(BrokerProcess, OpenFilePermsWithClientCheck) { - TestOpenFilePerms(true /* fast_check_in_client */, EPERM); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenOpenFilePermsNoClientCheck) { - TestOpenFilePerms(false /* fast_check_in_client */, EPERM); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -// Run the same twice again, but with ENOENT instead of EPERM. -TEST(BrokerProcess, OpenFilePermsWithClientCheckNoEnt) { - TestOpenFilePerms(true /* fast_check_in_client */, ENOENT); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenOpenFilePermsNoClientCheckNoEnt) { - TestOpenFilePerms(false /* fast_check_in_client */, ENOENT); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -void TestBadPaths(bool fast_check_in_client) { - const char kFileCpuInfo[] = "/proc/cpuinfo"; - const char kNotAbsPath[] = "proc/cpuinfo"; - const char kDotDotStart[] = "/../proc/cpuinfo"; - const char kDotDotMiddle[] = "/proc/self/../cpuinfo"; - const char kDotDotEnd[] = "/proc/.."; - const char kTrailingSlash[] = "/proc/"; - - std::vector<BrokerFilePermission> permissions; - - permissions.push_back(BrokerFilePermission::ReadOnlyRecursive("/proc/")); - std::unique_ptr<BrokerProcess> open_broker( - new BrokerProcess(EPERM, permissions, fast_check_in_client)); - ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); - // Open cpuinfo via the broker. - int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY); - base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); - ASSERT_GE(cpuinfo_fd, 0); - - int fd = -1; - int can_access; - - can_access = open_broker->Access(kNotAbsPath, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kNotAbsPath, O_RDONLY); - ASSERT_EQ(fd, -EPERM); - - can_access = open_broker->Access(kDotDotStart, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kDotDotStart, O_RDONLY); - ASSERT_EQ(fd, -EPERM); - - can_access = open_broker->Access(kDotDotMiddle, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kDotDotMiddle, O_RDONLY); - ASSERT_EQ(fd, -EPERM); - - can_access = open_broker->Access(kDotDotEnd, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kDotDotEnd, O_RDONLY); - ASSERT_EQ(fd, -EPERM); - - can_access = open_broker->Access(kTrailingSlash, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kTrailingSlash, O_RDONLY); - ASSERT_EQ(fd, -EPERM); -} - -TEST(BrokerProcess, BadPathsClientCheck) { - TestBadPaths(true /* fast_check_in_client */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, BadPathsNoClientCheck) { - TestBadPaths(false /* fast_check_in_client */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -void TestOpenCpuinfo(bool fast_check_in_client, bool recursive) { - const char kFileCpuInfo[] = "/proc/cpuinfo"; - const char kDirProc[] = "/proc/"; - - std::vector<BrokerFilePermission> permissions; - if (recursive) - permissions.push_back(BrokerFilePermission::ReadOnlyRecursive(kDirProc)); - else - permissions.push_back(BrokerFilePermission::ReadOnly(kFileCpuInfo)); - - std::unique_ptr<BrokerProcess> open_broker( - new BrokerProcess(EPERM, permissions, fast_check_in_client)); - ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); - - int fd = -1; - fd = open_broker->Open(kFileCpuInfo, O_RDWR); - base::ScopedFD fd_closer(fd); - ASSERT_EQ(fd, -EPERM); - - // Check we can read /proc/cpuinfo. - int can_access = open_broker->Access(kFileCpuInfo, R_OK); - ASSERT_EQ(can_access, 0); - can_access = open_broker->Access(kFileCpuInfo, W_OK); - ASSERT_EQ(can_access, -EPERM); - // Check we can not write /proc/cpuinfo. - - // Open cpuinfo via the broker. - int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY); - base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); - ASSERT_GE(cpuinfo_fd, 0); - char buf[3]; - memset(buf, 0, sizeof(buf)); - int read_len1 = read(cpuinfo_fd, buf, sizeof(buf)); - ASSERT_GT(read_len1, 0); - - // Open cpuinfo directly. - int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY); - base::ScopedFD cpuinfo_fd2_closer(cpuinfo_fd2); - ASSERT_GE(cpuinfo_fd2, 0); - char buf2[3]; - memset(buf2, 1, sizeof(buf2)); - int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2)); - ASSERT_GT(read_len1, 0); - - // The following is not guaranteed true, but will be in practice. - ASSERT_EQ(read_len1, read_len2); - // Compare the cpuinfo as returned by the broker with the one we opened - // ourselves. - ASSERT_EQ(memcmp(buf, buf2, read_len1), 0); - - ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); - open_broker.reset(); - ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); -} - -// Run this test 4 times. With and without the check in client -// and using a recursive path. -TEST(BrokerProcess, OpenCpuinfoWithClientCheck) { - TestOpenCpuinfo(true /* fast_check_in_client */, false /* not recursive */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenCpuinfoNoClientCheck) { - TestOpenCpuinfo(false /* fast_check_in_client */, false /* not recursive */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenCpuinfoWithClientCheckRecursive) { - TestOpenCpuinfo(true /* fast_check_in_client */, true /* recursive */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenCpuinfoNoClientCheckRecursive) { - TestOpenCpuinfo(false /* fast_check_in_client */, true /* recursive */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenFileRW) { - ScopedTemporaryFile tempfile; - const char* tempfile_name = tempfile.full_file_name(); - - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadWrite(tempfile_name)); - - BrokerProcess open_broker(EPERM, permissions); - ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); - - // Check we can access that file with read or write. - int can_access = open_broker.Access(tempfile_name, R_OK | W_OK); - ASSERT_EQ(can_access, 0); - - int tempfile2 = -1; - tempfile2 = open_broker.Open(tempfile_name, O_RDWR); - ASSERT_GE(tempfile2, 0); - - // Write to the descriptor opened by the broker. - char test_text[] = "TESTTESTTEST"; - ssize_t len = write(tempfile2, test_text, sizeof(test_text)); - ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text))); - - // Read back from the original file descriptor what we wrote through - // the descriptor provided by the broker. - char buf[1024]; - len = read(tempfile.fd(), buf, sizeof(buf)); - - ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text))); - ASSERT_EQ(memcmp(test_text, buf, sizeof(test_text)), 0); - - ASSERT_EQ(close(tempfile2), 0); -} - -// SANDBOX_TEST because the process could die with a SIGPIPE -// and we want this to happen in a subprocess. -SANDBOX_TEST(BrokerProcess, BrokerDied) { - const char kCpuInfo[] = "/proc/cpuinfo"; - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly(kCpuInfo)); - - BrokerProcess open_broker(EPERM, permissions, true /* fast_check_in_client */, - true /* quiet_failures_for_tests */); - SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback))); - const pid_t broker_pid = open_broker.broker_pid(); - SANDBOX_ASSERT(kill(broker_pid, SIGKILL) == 0); - - // Now we check that the broker has been signaled, but do not reap it. - siginfo_t process_info; - SANDBOX_ASSERT(HANDLE_EINTR(waitid( - P_PID, broker_pid, &process_info, WEXITED | WNOWAIT)) == - 0); - SANDBOX_ASSERT(broker_pid == process_info.si_pid); - SANDBOX_ASSERT(CLD_KILLED == process_info.si_code); - SANDBOX_ASSERT(SIGKILL == process_info.si_status); - - // Check that doing Open with a dead broker won't SIGPIPE us. - SANDBOX_ASSERT(open_broker.Open(kCpuInfo, O_RDONLY) == -ENOMEM); - SANDBOX_ASSERT(open_broker.Access(kCpuInfo, O_RDONLY) == -ENOMEM); -} - -void TestOpenComplexFlags(bool fast_check_in_client) { - const char kCpuInfo[] = "/proc/cpuinfo"; - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly(kCpuInfo)); - - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); - ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); - // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK. - int fd = -1; - int ret = 0; - fd = open_broker.Open(kCpuInfo, O_RDONLY); - ASSERT_GE(fd, 0); - ret = fcntl(fd, F_GETFL); - ASSERT_NE(-1, ret); - // The descriptor shouldn't have the O_CLOEXEC attribute, nor O_NONBLOCK. - ASSERT_EQ(0, ret & (O_CLOEXEC | O_NONBLOCK)); - ASSERT_EQ(0, close(fd)); - - fd = open_broker.Open(kCpuInfo, O_RDONLY | O_CLOEXEC); - ASSERT_GE(fd, 0); - ret = fcntl(fd, F_GETFD); - ASSERT_NE(-1, ret); - // Important: use F_GETFD, not F_GETFL. The O_CLOEXEC flag in F_GETFL - // is actually not used by the kernel. - ASSERT_TRUE(FD_CLOEXEC & ret); - ASSERT_EQ(0, close(fd)); - - fd = open_broker.Open(kCpuInfo, O_RDONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - ret = fcntl(fd, F_GETFL); - ASSERT_NE(-1, ret); - ASSERT_TRUE(O_NONBLOCK & ret); - ASSERT_EQ(0, close(fd)); -} - -TEST(BrokerProcess, OpenComplexFlagsWithClientCheck) { - TestOpenComplexFlags(true /* fast_check_in_client */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -TEST(BrokerProcess, OpenComplexFlagsNoClientCheck) { - TestOpenComplexFlags(false /* fast_check_in_client */); - // Don't do anything here, so that ASSERT works in the subfunction as - // expected. -} - -#if defined(OS_LINUX) -// Flaky on Linux NG bots: https://crbug.com/595199. -#define MAYBE_RecvMsgDescriptorLeak DISABLED_RecvMsgDescriptorLeak -#else -#define MAYBE_RecvMsgDescriptorLeak RecvMsgDescriptorLeak -#endif - -// We need to allow noise because the broker will log when it receives our -// bogus IPCs. -SANDBOX_TEST_ALLOW_NOISE(BrokerProcess, MAYBE_RecvMsgDescriptorLeak) { - // Android creates a socket on first use of the LOG call. - // We need to ensure this socket is open before we - // begin the test. - LOG(INFO) << "Ensure Android LOG socket is allocated"; - - // Find the four lowest available file descriptors. - int available_fds[4]; - SANDBOX_ASSERT(0 == pipe(available_fds)); - SANDBOX_ASSERT(0 == pipe(available_fds + 2)); - - // Save one FD to send to the broker later, and close the others. - base::ScopedFD message_fd(available_fds[0]); - for (size_t i = 1; i < arraysize(available_fds); i++) { - SANDBOX_ASSERT(0 == IGNORE_EINTR(close(available_fds[i]))); - } - - // Lower our file descriptor limit to just allow three more file descriptors - // to be allocated. (N.B., RLIMIT_NOFILE doesn't limit the number of file - // descriptors a process can have: it only limits the highest value that can - // be assigned to newly-created descriptors allocated by the process.) - const rlim_t fd_limit = - 1 + - *std::max_element(available_fds, - available_fds + arraysize(available_fds)); - - // Valgrind doesn't allow changing the hard descriptor limit, so we only - // change the soft descriptor limit here. - struct rlimit rlim; - SANDBOX_ASSERT(0 == getrlimit(RLIMIT_NOFILE, &rlim)); - SANDBOX_ASSERT(fd_limit <= rlim.rlim_cur); - rlim.rlim_cur = fd_limit; - SANDBOX_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim)); - - static const char kCpuInfo[] = "/proc/cpuinfo"; - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly(kCpuInfo)); - - BrokerProcess open_broker(EPERM, permissions); - SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback))); - - const int ipc_fd = BrokerProcessTestHelper::GetIPCDescriptor(&open_broker); - SANDBOX_ASSERT(ipc_fd >= 0); - - static const char kBogus[] = "not a pickle"; - std::vector<int> fds; - fds.push_back(message_fd.get()); - - // The broker process should only have a couple spare file descriptors - // available, but for good measure we send it fd_limit bogus IPCs anyway. - for (rlim_t i = 0; i < fd_limit; ++i) { - SANDBOX_ASSERT( - base::UnixDomainSocket::SendMsg(ipc_fd, kBogus, sizeof(kBogus), fds)); - } - - const int fd = open_broker.Open(kCpuInfo, O_RDONLY); - SANDBOX_ASSERT(fd >= 0); - SANDBOX_ASSERT(0 == IGNORE_EINTR(close(fd))); -} - -bool CloseFD(int fd) { - PCHECK(0 == IGNORE_EINTR(close(fd))); - return true; -} - -// Return true if the other end of the |reader| pipe was closed, -// false if |timeout_in_seconds| was reached or another event -// or error occured. -bool WaitForClosedPipeWriter(int reader, int timeout_in_ms) { - struct pollfd poll_fd = {reader, POLLIN | POLLRDHUP, 0}; - const int num_events = HANDLE_EINTR(poll(&poll_fd, 1, timeout_in_ms)); - if (1 == num_events && poll_fd.revents | POLLHUP) - return true; - return false; -} - -// Closing the broker client's IPC channel should terminate the broker -// process. -TEST(BrokerProcess, BrokerDiesOnClosedChannel) { - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly("/proc/cpuinfo")); - - // Get the writing end of a pipe into the broker (child) process so - // that we can reliably detect when it dies. - int lifeline_fds[2]; - PCHECK(0 == pipe(lifeline_fds)); - - BrokerProcess open_broker(EPERM, permissions, true /* fast_check_in_client */, - false /* quiet_failures_for_tests */); - ASSERT_TRUE(open_broker.Init(base::Bind(&CloseFD, lifeline_fds[0]))); - // Make sure the writing end only exists in the broker process. - CloseFD(lifeline_fds[1]); - base::ScopedFD reader(lifeline_fds[0]); - - const pid_t broker_pid = open_broker.broker_pid(); - - // This should cause the broker process to exit. - BrokerProcessTestHelper::CloseChannel(&open_broker); - - const int kTimeoutInMilliseconds = 5000; - const bool broker_lifeline_closed = - WaitForClosedPipeWriter(reader.get(), kTimeoutInMilliseconds); - // If the broker exited, its lifeline fd should be closed. - ASSERT_TRUE(broker_lifeline_closed); - // Now check that the broker has exited, but do not reap it. - siginfo_t process_info; - ASSERT_EQ(0, HANDLE_EINTR(waitid(P_PID, broker_pid, &process_info, - WEXITED | WNOWAIT))); - EXPECT_EQ(broker_pid, process_info.si_pid); - EXPECT_EQ(CLD_EXITED, process_info.si_code); - EXPECT_EQ(1, process_info.si_status); -} - -TEST(BrokerProcess, CreateFile) { - std::string temp_str; - { - ScopedTemporaryFile tmp_file; - temp_str = tmp_file.full_file_name(); - } - const char* tempfile_name = temp_str.c_str(); - - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadWriteCreate(tempfile_name)); - - BrokerProcess open_broker(EPERM, permissions); - ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); - - int fd = -1; - - // Try without O_EXCL - fd = open_broker.Open(tempfile_name, O_RDWR | O_CREAT); - ASSERT_EQ(fd, -EPERM); - - const char kTestText[] = "TESTTESTTEST"; - // Create a file - fd = open_broker.Open(tempfile_name, O_RDWR | O_CREAT | O_EXCL); - ASSERT_GE(fd, 0); - { - base::ScopedFD scoped_fd(fd); - - // Confirm fail if file exists - int bad_fd = open_broker.Open(tempfile_name, O_RDWR | O_CREAT | O_EXCL); - ASSERT_EQ(bad_fd, -EEXIST); - - // Write to the descriptor opened by the broker. - - ssize_t len = HANDLE_EINTR(write(fd, kTestText, sizeof(kTestText))); - ASSERT_EQ(len, static_cast<ssize_t>(sizeof(kTestText))); - } - - int fd_check = open(tempfile_name, O_RDONLY); - ASSERT_GE(fd_check, 0); - { - base::ScopedFD scoped_fd(fd_check); - char buf[1024]; - ssize_t len = HANDLE_EINTR(read(fd_check, buf, sizeof(buf))); - - ASSERT_EQ(len, static_cast<ssize_t>(sizeof(kTestText))); - ASSERT_EQ(memcmp(kTestText, buf, sizeof(kTestText)), 0); - } -} - -} // namespace syscall_broker - -} // namespace sandbox diff --git a/sandbox/linux/system_headers/arm64_linux_syscalls.h b/sandbox/linux/system_headers/arm64_linux_syscalls.h deleted file mode 100644 index 59d0eab8ec..0000000000 --- a/sandbox/linux/system_headers/arm64_linux_syscalls.h +++ /dev/null @@ -1,1066 +0,0 @@ -// Copyright 2014 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_LINUX_SYSTEM_HEADERS_ARM64_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_SYSCALLS_H_ - -#include <asm-generic/unistd.h> - -#if !defined(__NR_io_setup) -#define __NR_io_setup 0 -#endif - -#if !defined(__NR_io_destroy) -#define __NR_io_destroy 1 -#endif - -#if !defined(__NR_io_submit) -#define __NR_io_submit 2 -#endif - -#if !defined(__NR_io_cancel) -#define __NR_io_cancel 3 -#endif - -#if !defined(__NR_io_getevents) -#define __NR_io_getevents 4 -#endif - -#if !defined(__NR_setxattr) -#define __NR_setxattr 5 -#endif - -#if !defined(__NR_lsetxattr) -#define __NR_lsetxattr 6 -#endif - -#if !defined(__NR_fsetxattr) -#define __NR_fsetxattr 7 -#endif - -#if !defined(__NR_getxattr) -#define __NR_getxattr 8 -#endif - -#if !defined(__NR_lgetxattr) -#define __NR_lgetxattr 9 -#endif - -#if !defined(__NR_fgetxattr) -#define __NR_fgetxattr 10 -#endif - -#if !defined(__NR_listxattr) -#define __NR_listxattr 11 -#endif - -#if !defined(__NR_llistxattr) -#define __NR_llistxattr 12 -#endif - -#if !defined(__NR_flistxattr) -#define __NR_flistxattr 13 -#endif - -#if !defined(__NR_removexattr) -#define __NR_removexattr 14 -#endif - -#if !defined(__NR_lremovexattr) -#define __NR_lremovexattr 15 -#endif - -#if !defined(__NR_fremovexattr) -#define __NR_fremovexattr 16 -#endif - -#if !defined(__NR_getcwd) -#define __NR_getcwd 17 -#endif - -#if !defined(__NR_lookup_dcookie) -#define __NR_lookup_dcookie 18 -#endif - -#if !defined(__NR_eventfd2) -#define __NR_eventfd2 19 -#endif - -#if !defined(__NR_epoll_create1) -#define __NR_epoll_create1 20 -#endif - -#if !defined(__NR_epoll_ctl) -#define __NR_epoll_ctl 21 -#endif - -#if !defined(__NR_epoll_pwait) -#define __NR_epoll_pwait 22 -#endif - -#if !defined(__NR_dup) -#define __NR_dup 23 -#endif - -#if !defined(__NR_dup3) -#define __NR_dup3 24 -#endif - -#if !defined(__NR_fcntl) -#define __NR_fcntl 25 -#endif - -#if !defined(__NR_inotify_init1) -#define __NR_inotify_init1 26 -#endif - -#if !defined(__NR_inotify_add_watch) -#define __NR_inotify_add_watch 27 -#endif - -#if !defined(__NR_inotify_rm_watch) -#define __NR_inotify_rm_watch 28 -#endif - -#if !defined(__NR_ioctl) -#define __NR_ioctl 29 -#endif - -#if !defined(__NR_ioprio_set) -#define __NR_ioprio_set 30 -#endif - -#if !defined(__NR_ioprio_get) -#define __NR_ioprio_get 31 -#endif - -#if !defined(__NR_flock) -#define __NR_flock 32 -#endif - -#if !defined(__NR_mknodat) -#define __NR_mknodat 33 -#endif - -#if !defined(__NR_mkdirat) -#define __NR_mkdirat 34 -#endif - -#if !defined(__NR_unlinkat) -#define __NR_unlinkat 35 -#endif - -#if !defined(__NR_symlinkat) -#define __NR_symlinkat 36 -#endif - -#if !defined(__NR_linkat) -#define __NR_linkat 37 -#endif - -#if !defined(__NR_renameat) -#define __NR_renameat 38 -#endif - -#if !defined(__NR_umount2) -#define __NR_umount2 39 -#endif - -#if !defined(__NR_mount) -#define __NR_mount 40 -#endif - -#if !defined(__NR_pivot_root) -#define __NR_pivot_root 41 -#endif - -#if !defined(__NR_nfsservctl) -#define __NR_nfsservctl 42 -#endif - -#if !defined(__NR_statfs) -#define __NR_statfs 43 -#endif - -#if !defined(__NR_fstatfs) -#define __NR_fstatfs 44 -#endif - -#if !defined(__NR_truncate) -#define __NR_truncate 45 -#endif - -#if !defined(__NR_ftruncate) -#define __NR_ftruncate 46 -#endif - -#if !defined(__NR_fallocate) -#define __NR_fallocate 47 -#endif - -#if !defined(__NR_faccessat) -#define __NR_faccessat 48 -#endif - -#if !defined(__NR_chdir) -#define __NR_chdir 49 -#endif - -#if !defined(__NR_fchdir) -#define __NR_fchdir 50 -#endif - -#if !defined(__NR_chroot) -#define __NR_chroot 51 -#endif - -#if !defined(__NR_fchmod) -#define __NR_fchmod 52 -#endif - -#if !defined(__NR_fchmodat) -#define __NR_fchmodat 53 -#endif - -#if !defined(__NR_fchownat) -#define __NR_fchownat 54 -#endif - -#if !defined(__NR_fchown) -#define __NR_fchown 55 -#endif - -#if !defined(__NR_openat) -#define __NR_openat 56 -#endif - -#if !defined(__NR_close) -#define __NR_close 57 -#endif - -#if !defined(__NR_vhangup) -#define __NR_vhangup 58 -#endif - -#if !defined(__NR_pipe2) -#define __NR_pipe2 59 -#endif - -#if !defined(__NR_quotactl) -#define __NR_quotactl 60 -#endif - -#if !defined(__NR_getdents64) -#define __NR_getdents64 61 -#endif - -#if !defined(__NR_lseek) -#define __NR_lseek 62 -#endif - -#if !defined(__NR_read) -#define __NR_read 63 -#endif - -#if !defined(__NR_write) -#define __NR_write 64 -#endif - -#if !defined(__NR_readv) -#define __NR_readv 65 -#endif - -#if !defined(__NR_writev) -#define __NR_writev 66 -#endif - -#if !defined(__NR_pread64) -#define __NR_pread64 67 -#endif - -#if !defined(__NR_pwrite64) -#define __NR_pwrite64 68 -#endif - -#if !defined(__NR_preadv) -#define __NR_preadv 69 -#endif - -#if !defined(__NR_pwritev) -#define __NR_pwritev 70 -#endif - -#if !defined(__NR_sendfile) -#define __NR_sendfile 71 -#endif - -#if !defined(__NR_pselect6) -#define __NR_pselect6 72 -#endif - -#if !defined(__NR_ppoll) -#define __NR_ppoll 73 -#endif - -#if !defined(__NR_signalfd4) -#define __NR_signalfd4 74 -#endif - -#if !defined(__NR_vmsplice) -#define __NR_vmsplice 75 -#endif - -#if !defined(__NR_splice) -#define __NR_splice 76 -#endif - -#if !defined(__NR_tee) -#define __NR_tee 77 -#endif - -#if !defined(__NR_readlinkat) -#define __NR_readlinkat 78 -#endif - -#if !defined(__NR_newfstatat) -#define __NR_newfstatat 79 -#endif - -#if !defined(__NR_fstat) -#define __NR_fstat 80 -#endif - -#if !defined(__NR_sync) -#define __NR_sync 81 -#endif - -#if !defined(__NR_fsync) -#define __NR_fsync 82 -#endif - -#if !defined(__NR_fdatasync) -#define __NR_fdatasync 83 -#endif - -#if !defined(__NR_sync_file_range) -#define __NR_sync_file_range 84 -#endif - -#if !defined(__NR_timerfd_create) -#define __NR_timerfd_create 85 -#endif - -#if !defined(__NR_timerfd_settime) -#define __NR_timerfd_settime 86 -#endif - -#if !defined(__NR_timerfd_gettime) -#define __NR_timerfd_gettime 87 -#endif - -#if !defined(__NR_utimensat) -#define __NR_utimensat 88 -#endif - -#if !defined(__NR_acct) -#define __NR_acct 89 -#endif - -#if !defined(__NR_capget) -#define __NR_capget 90 -#endif - -#if !defined(__NR_capset) -#define __NR_capset 91 -#endif - -#if !defined(__NR_personality) -#define __NR_personality 92 -#endif - -#if !defined(__NR_exit) -#define __NR_exit 93 -#endif - -#if !defined(__NR_exit_group) -#define __NR_exit_group 94 -#endif - -#if !defined(__NR_waitid) -#define __NR_waitid 95 -#endif - -#if !defined(__NR_set_tid_address) -#define __NR_set_tid_address 96 -#endif - -#if !defined(__NR_unshare) -#define __NR_unshare 97 -#endif - -#if !defined(__NR_futex) -#define __NR_futex 98 -#endif - -#if !defined(__NR_set_robust_list) -#define __NR_set_robust_list 99 -#endif - -#if !defined(__NR_get_robust_list) -#define __NR_get_robust_list 100 -#endif - -#if !defined(__NR_nanosleep) -#define __NR_nanosleep 101 -#endif - -#if !defined(__NR_getitimer) -#define __NR_getitimer 102 -#endif - -#if !defined(__NR_setitimer) -#define __NR_setitimer 103 -#endif - -#if !defined(__NR_kexec_load) -#define __NR_kexec_load 104 -#endif - -#if !defined(__NR_init_module) -#define __NR_init_module 105 -#endif - -#if !defined(__NR_delete_module) -#define __NR_delete_module 106 -#endif - -#if !defined(__NR_timer_create) -#define __NR_timer_create 107 -#endif - -#if !defined(__NR_timer_gettime) -#define __NR_timer_gettime 108 -#endif - -#if !defined(__NR_timer_getoverrun) -#define __NR_timer_getoverrun 109 -#endif - -#if !defined(__NR_timer_settime) -#define __NR_timer_settime 110 -#endif - -#if !defined(__NR_timer_delete) -#define __NR_timer_delete 111 -#endif - -#if !defined(__NR_clock_settime) -#define __NR_clock_settime 112 -#endif - -#if !defined(__NR_clock_gettime) -#define __NR_clock_gettime 113 -#endif - -#if !defined(__NR_clock_getres) -#define __NR_clock_getres 114 -#endif - -#if !defined(__NR_clock_nanosleep) -#define __NR_clock_nanosleep 115 -#endif - -#if !defined(__NR_syslog) -#define __NR_syslog 116 -#endif - -#if !defined(__NR_ptrace) -#define __NR_ptrace 117 -#endif - -#if !defined(__NR_sched_setparam) -#define __NR_sched_setparam 118 -#endif - -#if !defined(__NR_sched_setscheduler) -#define __NR_sched_setscheduler 119 -#endif - -#if !defined(__NR_sched_getscheduler) -#define __NR_sched_getscheduler 120 -#endif - -#if !defined(__NR_sched_getparam) -#define __NR_sched_getparam 121 -#endif - -#if !defined(__NR_sched_setaffinity) -#define __NR_sched_setaffinity 122 -#endif - -#if !defined(__NR_sched_getaffinity) -#define __NR_sched_getaffinity 123 -#endif - -#if !defined(__NR_sched_yield) -#define __NR_sched_yield 124 -#endif - -#if !defined(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_max 125 -#endif - -#if !defined(__NR_sched_get_priority_min) -#define __NR_sched_get_priority_min 126 -#endif - -#if !defined(__NR_sched_rr_get_interval) -#define __NR_sched_rr_get_interval 127 -#endif - -#if !defined(__NR_restart_syscall) -#define __NR_restart_syscall 128 -#endif - -#if !defined(__NR_kill) -#define __NR_kill 129 -#endif - -#if !defined(__NR_tkill) -#define __NR_tkill 130 -#endif - -#if !defined(__NR_tgkill) -#define __NR_tgkill 131 -#endif - -#if !defined(__NR_sigaltstack) -#define __NR_sigaltstack 132 -#endif - -#if !defined(__NR_rt_sigsuspend) -#define __NR_rt_sigsuspend 133 -#endif - -#if !defined(__NR_rt_sigaction) -#define __NR_rt_sigaction 134 -#endif - -#if !defined(__NR_rt_sigprocmask) -#define __NR_rt_sigprocmask 135 -#endif - -#if !defined(__NR_rt_sigpending) -#define __NR_rt_sigpending 136 -#endif - -#if !defined(__NR_rt_sigtimedwait) -#define __NR_rt_sigtimedwait 137 -#endif - -#if !defined(__NR_rt_sigqueueinfo) -#define __NR_rt_sigqueueinfo 138 -#endif - -#if !defined(__NR_rt_sigreturn) -#define __NR_rt_sigreturn 139 -#endif - -#if !defined(__NR_setpriority) -#define __NR_setpriority 140 -#endif - -#if !defined(__NR_getpriority) -#define __NR_getpriority 141 -#endif - -#if !defined(__NR_reboot) -#define __NR_reboot 142 -#endif - -#if !defined(__NR_setregid) -#define __NR_setregid 143 -#endif - -#if !defined(__NR_setgid) -#define __NR_setgid 144 -#endif - -#if !defined(__NR_setreuid) -#define __NR_setreuid 145 -#endif - -#if !defined(__NR_setuid) -#define __NR_setuid 146 -#endif - -#if !defined(__NR_setresuid) -#define __NR_setresuid 147 -#endif - -#if !defined(__NR_getresuid) -#define __NR_getresuid 148 -#endif - -#if !defined(__NR_setresgid) -#define __NR_setresgid 149 -#endif - -#if !defined(__NR_getresgid) -#define __NR_getresgid 150 -#endif - -#if !defined(__NR_setfsuid) -#define __NR_setfsuid 151 -#endif - -#if !defined(__NR_setfsgid) -#define __NR_setfsgid 152 -#endif - -#if !defined(__NR_times) -#define __NR_times 153 -#endif - -#if !defined(__NR_setpgid) -#define __NR_setpgid 154 -#endif - -#if !defined(__NR_getpgid) -#define __NR_getpgid 155 -#endif - -#if !defined(__NR_getsid) -#define __NR_getsid 156 -#endif - -#if !defined(__NR_setsid) -#define __NR_setsid 157 -#endif - -#if !defined(__NR_getgroups) -#define __NR_getgroups 158 -#endif - -#if !defined(__NR_setgroups) -#define __NR_setgroups 159 -#endif - -#if !defined(__NR_uname) -#define __NR_uname 160 -#endif - -#if !defined(__NR_sethostname) -#define __NR_sethostname 161 -#endif - -#if !defined(__NR_setdomainname) -#define __NR_setdomainname 162 -#endif - -#if !defined(__NR_getrlimit) -#define __NR_getrlimit 163 -#endif - -#if !defined(__NR_setrlimit) -#define __NR_setrlimit 164 -#endif - -#if !defined(__NR_getrusage) -#define __NR_getrusage 165 -#endif - -#if !defined(__NR_umask) -#define __NR_umask 166 -#endif - -#if !defined(__NR_prctl) -#define __NR_prctl 167 -#endif - -#if !defined(__NR_getcpu) -#define __NR_getcpu 168 -#endif - -#if !defined(__NR_gettimeofday) -#define __NR_gettimeofday 169 -#endif - -#if !defined(__NR_settimeofday) -#define __NR_settimeofday 170 -#endif - -#if !defined(__NR_adjtimex) -#define __NR_adjtimex 171 -#endif - -#if !defined(__NR_getpid) -#define __NR_getpid 172 -#endif - -#if !defined(__NR_getppid) -#define __NR_getppid 173 -#endif - -#if !defined(__NR_getuid) -#define __NR_getuid 174 -#endif - -#if !defined(__NR_geteuid) -#define __NR_geteuid 175 -#endif - -#if !defined(__NR_getgid) -#define __NR_getgid 176 -#endif - -#if !defined(__NR_getegid) -#define __NR_getegid 177 -#endif - -#if !defined(__NR_gettid) -#define __NR_gettid 178 -#endif - -#if !defined(__NR_sysinfo) -#define __NR_sysinfo 179 -#endif - -#if !defined(__NR_mq_open) -#define __NR_mq_open 180 -#endif - -#if !defined(__NR_mq_unlink) -#define __NR_mq_unlink 181 -#endif - -#if !defined(__NR_mq_timedsend) -#define __NR_mq_timedsend 182 -#endif - -#if !defined(__NR_mq_timedreceive) -#define __NR_mq_timedreceive 183 -#endif - -#if !defined(__NR_mq_notify) -#define __NR_mq_notify 184 -#endif - -#if !defined(__NR_mq_getsetattr) -#define __NR_mq_getsetattr 185 -#endif - -#if !defined(__NR_msgget) -#define __NR_msgget 186 -#endif - -#if !defined(__NR_msgctl) -#define __NR_msgctl 187 -#endif - -#if !defined(__NR_msgrcv) -#define __NR_msgrcv 188 -#endif - -#if !defined(__NR_msgsnd) -#define __NR_msgsnd 189 -#endif - -#if !defined(__NR_semget) -#define __NR_semget 190 -#endif - -#if !defined(__NR_semctl) -#define __NR_semctl 191 -#endif - -#if !defined(__NR_semtimedop) -#define __NR_semtimedop 192 -#endif - -#if !defined(__NR_semop) -#define __NR_semop 193 -#endif - -#if !defined(__NR_shmget) -#define __NR_shmget 194 -#endif - -#if !defined(__NR_shmctl) -#define __NR_shmctl 195 -#endif - -#if !defined(__NR_shmat) -#define __NR_shmat 196 -#endif - -#if !defined(__NR_shmdt) -#define __NR_shmdt 197 -#endif - -#if !defined(__NR_socket) -#define __NR_socket 198 -#endif - -#if !defined(__NR_socketpair) -#define __NR_socketpair 199 -#endif - -#if !defined(__NR_bind) -#define __NR_bind 200 -#endif - -#if !defined(__NR_listen) -#define __NR_listen 201 -#endif - -#if !defined(__NR_accept) -#define __NR_accept 202 -#endif - -#if !defined(__NR_connect) -#define __NR_connect 203 -#endif - -#if !defined(__NR_getsockname) -#define __NR_getsockname 204 -#endif - -#if !defined(__NR_getpeername) -#define __NR_getpeername 205 -#endif - -#if !defined(__NR_sendto) -#define __NR_sendto 206 -#endif - -#if !defined(__NR_recvfrom) -#define __NR_recvfrom 207 -#endif - -#if !defined(__NR_setsockopt) -#define __NR_setsockopt 208 -#endif - -#if !defined(__NR_getsockopt) -#define __NR_getsockopt 209 -#endif - -#if !defined(__NR_shutdown) -#define __NR_shutdown 210 -#endif - -#if !defined(__NR_sendmsg) -#define __NR_sendmsg 211 -#endif - -#if !defined(__NR_recvmsg) -#define __NR_recvmsg 212 -#endif - -#if !defined(__NR_readahead) -#define __NR_readahead 213 -#endif - -#if !defined(__NR_brk) -#define __NR_brk 214 -#endif - -#if !defined(__NR_munmap) -#define __NR_munmap 215 -#endif - -#if !defined(__NR_mremap) -#define __NR_mremap 216 -#endif - -#if !defined(__NR_add_key) -#define __NR_add_key 217 -#endif - -#if !defined(__NR_request_key) -#define __NR_request_key 218 -#endif - -#if !defined(__NR_keyctl) -#define __NR_keyctl 219 -#endif - -#if !defined(__NR_clone) -#define __NR_clone 220 -#endif - -#if !defined(__NR_execve) -#define __NR_execve 221 -#endif - -#if !defined(__NR_mmap) -#define __NR_mmap 222 -#endif - -#if !defined(__NR_fadvise64) -#define __NR_fadvise64 223 -#endif - -#if !defined(__NR_swapon) -#define __NR_swapon 224 -#endif - -#if !defined(__NR_swapoff) -#define __NR_swapoff 225 -#endif - -#if !defined(__NR_mprotect) -#define __NR_mprotect 226 -#endif - -#if !defined(__NR_msync) -#define __NR_msync 227 -#endif - -#if !defined(__NR_mlock) -#define __NR_mlock 228 -#endif - -#if !defined(__NR_munlock) -#define __NR_munlock 229 -#endif - -#if !defined(__NR_mlockall) -#define __NR_mlockall 230 -#endif - -#if !defined(__NR_munlockall) -#define __NR_munlockall 231 -#endif - -#if !defined(__NR_mincore) -#define __NR_mincore 232 -#endif - -#if !defined(__NR_madvise) -#define __NR_madvise 233 -#endif - -#if !defined(__NR_remap_file_pages) -#define __NR_remap_file_pages 234 -#endif - -#if !defined(__NR_mbind) -#define __NR_mbind 235 -#endif - -#if !defined(__NR_get_mempolicy) -#define __NR_get_mempolicy 236 -#endif - -#if !defined(__NR_set_mempolicy) -#define __NR_set_mempolicy 237 -#endif - -#if !defined(__NR_migrate_pages) -#define __NR_migrate_pages 238 -#endif - -#if !defined(__NR_move_pages) -#define __NR_move_pages 239 -#endif - -#if !defined(__NR_rt_tgsigqueueinfo) -#define __NR_rt_tgsigqueueinfo 240 -#endif - -#if !defined(__NR_perf_event_open) -#define __NR_perf_event_open 241 -#endif - -#if !defined(__NR_accept4) -#define __NR_accept4 242 -#endif - -#if !defined(__NR_recvmmsg) -#define __NR_recvmmsg 243 -#endif - -#if !defined(__NR_wait4) -#define __NR_wait4 260 -#endif - -#if !defined(__NR_prlimit64) -#define __NR_prlimit64 261 -#endif - -#if !defined(__NR_fanotify_init) -#define __NR_fanotify_init 262 -#endif - -#if !defined(__NR_fanotify_mark) -#define __NR_fanotify_mark 263 -#endif - -#if !defined(__NR_name_to_handle_at) -#define __NR_name_to_handle_at 264 -#endif - -#if !defined(__NR_open_by_handle_at) -#define __NR_open_by_handle_at 265 -#endif - -#if !defined(__NR_clock_adjtime) -#define __NR_clock_adjtime 266 -#endif - -#if !defined(__NR_syncfs) -#define __NR_syncfs 267 -#endif - -#if !defined(__NR_setns) -#define __NR_setns 268 -#endif - -#if !defined(__NR_sendmmsg) -#define __NR_sendmmsg 269 -#endif - -#if !defined(__NR_process_vm_readv) -#define __NR_process_vm_readv 270 -#endif - -#if !defined(__NR_process_vm_writev) -#define __NR_process_vm_writev 271 -#endif - -#if !defined(__NR_kcmp) -#define __NR_kcmp 272 -#endif - -#if !defined(__NR_finit_module) -#define __NR_finit_module 273 -#endif - -#if !defined(__NR_sched_setattr) -#define __NR_sched_setattr 274 -#endif - -#if !defined(__NR_sched_getattr) -#define __NR_sched_getattr 275 -#endif - -#if !defined(__NR_renameat2) -#define __NR_renameat2 276 -#endif - -#if !defined(__NR_seccomp) -#define __NR_seccomp 277 -#endif - -#if !defined(__NR_getrandom) -#define __NR_getrandom 278 -#endif - -#if !defined(__NR_memfd_create) -#define __NR_memfd_create 279 -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_SYSCALLS_H_ diff --git a/sandbox/linux/system_headers/arm64_linux_ucontext.h b/sandbox/linux/system_headers/arm64_linux_ucontext.h deleted file mode 100644 index 48303ba8dc..0000000000 --- a/sandbox/linux/system_headers/arm64_linux_ucontext.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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_LINUX_SYSTEM_HEADERS_ARM64_LINUX_UCONTEXT_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_UCONTEXT_H_ - -#if !defined(__BIONIC_HAVE_UCONTEXT_T) -#include <asm/sigcontext.h> -#include <signal.h> -#include <stdint.h> -// We also need greg_t for the sandbox, include it in this header as well. -typedef uint64_t greg_t; - -struct ucontext_t { - unsigned long uc_flags; - struct ucontext* uc_link; - stack_t uc_stack; - sigset_t uc_sigmask; - /* glibc uses a 1024-bit sigset_t */ - uint8_t unused[1024 / 8 - sizeof(sigset_t)]; - /* last for future expansion */ - struct sigcontext uc_mcontext; -}; - -#else -#include <sys/ucontext.h> -#endif // __BIONIC_HAVE_UCONTEXT_T - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_UCONTEXT_H_ diff --git a/sandbox/linux/system_headers/arm_linux_syscalls.h b/sandbox/linux/system_headers/arm_linux_syscalls.h deleted file mode 100644 index 1addd53843..0000000000 --- a/sandbox/linux/system_headers/arm_linux_syscalls.h +++ /dev/null @@ -1,1418 +0,0 @@ -// Copyright (c) 2012 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. - -// Generated from the Linux kernel's calls.S. -#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_SYSCALLS_H_ - -#if !defined(__arm__) || !defined(__ARM_EABI__) -#error "Including header on wrong architecture" -#endif - -#if !defined(__NR_SYSCALL_BASE) -// On ARM EABI arch, __NR_SYSCALL_BASE is 0. -#define __NR_SYSCALL_BASE 0 -#endif - -// This syscall list has holes, because ARM EABI makes some syscalls obsolete. - -#if !defined(__NR_restart_syscall) -#define __NR_restart_syscall (__NR_SYSCALL_BASE+0) -#endif - -#if !defined(__NR_exit) -#define __NR_exit (__NR_SYSCALL_BASE+1) -#endif - -#if !defined(__NR_fork) -#define __NR_fork (__NR_SYSCALL_BASE+2) -#endif - -#if !defined(__NR_read) -#define __NR_read (__NR_SYSCALL_BASE+3) -#endif - -#if !defined(__NR_write) -#define __NR_write (__NR_SYSCALL_BASE+4) -#endif - -#if !defined(__NR_open) -#define __NR_open (__NR_SYSCALL_BASE+5) -#endif - -#if !defined(__NR_close) -#define __NR_close (__NR_SYSCALL_BASE+6) -#endif - -#if !defined(__NR_creat) -#define __NR_creat (__NR_SYSCALL_BASE+8) -#endif - -#if !defined(__NR_link) -#define __NR_link (__NR_SYSCALL_BASE+9) -#endif - -#if !defined(__NR_unlink) -#define __NR_unlink (__NR_SYSCALL_BASE+10) -#endif - -#if !defined(__NR_execve) -#define __NR_execve (__NR_SYSCALL_BASE+11) -#endif - -#if !defined(__NR_chdir) -#define __NR_chdir (__NR_SYSCALL_BASE+12) -#endif - -#if !defined(__NR_mknod) -#define __NR_mknod (__NR_SYSCALL_BASE+14) -#endif - -#if !defined(__NR_chmod) -#define __NR_chmod (__NR_SYSCALL_BASE+15) -#endif - -#if !defined(__NR_lchown) -#define __NR_lchown (__NR_SYSCALL_BASE+16) -#endif - -#if !defined(__NR_lseek) -#define __NR_lseek (__NR_SYSCALL_BASE+19) -#endif - -#if !defined(__NR_getpid) -#define __NR_getpid (__NR_SYSCALL_BASE+20) -#endif - -#if !defined(__NR_mount) -#define __NR_mount (__NR_SYSCALL_BASE+21) -#endif - -#if !defined(__NR_setuid) -#define __NR_setuid (__NR_SYSCALL_BASE+23) -#endif - -#if !defined(__NR_getuid) -#define __NR_getuid (__NR_SYSCALL_BASE+24) -#endif - -#if !defined(__NR_ptrace) -#define __NR_ptrace (__NR_SYSCALL_BASE+26) -#endif - -#if !defined(__NR_pause) -#define __NR_pause (__NR_SYSCALL_BASE+29) -#endif - -#if !defined(__NR_access) -#define __NR_access (__NR_SYSCALL_BASE+33) -#endif - -#if !defined(__NR_nice) -#define __NR_nice (__NR_SYSCALL_BASE+34) -#endif - -#if !defined(__NR_sync) -#define __NR_sync (__NR_SYSCALL_BASE+36) -#endif - -#if !defined(__NR_kill) -#define __NR_kill (__NR_SYSCALL_BASE+37) -#endif - -#if !defined(__NR_rename) -#define __NR_rename (__NR_SYSCALL_BASE+38) -#endif - -#if !defined(__NR_mkdir) -#define __NR_mkdir (__NR_SYSCALL_BASE+39) -#endif - -#if !defined(__NR_rmdir) -#define __NR_rmdir (__NR_SYSCALL_BASE+40) -#endif - -#if !defined(__NR_dup) -#define __NR_dup (__NR_SYSCALL_BASE+41) -#endif - -#if !defined(__NR_pipe) -#define __NR_pipe (__NR_SYSCALL_BASE+42) -#endif - -#if !defined(__NR_times) -#define __NR_times (__NR_SYSCALL_BASE+43) -#endif - -#if !defined(__NR_brk) -#define __NR_brk (__NR_SYSCALL_BASE+45) -#endif - -#if !defined(__NR_setgid) -#define __NR_setgid (__NR_SYSCALL_BASE+46) -#endif - -#if !defined(__NR_getgid) -#define __NR_getgid (__NR_SYSCALL_BASE+47) -#endif - -#if !defined(__NR_geteuid) -#define __NR_geteuid (__NR_SYSCALL_BASE+49) -#endif - -#if !defined(__NR_getegid) -#define __NR_getegid (__NR_SYSCALL_BASE+50) -#endif - -#if !defined(__NR_acct) -#define __NR_acct (__NR_SYSCALL_BASE+51) -#endif - -#if !defined(__NR_umount2) -#define __NR_umount2 (__NR_SYSCALL_BASE+52) -#endif - -#if !defined(__NR_ioctl) -#define __NR_ioctl (__NR_SYSCALL_BASE+54) -#endif - -#if !defined(__NR_fcntl) -#define __NR_fcntl (__NR_SYSCALL_BASE+55) -#endif - -#if !defined(__NR_setpgid) -#define __NR_setpgid (__NR_SYSCALL_BASE+57) -#endif - -#if !defined(__NR_umask) -#define __NR_umask (__NR_SYSCALL_BASE+60) -#endif - -#if !defined(__NR_chroot) -#define __NR_chroot (__NR_SYSCALL_BASE+61) -#endif - -#if !defined(__NR_ustat) -#define __NR_ustat (__NR_SYSCALL_BASE+62) -#endif - -#if !defined(__NR_dup2) -#define __NR_dup2 (__NR_SYSCALL_BASE+63) -#endif - -#if !defined(__NR_getppid) -#define __NR_getppid (__NR_SYSCALL_BASE+64) -#endif - -#if !defined(__NR_getpgrp) -#define __NR_getpgrp (__NR_SYSCALL_BASE+65) -#endif - -#if !defined(__NR_setsid) -#define __NR_setsid (__NR_SYSCALL_BASE+66) -#endif - -#if !defined(__NR_sigaction) -#define __NR_sigaction (__NR_SYSCALL_BASE+67) -#endif - -#if !defined(__NR_setreuid) -#define __NR_setreuid (__NR_SYSCALL_BASE+70) -#endif - -#if !defined(__NR_setregid) -#define __NR_setregid (__NR_SYSCALL_BASE+71) -#endif - -#if !defined(__NR_sigsuspend) -#define __NR_sigsuspend (__NR_SYSCALL_BASE+72) -#endif - -#if !defined(__NR_sigpending) -#define __NR_sigpending (__NR_SYSCALL_BASE+73) -#endif - -#if !defined(__NR_sethostname) -#define __NR_sethostname (__NR_SYSCALL_BASE+74) -#endif - -#if !defined(__NR_setrlimit) -#define __NR_setrlimit (__NR_SYSCALL_BASE+75) -#endif - -#if !defined(__NR_getrusage) -#define __NR_getrusage (__NR_SYSCALL_BASE+77) -#endif - -#if !defined(__NR_gettimeofday) -#define __NR_gettimeofday (__NR_SYSCALL_BASE+78) -#endif - -#if !defined(__NR_settimeofday) -#define __NR_settimeofday (__NR_SYSCALL_BASE+79) -#endif - -#if !defined(__NR_getgroups) -#define __NR_getgroups (__NR_SYSCALL_BASE+80) -#endif - -#if !defined(__NR_setgroups) -#define __NR_setgroups (__NR_SYSCALL_BASE+81) -#endif - -#if !defined(__NR_symlink) -#define __NR_symlink (__NR_SYSCALL_BASE+83) -#endif - -#if !defined(__NR_readlink) -#define __NR_readlink (__NR_SYSCALL_BASE+85) -#endif - -#if !defined(__NR_uselib) -#define __NR_uselib (__NR_SYSCALL_BASE+86) -#endif - -#if !defined(__NR_swapon) -#define __NR_swapon (__NR_SYSCALL_BASE+87) -#endif - -#if !defined(__NR_reboot) -#define __NR_reboot (__NR_SYSCALL_BASE+88) -#endif - -#if !defined(__NR_munmap) -#define __NR_munmap (__NR_SYSCALL_BASE+91) -#endif - -#if !defined(__NR_truncate) -#define __NR_truncate (__NR_SYSCALL_BASE+92) -#endif - -#if !defined(__NR_ftruncate) -#define __NR_ftruncate (__NR_SYSCALL_BASE+93) -#endif - -#if !defined(__NR_fchmod) -#define __NR_fchmod (__NR_SYSCALL_BASE+94) -#endif - -#if !defined(__NR_fchown) -#define __NR_fchown (__NR_SYSCALL_BASE+95) -#endif - -#if !defined(__NR_getpriority) -#define __NR_getpriority (__NR_SYSCALL_BASE+96) -#endif - -#if !defined(__NR_setpriority) -#define __NR_setpriority (__NR_SYSCALL_BASE+97) -#endif - -#if !defined(__NR_statfs) -#define __NR_statfs (__NR_SYSCALL_BASE+99) -#endif - -#if !defined(__NR_fstatfs) -#define __NR_fstatfs (__NR_SYSCALL_BASE+100) -#endif - -#if !defined(__NR_syslog) -#define __NR_syslog (__NR_SYSCALL_BASE+103) -#endif - -#if !defined(__NR_setitimer) -#define __NR_setitimer (__NR_SYSCALL_BASE+104) -#endif - -#if !defined(__NR_getitimer) -#define __NR_getitimer (__NR_SYSCALL_BASE+105) -#endif - -#if !defined(__NR_stat) -#define __NR_stat (__NR_SYSCALL_BASE+106) -#endif - -#if !defined(__NR_lstat) -#define __NR_lstat (__NR_SYSCALL_BASE+107) -#endif - -#if !defined(__NR_fstat) -#define __NR_fstat (__NR_SYSCALL_BASE+108) -#endif - -#if !defined(__NR_vhangup) -#define __NR_vhangup (__NR_SYSCALL_BASE+111) -#endif - -#if !defined(__NR_wait4) -#define __NR_wait4 (__NR_SYSCALL_BASE+114) -#endif - -#if !defined(__NR_swapoff) -#define __NR_swapoff (__NR_SYSCALL_BASE+115) -#endif - -#if !defined(__NR_sysinfo) -#define __NR_sysinfo (__NR_SYSCALL_BASE+116) -#endif - -#if !defined(__NR_fsync) -#define __NR_fsync (__NR_SYSCALL_BASE+118) -#endif - -#if !defined(__NR_sigreturn) -#define __NR_sigreturn (__NR_SYSCALL_BASE+119) -#endif - -#if !defined(__NR_clone) -#define __NR_clone (__NR_SYSCALL_BASE+120) -#endif - -#if !defined(__NR_setdomainname) -#define __NR_setdomainname (__NR_SYSCALL_BASE+121) -#endif - -#if !defined(__NR_uname) -#define __NR_uname (__NR_SYSCALL_BASE+122) -#endif - -#if !defined(__NR_adjtimex) -#define __NR_adjtimex (__NR_SYSCALL_BASE+124) -#endif - -#if !defined(__NR_mprotect) -#define __NR_mprotect (__NR_SYSCALL_BASE+125) -#endif - -#if !defined(__NR_sigprocmask) -#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) -#endif - -#if !defined(__NR_init_module) -#define __NR_init_module (__NR_SYSCALL_BASE+128) -#endif - -#if !defined(__NR_delete_module) -#define __NR_delete_module (__NR_SYSCALL_BASE+129) -#endif - -#if !defined(__NR_quotactl) -#define __NR_quotactl (__NR_SYSCALL_BASE+131) -#endif - -#if !defined(__NR_getpgid) -#define __NR_getpgid (__NR_SYSCALL_BASE+132) -#endif - -#if !defined(__NR_fchdir) -#define __NR_fchdir (__NR_SYSCALL_BASE+133) -#endif - -#if !defined(__NR_bdflush) -#define __NR_bdflush (__NR_SYSCALL_BASE+134) -#endif - -#if !defined(__NR_sysfs) -#define __NR_sysfs (__NR_SYSCALL_BASE+135) -#endif - -#if !defined(__NR_personality) -#define __NR_personality (__NR_SYSCALL_BASE+136) -#endif - -#if !defined(__NR_setfsuid) -#define __NR_setfsuid (__NR_SYSCALL_BASE+138) -#endif - -#if !defined(__NR_setfsgid) -#define __NR_setfsgid (__NR_SYSCALL_BASE+139) -#endif - -#if !defined(__NR__llseek) -#define __NR__llseek (__NR_SYSCALL_BASE+140) -#endif - -#if !defined(__NR_getdents) -#define __NR_getdents (__NR_SYSCALL_BASE+141) -#endif - -#if !defined(__NR__newselect) -#define __NR__newselect (__NR_SYSCALL_BASE+142) -#endif - -#if !defined(__NR_flock) -#define __NR_flock (__NR_SYSCALL_BASE+143) -#endif - -#if !defined(__NR_msync) -#define __NR_msync (__NR_SYSCALL_BASE+144) -#endif - -#if !defined(__NR_readv) -#define __NR_readv (__NR_SYSCALL_BASE+145) -#endif - -#if !defined(__NR_writev) -#define __NR_writev (__NR_SYSCALL_BASE+146) -#endif - -#if !defined(__NR_getsid) -#define __NR_getsid (__NR_SYSCALL_BASE+147) -#endif - -#if !defined(__NR_fdatasync) -#define __NR_fdatasync (__NR_SYSCALL_BASE+148) -#endif - -#if !defined(__NR__sysctl) -#define __NR__sysctl (__NR_SYSCALL_BASE+149) -#endif - -#if !defined(__NR_mlock) -#define __NR_mlock (__NR_SYSCALL_BASE+150) -#endif - -#if !defined(__NR_munlock) -#define __NR_munlock (__NR_SYSCALL_BASE+151) -#endif - -#if !defined(__NR_mlockall) -#define __NR_mlockall (__NR_SYSCALL_BASE+152) -#endif - -#if !defined(__NR_munlockall) -#define __NR_munlockall (__NR_SYSCALL_BASE+153) -#endif - -#if !defined(__NR_sched_setparam) -#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) -#endif - -#if !defined(__NR_sched_getparam) -#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) -#endif - -#if !defined(__NR_sched_setscheduler) -#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) -#endif - -#if !defined(__NR_sched_getscheduler) -#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) -#endif - -#if !defined(__NR_sched_yield) -#define __NR_sched_yield (__NR_SYSCALL_BASE+158) -#endif - -#if !defined(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) -#endif - -#if !defined(__NR_sched_get_priority_min) -#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) -#endif - -#if !defined(__NR_sched_rr_get_interval) -#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) -#endif - -#if !defined(__NR_nanosleep) -#define __NR_nanosleep (__NR_SYSCALL_BASE+162) -#endif - -#if !defined(__NR_mremap) -#define __NR_mremap (__NR_SYSCALL_BASE+163) -#endif - -#if !defined(__NR_setresuid) -#define __NR_setresuid (__NR_SYSCALL_BASE+164) -#endif - -#if !defined(__NR_getresuid) -#define __NR_getresuid (__NR_SYSCALL_BASE+165) -#endif - -#if !defined(__NR_poll) -#define __NR_poll (__NR_SYSCALL_BASE+168) -#endif - -#if !defined(__NR_nfsservctl) -#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) -#endif - -#if !defined(__NR_setresgid) -#define __NR_setresgid (__NR_SYSCALL_BASE+170) -#endif - -#if !defined(__NR_getresgid) -#define __NR_getresgid (__NR_SYSCALL_BASE+171) -#endif - -#if !defined(__NR_prctl) -#define __NR_prctl (__NR_SYSCALL_BASE+172) -#endif - -#if !defined(__NR_rt_sigreturn) -#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) -#endif - -#if !defined(__NR_rt_sigaction) -#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) -#endif - -#if !defined(__NR_rt_sigprocmask) -#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) -#endif - -#if !defined(__NR_rt_sigpending) -#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) -#endif - -#if !defined(__NR_rt_sigtimedwait) -#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) -#endif - -#if !defined(__NR_rt_sigqueueinfo) -#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) -#endif - -#if !defined(__NR_rt_sigsuspend) -#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) -#endif - -#if !defined(__NR_pread64) -#define __NR_pread64 (__NR_SYSCALL_BASE+180) -#endif - -#if !defined(__NR_pwrite64) -#define __NR_pwrite64 (__NR_SYSCALL_BASE+181) -#endif - -#if !defined(__NR_chown) -#define __NR_chown (__NR_SYSCALL_BASE+182) -#endif - -#if !defined(__NR_getcwd) -#define __NR_getcwd (__NR_SYSCALL_BASE+183) -#endif - -#if !defined(__NR_capget) -#define __NR_capget (__NR_SYSCALL_BASE+184) -#endif - -#if !defined(__NR_capset) -#define __NR_capset (__NR_SYSCALL_BASE+185) -#endif - -#if !defined(__NR_sigaltstack) -#define __NR_sigaltstack (__NR_SYSCALL_BASE+186) -#endif - -#if !defined(__NR_sendfile) -#define __NR_sendfile (__NR_SYSCALL_BASE+187) -#endif - -#if !defined(__NR_vfork) -#define __NR_vfork (__NR_SYSCALL_BASE+190) -#endif - -#if !defined(__NR_ugetrlimit) -#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) -#endif - -#if !defined(__NR_mmap2) -#define __NR_mmap2 (__NR_SYSCALL_BASE+192) -#endif - -#if !defined(__NR_truncate64) -#define __NR_truncate64 (__NR_SYSCALL_BASE+193) -#endif - -#if !defined(__NR_ftruncate64) -#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194) -#endif - -#if !defined(__NR_stat64) -#define __NR_stat64 (__NR_SYSCALL_BASE+195) -#endif - -#if !defined(__NR_lstat64) -#define __NR_lstat64 (__NR_SYSCALL_BASE+196) -#endif - -#if !defined(__NR_fstat64) -#define __NR_fstat64 (__NR_SYSCALL_BASE+197) -#endif - -#if !defined(__NR_lchown32) -#define __NR_lchown32 (__NR_SYSCALL_BASE+198) -#endif - -#if !defined(__NR_getuid32) -#define __NR_getuid32 (__NR_SYSCALL_BASE+199) -#endif - -#if !defined(__NR_getgid32) -#define __NR_getgid32 (__NR_SYSCALL_BASE+200) -#endif - -#if !defined(__NR_geteuid32) -#define __NR_geteuid32 (__NR_SYSCALL_BASE+201) -#endif - -#if !defined(__NR_getegid32) -#define __NR_getegid32 (__NR_SYSCALL_BASE+202) -#endif - -#if !defined(__NR_setreuid32) -#define __NR_setreuid32 (__NR_SYSCALL_BASE+203) -#endif - -#if !defined(__NR_setregid32) -#define __NR_setregid32 (__NR_SYSCALL_BASE+204) -#endif - -#if !defined(__NR_getgroups32) -#define __NR_getgroups32 (__NR_SYSCALL_BASE+205) -#endif - -#if !defined(__NR_setgroups32) -#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) -#endif - -#if !defined(__NR_fchown32) -#define __NR_fchown32 (__NR_SYSCALL_BASE+207) -#endif - -#if !defined(__NR_setresuid32) -#define __NR_setresuid32 (__NR_SYSCALL_BASE+208) -#endif - -#if !defined(__NR_getresuid32) -#define __NR_getresuid32 (__NR_SYSCALL_BASE+209) -#endif - -#if !defined(__NR_setresgid32) -#define __NR_setresgid32 (__NR_SYSCALL_BASE+210) -#endif - -#if !defined(__NR_getresgid32) -#define __NR_getresgid32 (__NR_SYSCALL_BASE+211) -#endif - -#if !defined(__NR_chown32) -#define __NR_chown32 (__NR_SYSCALL_BASE+212) -#endif - -#if !defined(__NR_setuid32) -#define __NR_setuid32 (__NR_SYSCALL_BASE+213) -#endif - -#if !defined(__NR_setgid32) -#define __NR_setgid32 (__NR_SYSCALL_BASE+214) -#endif - -#if !defined(__NR_setfsuid32) -#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215) -#endif - -#if !defined(__NR_setfsgid32) -#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216) -#endif - -#if !defined(__NR_getdents64) -#define __NR_getdents64 (__NR_SYSCALL_BASE+217) -#endif - -#if !defined(__NR_pivot_root) -#define __NR_pivot_root (__NR_SYSCALL_BASE+218) -#endif - -#if !defined(__NR_mincore) -#define __NR_mincore (__NR_SYSCALL_BASE+219) -#endif - -#if !defined(__NR_madvise) -#define __NR_madvise (__NR_SYSCALL_BASE+220) -#endif - -#if !defined(__NR_fcntl64) -#define __NR_fcntl64 (__NR_SYSCALL_BASE+221) -#endif - -#if !defined(__NR_gettid) -#define __NR_gettid (__NR_SYSCALL_BASE+224) -#endif - -#if !defined(__NR_readahead) -#define __NR_readahead (__NR_SYSCALL_BASE+225) -#endif - -#if !defined(__NR_setxattr) -#define __NR_setxattr (__NR_SYSCALL_BASE+226) -#endif - -#if !defined(__NR_lsetxattr) -#define __NR_lsetxattr (__NR_SYSCALL_BASE+227) -#endif - -#if !defined(__NR_fsetxattr) -#define __NR_fsetxattr (__NR_SYSCALL_BASE+228) -#endif - -#if !defined(__NR_getxattr) -#define __NR_getxattr (__NR_SYSCALL_BASE+229) -#endif - -#if !defined(__NR_lgetxattr) -#define __NR_lgetxattr (__NR_SYSCALL_BASE+230) -#endif - -#if !defined(__NR_fgetxattr) -#define __NR_fgetxattr (__NR_SYSCALL_BASE+231) -#endif - -#if !defined(__NR_listxattr) -#define __NR_listxattr (__NR_SYSCALL_BASE+232) -#endif - -#if !defined(__NR_llistxattr) -#define __NR_llistxattr (__NR_SYSCALL_BASE+233) -#endif - -#if !defined(__NR_flistxattr) -#define __NR_flistxattr (__NR_SYSCALL_BASE+234) -#endif - -#if !defined(__NR_removexattr) -#define __NR_removexattr (__NR_SYSCALL_BASE+235) -#endif - -#if !defined(__NR_lremovexattr) -#define __NR_lremovexattr (__NR_SYSCALL_BASE+236) -#endif - -#if !defined(__NR_fremovexattr) -#define __NR_fremovexattr (__NR_SYSCALL_BASE+237) -#endif - -#if !defined(__NR_tkill) -#define __NR_tkill (__NR_SYSCALL_BASE+238) -#endif - -#if !defined(__NR_sendfile64) -#define __NR_sendfile64 (__NR_SYSCALL_BASE+239) -#endif - -#if !defined(__NR_futex) -#define __NR_futex (__NR_SYSCALL_BASE+240) -#endif - -#if !defined(__NR_sched_setaffinity) -#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241) -#endif - -#if !defined(__NR_sched_getaffinity) -#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242) -#endif - -#if !defined(__NR_io_setup) -#define __NR_io_setup (__NR_SYSCALL_BASE+243) -#endif - -#if !defined(__NR_io_destroy) -#define __NR_io_destroy (__NR_SYSCALL_BASE+244) -#endif - -#if !defined(__NR_io_getevents) -#define __NR_io_getevents (__NR_SYSCALL_BASE+245) -#endif - -#if !defined(__NR_io_submit) -#define __NR_io_submit (__NR_SYSCALL_BASE+246) -#endif - -#if !defined(__NR_io_cancel) -#define __NR_io_cancel (__NR_SYSCALL_BASE+247) -#endif - -#if !defined(__NR_exit_group) -#define __NR_exit_group (__NR_SYSCALL_BASE+248) -#endif - -#if !defined(__NR_lookup_dcookie) -#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) -#endif - -#if !defined(__NR_epoll_create) -#define __NR_epoll_create (__NR_SYSCALL_BASE+250) -#endif - -#if !defined(__NR_epoll_ctl) -#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251) -#endif - -#if !defined(__NR_epoll_wait) -#define __NR_epoll_wait (__NR_SYSCALL_BASE+252) -#endif - -#if !defined(__NR_remap_file_pages) -#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253) -#endif - -#if !defined(__NR_set_tid_address) -#define __NR_set_tid_address (__NR_SYSCALL_BASE+256) -#endif - -#if !defined(__NR_timer_create) -#define __NR_timer_create (__NR_SYSCALL_BASE+257) -#endif - -#if !defined(__NR_timer_settime) -#define __NR_timer_settime (__NR_SYSCALL_BASE+258) -#endif - -#if !defined(__NR_timer_gettime) -#define __NR_timer_gettime (__NR_SYSCALL_BASE+259) -#endif - -#if !defined(__NR_timer_getoverrun) -#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260) -#endif - -#if !defined(__NR_timer_delete) -#define __NR_timer_delete (__NR_SYSCALL_BASE+261) -#endif - -#if !defined(__NR_clock_settime) -#define __NR_clock_settime (__NR_SYSCALL_BASE+262) -#endif - -#if !defined(__NR_clock_gettime) -#define __NR_clock_gettime (__NR_SYSCALL_BASE+263) -#endif - -#if !defined(__NR_clock_getres) -#define __NR_clock_getres (__NR_SYSCALL_BASE+264) -#endif - -#if !defined(__NR_clock_nanosleep) -#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265) -#endif - -#if !defined(__NR_statfs64) -#define __NR_statfs64 (__NR_SYSCALL_BASE+266) -#endif - -#if !defined(__NR_fstatfs64) -#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) -#endif - -#if !defined(__NR_tgkill) -#define __NR_tgkill (__NR_SYSCALL_BASE+268) -#endif - -#if !defined(__NR_utimes) -#define __NR_utimes (__NR_SYSCALL_BASE+269) -#endif - -#if !defined(__NR_arm_fadvise64_64) -#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270) -#endif - -#if !defined(__NR_pciconfig_iobase) -#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) -#endif - -#if !defined(__NR_pciconfig_read) -#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) -#endif - -#if !defined(__NR_pciconfig_write) -#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) -#endif - -#if !defined(__NR_mq_open) -#define __NR_mq_open (__NR_SYSCALL_BASE+274) -#endif - -#if !defined(__NR_mq_unlink) -#define __NR_mq_unlink (__NR_SYSCALL_BASE+275) -#endif - -#if !defined(__NR_mq_timedsend) -#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276) -#endif - -#if !defined(__NR_mq_timedreceive) -#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277) -#endif - -#if !defined(__NR_mq_notify) -#define __NR_mq_notify (__NR_SYSCALL_BASE+278) -#endif - -#if !defined(__NR_mq_getsetattr) -#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) -#endif - -#if !defined(__NR_waitid) -#define __NR_waitid (__NR_SYSCALL_BASE+280) -#endif - -#if !defined(__NR_socket) -#define __NR_socket (__NR_SYSCALL_BASE+281) -#endif - -#if !defined(__NR_bind) -#define __NR_bind (__NR_SYSCALL_BASE+282) -#endif - -#if !defined(__NR_connect) -#define __NR_connect (__NR_SYSCALL_BASE+283) -#endif - -#if !defined(__NR_listen) -#define __NR_listen (__NR_SYSCALL_BASE+284) -#endif - -#if !defined(__NR_accept) -#define __NR_accept (__NR_SYSCALL_BASE+285) -#endif - -#if !defined(__NR_getsockname) -#define __NR_getsockname (__NR_SYSCALL_BASE+286) -#endif - -#if !defined(__NR_getpeername) -#define __NR_getpeername (__NR_SYSCALL_BASE+287) -#endif - -#if !defined(__NR_socketpair) -#define __NR_socketpair (__NR_SYSCALL_BASE+288) -#endif - -#if !defined(__NR_send) -#define __NR_send (__NR_SYSCALL_BASE+289) -#endif - -#if !defined(__NR_sendto) -#define __NR_sendto (__NR_SYSCALL_BASE+290) -#endif - -#if !defined(__NR_recv) -#define __NR_recv (__NR_SYSCALL_BASE+291) -#endif - -#if !defined(__NR_recvfrom) -#define __NR_recvfrom (__NR_SYSCALL_BASE+292) -#endif - -#if !defined(__NR_shutdown) -#define __NR_shutdown (__NR_SYSCALL_BASE+293) -#endif - -#if !defined(__NR_setsockopt) -#define __NR_setsockopt (__NR_SYSCALL_BASE+294) -#endif - -#if !defined(__NR_getsockopt) -#define __NR_getsockopt (__NR_SYSCALL_BASE+295) -#endif - -#if !defined(__NR_sendmsg) -#define __NR_sendmsg (__NR_SYSCALL_BASE+296) -#endif - -#if !defined(__NR_recvmsg) -#define __NR_recvmsg (__NR_SYSCALL_BASE+297) -#endif - -#if !defined(__NR_semop) -#define __NR_semop (__NR_SYSCALL_BASE+298) -#endif - -#if !defined(__NR_semget) -#define __NR_semget (__NR_SYSCALL_BASE+299) -#endif - -#if !defined(__NR_semctl) -#define __NR_semctl (__NR_SYSCALL_BASE+300) -#endif - -#if !defined(__NR_msgsnd) -#define __NR_msgsnd (__NR_SYSCALL_BASE+301) -#endif - -#if !defined(__NR_msgrcv) -#define __NR_msgrcv (__NR_SYSCALL_BASE+302) -#endif - -#if !defined(__NR_msgget) -#define __NR_msgget (__NR_SYSCALL_BASE+303) -#endif - -#if !defined(__NR_msgctl) -#define __NR_msgctl (__NR_SYSCALL_BASE+304) -#endif - -#if !defined(__NR_shmat) -#define __NR_shmat (__NR_SYSCALL_BASE+305) -#endif - -#if !defined(__NR_shmdt) -#define __NR_shmdt (__NR_SYSCALL_BASE+306) -#endif - -#if !defined(__NR_shmget) -#define __NR_shmget (__NR_SYSCALL_BASE+307) -#endif - -#if !defined(__NR_shmctl) -#define __NR_shmctl (__NR_SYSCALL_BASE+308) -#endif - -#if !defined(__NR_add_key) -#define __NR_add_key (__NR_SYSCALL_BASE+309) -#endif - -#if !defined(__NR_request_key) -#define __NR_request_key (__NR_SYSCALL_BASE+310) -#endif - -#if !defined(__NR_keyctl) -#define __NR_keyctl (__NR_SYSCALL_BASE+311) -#endif - -#if !defined(__NR_semtimedop) -#define __NR_semtimedop (__NR_SYSCALL_BASE+312) -#endif - -#if !defined(__NR_vserver) -#define __NR_vserver (__NR_SYSCALL_BASE+313) -#endif - -#if !defined(__NR_ioprio_set) -#define __NR_ioprio_set (__NR_SYSCALL_BASE+314) -#endif - -#if !defined(__NR_ioprio_get) -#define __NR_ioprio_get (__NR_SYSCALL_BASE+315) -#endif - -#if !defined(__NR_inotify_init) -#define __NR_inotify_init (__NR_SYSCALL_BASE+316) -#endif - -#if !defined(__NR_inotify_add_watch) -#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317) -#endif - -#if !defined(__NR_inotify_rm_watch) -#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318) -#endif - -#if !defined(__NR_mbind) -#define __NR_mbind (__NR_SYSCALL_BASE+319) -#endif - -#if !defined(__NR_get_mempolicy) -#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320) -#endif - -#if !defined(__NR_set_mempolicy) -#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321) -#endif - -#if !defined(__NR_openat) -#define __NR_openat (__NR_SYSCALL_BASE+322) -#endif - -#if !defined(__NR_mkdirat) -#define __NR_mkdirat (__NR_SYSCALL_BASE+323) -#endif - -#if !defined(__NR_mknodat) -#define __NR_mknodat (__NR_SYSCALL_BASE+324) -#endif - -#if !defined(__NR_fchownat) -#define __NR_fchownat (__NR_SYSCALL_BASE+325) -#endif - -#if !defined(__NR_futimesat) -#define __NR_futimesat (__NR_SYSCALL_BASE+326) -#endif - -#if !defined(__NR_fstatat64) -#define __NR_fstatat64 (__NR_SYSCALL_BASE+327) -#endif - -#if !defined(__NR_unlinkat) -#define __NR_unlinkat (__NR_SYSCALL_BASE+328) -#endif - -#if !defined(__NR_renameat) -#define __NR_renameat (__NR_SYSCALL_BASE+329) -#endif - -#if !defined(__NR_linkat) -#define __NR_linkat (__NR_SYSCALL_BASE+330) -#endif - -#if !defined(__NR_symlinkat) -#define __NR_symlinkat (__NR_SYSCALL_BASE+331) -#endif - -#if !defined(__NR_readlinkat) -#define __NR_readlinkat (__NR_SYSCALL_BASE+332) -#endif - -#if !defined(__NR_fchmodat) -#define __NR_fchmodat (__NR_SYSCALL_BASE+333) -#endif - -#if !defined(__NR_faccessat) -#define __NR_faccessat (__NR_SYSCALL_BASE+334) -#endif - -#if !defined(__NR_pselect6) -#define __NR_pselect6 (__NR_SYSCALL_BASE+335) -#endif - -#if !defined(__NR_ppoll) -#define __NR_ppoll (__NR_SYSCALL_BASE+336) -#endif - -#if !defined(__NR_unshare) -#define __NR_unshare (__NR_SYSCALL_BASE+337) -#endif - -#if !defined(__NR_set_robust_list) -#define __NR_set_robust_list (__NR_SYSCALL_BASE+338) -#endif - -#if !defined(__NR_get_robust_list) -#define __NR_get_robust_list (__NR_SYSCALL_BASE+339) -#endif - -#if !defined(__NR_splice) -#define __NR_splice (__NR_SYSCALL_BASE+340) -#endif - -#if !defined(__NR_arm_sync_file_range) -#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341) -#endif - -#if !defined(__NR_sync_file_range2) -#define __NR_sync_file_range2 (__NR_SYSCALL_BASE+341) -#endif - -#if !defined(__NR_tee) -#define __NR_tee (__NR_SYSCALL_BASE+342) -#endif - -#if !defined(__NR_vmsplice) -#define __NR_vmsplice (__NR_SYSCALL_BASE+343) -#endif - -#if !defined(__NR_move_pages) -#define __NR_move_pages (__NR_SYSCALL_BASE+344) -#endif - -#if !defined(__NR_getcpu) -#define __NR_getcpu (__NR_SYSCALL_BASE+345) -#endif - -#if !defined(__NR_epoll_pwait) -#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) -#endif - -#if !defined(__NR_kexec_load) -#define __NR_kexec_load (__NR_SYSCALL_BASE+347) -#endif - -#if !defined(__NR_utimensat) -#define __NR_utimensat (__NR_SYSCALL_BASE+348) -#endif - -#if !defined(__NR_signalfd) -#define __NR_signalfd (__NR_SYSCALL_BASE+349) -#endif - -#if !defined(__NR_timerfd_create) -#define __NR_timerfd_create (__NR_SYSCALL_BASE+350) -#endif - -#if !defined(__NR_eventfd) -#define __NR_eventfd (__NR_SYSCALL_BASE+351) -#endif - -#if !defined(__NR_fallocate) -#define __NR_fallocate (__NR_SYSCALL_BASE+352) -#endif - -#if !defined(__NR_timerfd_settime) -#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353) -#endif - -#if !defined(__NR_timerfd_gettime) -#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354) -#endif - -#if !defined(__NR_signalfd4) -#define __NR_signalfd4 (__NR_SYSCALL_BASE+355) -#endif - -#if !defined(__NR_eventfd2) -#define __NR_eventfd2 (__NR_SYSCALL_BASE+356) -#endif - -#if !defined(__NR_epoll_create1) -#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357) -#endif - -#if !defined(__NR_dup3) -#define __NR_dup3 (__NR_SYSCALL_BASE+358) -#endif - -#if !defined(__NR_pipe2) -#define __NR_pipe2 (__NR_SYSCALL_BASE+359) -#endif - -#if !defined(__NR_inotify_init1) -#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360) -#endif - -#if !defined(__NR_preadv) -#define __NR_preadv (__NR_SYSCALL_BASE+361) -#endif - -#if !defined(__NR_pwritev) -#define __NR_pwritev (__NR_SYSCALL_BASE+362) -#endif - -#if !defined(__NR_rt_tgsigqueueinfo) -#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363) -#endif - -#if !defined(__NR_perf_event_open) -#define __NR_perf_event_open (__NR_SYSCALL_BASE+364) -#endif - -#if !defined(__NR_recvmmsg) -#define __NR_recvmmsg (__NR_SYSCALL_BASE+365) -#endif - -#if !defined(__NR_accept4) -#define __NR_accept4 (__NR_SYSCALL_BASE+366) -#endif - -#if !defined(__NR_fanotify_init) -#define __NR_fanotify_init (__NR_SYSCALL_BASE+367) -#endif - -#if !defined(__NR_fanotify_mark) -#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368) -#endif - -#if !defined(__NR_prlimit64) -#define __NR_prlimit64 (__NR_SYSCALL_BASE+369) -#endif - -#if !defined(__NR_name_to_handle_at) -#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370) -#endif - -#if !defined(__NR_open_by_handle_at) -#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371) -#endif - -#if !defined(__NR_clock_adjtime) -#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372) -#endif - -#if !defined(__NR_syncfs) -#define __NR_syncfs (__NR_SYSCALL_BASE+373) -#endif - -#if !defined(__NR_sendmmsg) -#define __NR_sendmmsg (__NR_SYSCALL_BASE+374) -#endif - -#if !defined(__NR_setns) -#define __NR_setns (__NR_SYSCALL_BASE+375) -#endif - -#if !defined(__NR_process_vm_readv) -#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) -#endif - -#if !defined(__NR_process_vm_writev) -#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) -#endif - -#if !defined(__NR_kcmp) -#define __NR_kcmp (__NR_SYSCALL_BASE+378) -#endif - -#if !defined(__NR_finit_module) -#define __NR_finit_module (__NR_SYSCALL_BASE+379) -#endif - -#if !defined(__NR_sched_setattr) -#define __NR_sched_setattr (__NR_SYSCALL_BASE+380) -#endif - -#if !defined(__NR_sched_getattr) -#define __NR_sched_getattr (__NR_SYSCALL_BASE+381) -#endif - -#if !defined(__NR_renameat2) -#define __NR_renameat2 (__NR_SYSCALL_BASE+382) -#endif - -#if !defined(__NR_seccomp) -#define __NR_seccomp (__NR_SYSCALL_BASE+383) -#endif - -#if !defined(__NR_getrandom) -#define __NR_getrandom (__NR_SYSCALL_BASE+384) -#endif - -#if !defined(__NR_memfd_create) -#define __NR_memfd_create (__NR_SYSCALL_BASE+385) -#endif - -// ARM private syscalls. -#if !defined(__ARM_NR_BASE) -#define __ARM_NR_BASE (__NR_SYSCALL_BASE + 0xF0000) -#endif - -#if !defined(__ARM_NR_breakpoint) -#define __ARM_NR_breakpoint (__ARM_NR_BASE+1) -#endif - -#if !defined(__ARM_NR_cacheflush) -#define __ARM_NR_cacheflush (__ARM_NR_BASE+2) -#endif - -#if !defined(__ARM_NR_usr26) -#define __ARM_NR_usr26 (__ARM_NR_BASE+3) -#endif - -#if !defined(__ARM_NR_usr32) -#define __ARM_NR_usr32 (__ARM_NR_BASE+4) -#endif - -#if !defined(__ARM_NR_set_tls) -#define __ARM_NR_set_tls (__ARM_NR_BASE+5) -#endif - -// ARM kernel private syscall. -#if !defined(__ARM_NR_cmpxchg) -#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0) -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_SYSCALLS_H_ diff --git a/sandbox/linux/system_headers/arm_linux_ucontext.h b/sandbox/linux/system_headers/arm_linux_ucontext.h deleted file mode 100644 index 35208fa2a5..0000000000 --- a/sandbox/linux/system_headers/arm_linux_ucontext.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SYSTEM_HEADERS_ARM_LINUX_UCONTEXT_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_UCONTEXT_H_ - -#include <stddef.h> - -#if !defined(__BIONIC_HAVE_UCONTEXT_T) -#if !defined(__native_client_nonsfi__) -#include <asm/sigcontext.h> -#else -// In PNaCl toolchain, sigcontext and stack_t is not defined. So here declare -// them. -struct sigcontext { - unsigned long trap_no; - unsigned long error_code; - unsigned long oldmask; - unsigned long arm_r0; - unsigned long arm_r1; - unsigned long arm_r2; - unsigned long arm_r3; - unsigned long arm_r4; - unsigned long arm_r5; - unsigned long arm_r6; - unsigned long arm_r7; - unsigned long arm_r8; - unsigned long arm_r9; - unsigned long arm_r10; - unsigned long arm_fp; - unsigned long arm_ip; - unsigned long arm_sp; - unsigned long arm_lr; - unsigned long arm_pc; - unsigned long arm_cpsr; - unsigned long fault_address; -}; - -typedef struct sigaltstack { - void* ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#endif - -// We also need greg_t for the sandbox, include it in this header as well. -typedef unsigned long greg_t; - -// typedef unsigned long sigset_t; -typedef struct ucontext { - unsigned long uc_flags; - struct ucontext* uc_link; - stack_t uc_stack; - struct sigcontext uc_mcontext; - sigset_t uc_sigmask; - /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */ - int __not_used[32 - (sizeof(sigset_t) / sizeof(int))]; - /* Last for extensibility. Eight byte aligned because some - coprocessors require eight byte alignment. */ - unsigned long uc_regspace[128] __attribute__((__aligned__(8))); -} ucontext_t; - -#else -#include <sys/ucontext.h> -#endif // __BIONIC_HAVE_UCONTEXT_T - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_UCONTEXT_H_ diff --git a/sandbox/linux/system_headers/capability.h b/sandbox/linux/system_headers/capability.h deleted file mode 100644 index f91fcf78ac..0000000000 --- a/sandbox/linux/system_headers/capability.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 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_LINUX_SYSTEM_HEADERS_LINUX_CAPABILITY_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_CAPABILITY_H_ - -#include <stdint.h> - -// The following macros are taken from linux/capability.h. -// We only support capability version 3, which was introduced in Linux 2.6.26. -#ifndef _LINUX_CAPABILITY_VERSION_3 -#define _LINUX_CAPABILITY_VERSION_3 0x20080522 -#endif -#ifndef _LINUX_CAPABILITY_U32S_3 -#define _LINUX_CAPABILITY_U32S_3 2 -#endif -#ifndef CAP_TO_INDEX -#define CAP_TO_INDEX(x) ((x) >> 5) // 1 << 5 == bits in __u32 -#endif -#ifndef CAP_TO_MASK -#define CAP_TO_MASK(x) (1 << ((x) & 31)) // mask for indexed __u32 -#endif -#ifndef CAP_SYS_CHROOT -#define CAP_SYS_CHROOT 18 -#endif -#ifndef CAP_SYS_ADMIN -#define CAP_SYS_ADMIN 21 -#endif - -struct cap_hdr { - uint32_t version; - int pid; -}; - -struct cap_data { - uint32_t effective; - uint32_t permitted; - uint32_t inheritable; -}; - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_CAPABILITY_H_ diff --git a/sandbox/linux/system_headers/i386_linux_ucontext.h b/sandbox/linux/system_headers/i386_linux_ucontext.h deleted file mode 100644 index f4380339d9..0000000000 --- a/sandbox/linux/system_headers/i386_linux_ucontext.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2012 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_LINUX_SYSTEM_HEADERS_ANDROID_I386_UCONTEXT_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_I386_UCONTEXT_H_ - -#include <stddef.h> -#include <stdint.h> - -// We do something compatible with glibc. Hopefully, at some point Android will -// provide that for us, and __BIONIC_HAVE_UCONTEXT_T should be defined. -// This is mostly copied from breakpad (common/android/include/sys/ucontext.h), -// except we do use sigset_t for uc_sigmask instead of a custom type. - -#if !defined(__BIONIC_HAVE_UCONTEXT_T) -#if !defined(__native_client_nonsfi__) -#include <asm/sigcontext.h> -#else -// In PNaCl toolchain, sigcontext is not defined. So here declare it. -typedef struct sigaltstack { - void* ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; -#endif - -/* 80-bit floating-point register */ -struct _libc_fpreg { - unsigned short significand[4]; - unsigned short exponent; -}; - -/* Simple floating-point state, see FNSTENV instruction */ -struct _libc_fpstate { - unsigned long cw; - unsigned long sw; - unsigned long tag; - unsigned long ipoff; - unsigned long cssel; - unsigned long dataoff; - unsigned long datasel; - struct _libc_fpreg _st[8]; - unsigned long status; -}; - -typedef uint32_t greg_t; - -typedef struct { - uint32_t gregs[19]; - struct _libc_fpstate* fpregs; - uint32_t oldmask; - uint32_t cr2; -} mcontext_t; - -enum { - REG_GS = 0, - REG_FS, - REG_ES, - REG_DS, - REG_EDI, - REG_ESI, - REG_EBP, - REG_ESP, - REG_EBX, - REG_EDX, - REG_ECX, - REG_EAX, - REG_TRAPNO, - REG_ERR, - REG_EIP, - REG_CS, - REG_EFL, - REG_UESP, - REG_SS, -}; - -typedef struct ucontext { - uint32_t uc_flags; - struct ucontext* uc_link; - stack_t uc_stack; - mcontext_t uc_mcontext; - // Android and PNaCl toolchain's sigset_t has only 32 bits, though Linux - // ABI requires 64 bits. - union { - sigset_t uc_sigmask; - uint32_t kernel_sigmask[2]; - }; - struct _libc_fpstate __fpregs_mem; -} ucontext_t; - -#else -#include <sys/ucontext.h> -#endif // __BIONIC_HAVE_UCONTEXT_T - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_I386_UCONTEXT_H_ diff --git a/sandbox/linux/system_headers/linux_filter.h b/sandbox/linux/system_headers/linux_filter.h deleted file mode 100644 index b23b6eb0c1..0000000000 --- a/sandbox/linux/system_headers/linux_filter.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2015 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_LINUX_SYSTEM_HEADERS_LINUX_FILTER_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_FILTER_H_ - -#include <stdint.h> - -// The following structs and macros are taken from linux/filter.h, -// as some toolchain does not expose them. -struct sock_filter { - uint16_t code; - uint8_t jt; - uint8_t jf; - uint32_t k; -}; - -struct sock_fprog { - uint16_t len; - struct sock_filter *filter; -}; - -#ifndef BPF_CLASS -#define BPF_CLASS(code) ((code) & 0x07) -#endif - -#ifndef BPF_LD -#define BPF_LD 0x00 -#endif - -#ifndef BPF_ALU -#define BPF_ALU 0x04 -#endif - -#ifndef BPF_JMP -#define BPF_JMP 0x05 -#endif - -#ifndef BPF_RET -#define BPF_RET 0x06 -#endif - -#ifndef BPF_SIZE -#define BPF_SIZE(code) ((code) & 0x18) -#endif - -#ifndef BPF_W -#define BPF_W 0x00 -#endif - -#ifndef BPF_MODE -#define BPF_MODE(code) ((code) & 0xe0) -#endif - -#ifndef BPF_ABS -#define BPF_ABS 0x20 -#endif - -#ifndef BPF_OP -#define BPF_OP(code) ((code) & 0xf0) -#endif - -#ifndef BPF_ADD -#define BPF_ADD 0x00 -#endif - -#ifndef BPF_SUB -#define BPF_SUB 0x10 -#endif - -#ifndef BPF_MUL -#define BPF_MUL 0x20 -#endif - -#ifndef BPF_DIV -#define BPF_DIV 0x30 -#endif - -#ifndef BPF_OR -#define BPF_OR 0x40 -#endif - -#ifndef BPF_AND -#define BPF_AND 0x50 -#endif - -#ifndef BPF_LSH -#define BPF_LSH 0x60 -#endif - -#ifndef BPF_RSH -#define BPF_RSH 0x70 -#endif - -#ifndef BPF_NEG -#define BPF_NEG 0x80 -#endif - -#ifndef BPF_MOD -#define BPF_MOD 0x90 -#endif - -#ifndef BPF_XOR -#define BPF_XOR 0xA0 -#endif - -#ifndef BPF_JA -#define BPF_JA 0x00 -#endif - -#ifndef BPF_JEQ -#define BPF_JEQ 0x10 -#endif - -#ifndef BPF_JGT -#define BPF_JGT 0x20 -#endif - -#ifndef BPF_JGE -#define BPF_JGE 0x30 -#endif - -#ifndef BPF_JSET -#define BPF_JSET 0x40 -#endif - -#ifndef BPF_SRC -#define BPF_SRC(code) ((code) & 0x08) -#endif - -#ifndef BPF_K -#define BPF_K 0x00 -#endif - -#ifndef BPF_MAXINSNS -#define BPF_MAXINSNS 4096 -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_FILTER_H_ diff --git a/sandbox/linux/system_headers/linux_futex.h b/sandbox/linux/system_headers/linux_futex.h deleted file mode 100644 index 4e28403336..0000000000 --- a/sandbox/linux/system_headers/linux_futex.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2014 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_LINUX_SYSTEM_HEADERS_LINUX_FUTEX_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_FUTEX_H_ - -#if !defined(__native_client_nonsfi__) -#include <linux/futex.h> -#endif // !defined(__native_client_nonsfi__) - -#if !defined(FUTEX_WAIT) -#define FUTEX_WAIT 0 -#endif - -#if !defined(FUTEX_WAKE) -#define FUTEX_WAKE 1 -#endif - -#if !defined(FUTEX_FD) -#define FUTEX_FD 2 -#endif - -#if !defined(FUTEX_REQUEUE) -#define FUTEX_REQUEUE 3 -#endif - -#if !defined(FUTEX_CMP_REQUEUE) -#define FUTEX_CMP_REQUEUE 4 -#endif - -#if !defined(FUTEX_WAKE_OP) -#define FUTEX_WAKE_OP 5 -#endif - -#if !defined(FUTEX_LOCK_PI) -#define FUTEX_LOCK_PI 6 -#endif - -#if !defined(FUTEX_UNLOCK_PI) -#define FUTEX_UNLOCK_PI 7 -#endif - -#if !defined(FUTEX_TRYLOCK_PI) -#define FUTEX_TRYLOCK_PI 8 -#endif - -#if !defined(FUTEX_WAIT_BITSET) -#define FUTEX_WAIT_BITSET 9 -#endif - -#if !defined(FUTEX_WAKE_BITSET) -#define FUTEX_WAKE_BITSET 10 -#endif - -#if !defined(FUTEX_WAIT_REQUEUE_PI) -#define FUTEX_WAIT_REQUEUE_PI 11 -#endif - -#if !defined(FUTEX_CMP_REQUEUE_PI) -#define FUTEX_CMP_REQUEUE_PI 12 -#endif - -#if !defined(FUTEX_PRIVATE_FLAG) -#define FUTEX_PRIVATE_FLAG 128 -#endif - -#if !defined FUTEX_CLOCK_REALTIME -#define FUTEX_CLOCK_REALTIME 256 -#endif - -#if !defined(FUTEX_CMD_MASK) -#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) -#endif - -#if !defined(FUTEX_CMP_REQUEUE_PI_PRIVATE) -#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG) -#endif - -#if !defined(FUTEX_UNLOCK_PI_PRIVATE) -#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_FUTEX_H_ diff --git a/sandbox/linux/system_headers/linux_seccomp.h b/sandbox/linux/system_headers/linux_seccomp.h deleted file mode 100644 index 3deb3d2253..0000000000 --- a/sandbox/linux/system_headers/linux_seccomp.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015 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_LINUX_SYSTEM_HEADERS_LINUX_SECCOMP_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SECCOMP_H_ - -// The Seccomp2 kernel ABI is not part of older versions of glibc. -// As we can't break compilation with these versions of the library, -// we explicitly define all missing symbols. -// If we ever decide that we can now rely on system headers, the following -// include files should be enabled: -// #include <linux/audit.h> -// #include <linux/seccomp.h> - -// For audit.h -#ifndef EM_ARM -#define EM_ARM 40 -#endif -#ifndef EM_386 -#define EM_386 3 -#endif -#ifndef EM_X86_64 -#define EM_X86_64 62 -#endif -#ifndef EM_MIPS -#define EM_MIPS 8 -#endif -#ifndef EM_AARCH64 -#define EM_AARCH64 183 -#endif - -#ifndef __AUDIT_ARCH_64BIT -#define __AUDIT_ARCH_64BIT 0x80000000 -#endif -#ifndef __AUDIT_ARCH_LE -#define __AUDIT_ARCH_LE 0x40000000 -#endif -#ifndef AUDIT_ARCH_ARM -#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE) -#endif -#ifndef AUDIT_ARCH_I386 -#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE) -#endif -#ifndef AUDIT_ARCH_X86_64 -#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) -#endif -#ifndef AUDIT_ARCH_MIPSEL -#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE) -#endif -#ifndef AUDIT_ARCH_AARCH64 -#define AUDIT_ARCH_AARCH64 (EM_AARCH64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) -#endif - -// For prctl.h -#ifndef PR_SET_SECCOMP -#define PR_SET_SECCOMP 22 -#define PR_GET_SECCOMP 21 -#endif -#ifndef PR_SET_NO_NEW_PRIVS -#define PR_SET_NO_NEW_PRIVS 38 -#define PR_GET_NO_NEW_PRIVS 39 -#endif -#ifndef IPC_64 -#define IPC_64 0x0100 -#endif - -// In order to build will older tool chains, we currently have to avoid -// including <linux/seccomp.h>. Until that can be fixed (if ever). Rely on -// our own definitions of the seccomp kernel ABI. -#ifndef SECCOMP_MODE_FILTER -#define SECCOMP_MODE_DISABLED 0 -#define SECCOMP_MODE_STRICT 1 -#define SECCOMP_MODE_FILTER 2 // User user-supplied filter -#endif - -#ifndef SECCOMP_SET_MODE_STRICT -#define SECCOMP_SET_MODE_STRICT 0 -#endif -#ifndef SECCOMP_SET_MODE_FILTER -#define SECCOMP_SET_MODE_FILTER 1 -#endif -#ifndef SECCOMP_FILTER_FLAG_TSYNC -#define SECCOMP_FILTER_FLAG_TSYNC 1 -#endif - -#ifndef SECCOMP_RET_KILL -// Return values supported for BPF filter programs. Please note that the -// "illegal" SECCOMP_RET_INVALID is not supported by the kernel, should only -// ever be used internally, and would result in the kernel killing our process. -#define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately -#define SECCOMP_RET_INVALID 0x00010000U // Illegal return value -#define SECCOMP_RET_TRAP 0x00030000U // Disallow and force a SIGSYS -#define SECCOMP_RET_ERRNO 0x00050000U // Returns an errno -#define SECCOMP_RET_TRACE 0x7ff00000U // Pass to a tracer or disallow -#define SECCOMP_RET_ALLOW 0x7fff0000U // Allow -#define SECCOMP_RET_ACTION 0xffff0000U // Masks for the return value -#define SECCOMP_RET_DATA 0x0000ffffU // sections -#else -#define SECCOMP_RET_INVALID 0x00010000U // Illegal return value -#endif - -#ifndef SYS_SECCOMP -#define SYS_SECCOMP 1 -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SECCOMP_H_ diff --git a/sandbox/linux/system_headers/linux_signal.h b/sandbox/linux/system_headers/linux_signal.h deleted file mode 100644 index fb9a47b8d1..0000000000 --- a/sandbox/linux/system_headers/linux_signal.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2015 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_LINUX_SYSTEM_HEADERS_LINUX_SIGNAL_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SIGNAL_H_ - -#include <stdint.h> - -// NOTE: On some toolchains, signal related ABI is incompatible with Linux's -// (not undefined, but defined different values and in different memory -// layouts). So, fill the gap here. -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \ - defined(__aarch64__) - -#define LINUX_SIGHUP 1 -#define LINUX_SIGINT 2 -#define LINUX_SIGQUIT 3 -#define LINUX_SIGABRT 6 -#define LINUX_SIGBUS 7 -#define LINUX_SIGUSR1 10 -#define LINUX_SIGSEGV 11 -#define LINUX_SIGUSR2 12 -#define LINUX_SIGPIPE 13 -#define LINUX_SIGTERM 15 -#define LINUX_SIGCHLD 17 -#define LINUX_SIGSYS 31 - -#define LINUX_SIG_BLOCK 0 -#define LINUX_SIG_UNBLOCK 1 - -#define LINUX_SA_SIGINFO 4 -#define LINUX_SA_NODEFER 0x40000000 -#define LINUX_SA_RESTART 0x10000000 - -#define LINUX_SIG_DFL 0 - -#elif defined(__mips__) - -#define LINUX_SIGHUP 1 -#define LINUX_SIGINT 2 -#define LINUX_SIGQUIT 3 -#define LINUX_SIGABRT 6 -#define LINUX_SIGBUS 10 -#define LINUX_SIGSEGV 11 -#define LINUX_SIGSYS 12 -#define LINUX_SIGPIPE 13 -#define LINUX_SIGTERM 15 -#define LINUX_SIGUSR1 16 -#define LINUX_SIGUSR2 17 -#define LINUX_SIGCHLD 18 - -#define LINUX_SIG_BLOCK 1 -#define LINUX_SIG_UNBLOCK 2 - -#define LINUX_SA_SIGINFO 0x00000008 -#define LINUX_SA_NODEFER 0x40000000 -#define LINUX_SA_RESTART 0x10000000 - -#define LINUX_SIG_DFL 0 - -#else -#error "Unsupported platform" -#endif - -#if defined(__native_client_nonsfi__) -#if !defined(__i386__) && !defined(__arm__) -#error "Unsupported platform" -#endif - -#include <signal.h> - -struct LinuxSigInfo { - int si_signo; - int si_errno; - int si_code; - - // Extra data is followed by the |si_code|. The length depends on the - // signal number. - char _sifields[1]; -}; - -#include "sandbox/linux/system_headers/linux_ucontext.h" - -#else // !defined(__native_client_nonsfi__) - -#include <signal.h> - -static_assert(LINUX_SIGHUP == SIGHUP, "LINUX_SIGHUP == SIGHUP"); -static_assert(LINUX_SIGINT == SIGINT, "LINUX_SIGINT == SIGINT"); -static_assert(LINUX_SIGQUIT == SIGQUIT, "LINUX_SIGQUIT == SIGQUIT"); -static_assert(LINUX_SIGABRT == SIGABRT, "LINUX_SIGABRT == SIGABRT"); -static_assert(LINUX_SIGBUS == SIGBUS, "LINUX_SIGBUS == SIGBUS"); -static_assert(LINUX_SIGUSR1 == SIGUSR1, "LINUX_SIGUSR1 == SIGUSR1"); -static_assert(LINUX_SIGSEGV == SIGSEGV, "LINUX_SIGSEGV == SIGSEGV"); -static_assert(LINUX_SIGUSR2 == SIGUSR2, "LINUX_SIGUSR2 == SIGUSR2"); -static_assert(LINUX_SIGPIPE == SIGPIPE, "LINUX_SIGPIPE == SIGPIPE"); -static_assert(LINUX_SIGTERM == SIGTERM, "LINUX_SIGTERM == SIGTERM"); -static_assert(LINUX_SIGCHLD == SIGCHLD, "LINUX_SIGCHLD == SIGCHLD"); -static_assert(LINUX_SIGSYS == SIGSYS, "LINUX_SIGSYS == SIGSYS"); -static_assert(LINUX_SIG_BLOCK == SIG_BLOCK, "LINUX_SIG_BLOCK == SIG_BLOCK"); -static_assert(LINUX_SIG_UNBLOCK == SIG_UNBLOCK, - "LINUX_SIG_UNBLOCK == SIG_UNBLOCK"); -static_assert(LINUX_SA_SIGINFO == SA_SIGINFO, "LINUX_SA_SIGINFO == SA_SIGINFO"); -static_assert(LINUX_SA_NODEFER == SA_NODEFER, "LINUX_SA_NODEFER == SA_NODEFER"); -static_assert(LINUX_SA_RESTART == SA_RESTART, "LINUX_SA_RESTART == SA_RESTART"); -static_assert(LINUX_SIG_DFL == SIG_DFL, "LINUX_SIG_DFL == SIG_DFL"); - -typedef siginfo_t LinuxSigInfo; - -#if defined(__ANDROID__) -// Android's signal.h doesn't define ucontext etc. -#include "sandbox/linux/system_headers/linux_ucontext.h" -#endif // defined(__ANDROID__) - -#endif // !defined(__native_client_nonsfi__) - -// struct sigset_t is different size in PNaCl from the Linux's. -#if defined(__mips__) -#if !defined(_NSIG_WORDS) -#define _NSIG_WORDS 4 -#endif -struct LinuxSigSet { - unsigned long sig[_NSIG_WORDS]; -}; -#else -typedef uint64_t LinuxSigSet; -#endif - -// struct sigaction is different in PNaCl from the Linux's. -#if defined(__mips__) -struct LinuxSigAction { - unsigned int sa_flags; - void (*kernel_handler)(int); - LinuxSigSet sa_mask; -}; -#else -struct LinuxSigAction { - void (*kernel_handler)(int); - uint32_t sa_flags; - void (*sa_restorer)(void); - LinuxSigSet sa_mask; -}; -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SIGNAL_H_ diff --git a/sandbox/linux/system_headers/linux_syscalls.h b/sandbox/linux/system_headers/linux_syscalls.h deleted file mode 100644 index 2b441e47ea..0000000000 --- a/sandbox/linux/system_headers/linux_syscalls.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2012 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. - -// This header will be kept up to date so that we can compile system-call -// policies even when system headers are old. -// System call numbers are accessible through __NR_syscall_name. - -#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SYSCALLS_H_ - -#if defined(__x86_64__) -#include "sandbox/linux/system_headers/x86_64_linux_syscalls.h" -#endif - -#if defined(__i386__) -#include "sandbox/linux/system_headers/x86_32_linux_syscalls.h" -#endif - -#if defined(__arm__) && defined(__ARM_EABI__) -#include "sandbox/linux/system_headers/arm_linux_syscalls.h" -#endif - -#if defined(__mips__) && (_MIPS_SIM == _ABIO32) -#include "sandbox/linux/system_headers/mips_linux_syscalls.h" -#endif - -#if defined(__mips__) && (_MIPS_SIM == _ABI64) -#include "sandbox/linux/system_headers/mips64_linux_syscalls.h" -#endif - -#if defined(__aarch64__) -#include "sandbox/linux/system_headers/arm64_linux_syscalls.h" -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SYSCALLS_H_ - diff --git a/sandbox/linux/system_headers/linux_time.h b/sandbox/linux/system_headers/linux_time.h deleted file mode 100644 index e6c8112b86..0000000000 --- a/sandbox/linux/system_headers/linux_time.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015 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_LINUX_SYSTEM_HEADERS_LINUX_TIME_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_TIME_H_ - -#include <time.h> - -#if !defined(CLOCK_REALTIME_COARSE) -#define CLOCK_REALTIME_COARSE 5 -#endif - -#if !defined(CLOCK_MONOTONIC_COARSE) -#define CLOCK_MONOTONIC_COARSE 6 -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_TIME_H_ diff --git a/sandbox/linux/system_headers/linux_ucontext.h b/sandbox/linux/system_headers/linux_ucontext.h deleted file mode 100644 index ea4d8a6c1f..0000000000 --- a/sandbox/linux/system_headers/linux_ucontext.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2013 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_LINUX_SYSTEM_HEADERS_LINUX_UCONTEXT_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_UCONTEXT_H_ - -#if defined(__ANDROID__) || defined(__native_client_nonsfi__) - -#if defined(__arm__) -#include "sandbox/linux/system_headers/arm_linux_ucontext.h" -#elif defined(__i386__) -#include "sandbox/linux/system_headers/i386_linux_ucontext.h" -#elif defined(__x86_64__) -#include "sandbox/linux/system_headers/x86_64_linux_ucontext.h" -#elif defined(__mips__) -#include "sandbox/linux/system_headers/mips_linux_ucontext.h" -#elif defined(__aarch64__) -#include "sandbox/linux/system_headers/arm64_linux_ucontext.h" -#else -#error "No support for your architecture in Android or PNaCl header" -#endif - -#else // defined(__ANDROID__) || defined(__native_client_nonsfi__) -#error "The header file included on non Android and non PNaCl." -#endif // defined(__ANDROID__) || defined(__native_client_nonsfi__) - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_UCONTEXT_H_ diff --git a/sandbox/linux/system_headers/mips64_linux_syscalls.h b/sandbox/linux/system_headers/mips64_linux_syscalls.h deleted file mode 100644 index 90f3d1bea8..0000000000 --- a/sandbox/linux/system_headers/mips64_linux_syscalls.h +++ /dev/null @@ -1,1274 +0,0 @@ -// Copyright 2014 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. - -// Generated from the Linux kernel's calls.S. -#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_MIPS64_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_MIPS64_LINUX_SYSCALLS_H_ - -#if !defined(__mips__) || (_MIPS_SIM != _ABI64) -#error "Including header on wrong architecture" -#endif - -// __NR_Linux, is defined in <asm/unistd.h>. -#include <asm/unistd.h> - -#if !defined(__NR_read) -#define __NR_read (__NR_Linux + 0) -#endif - -#if !defined(__NR_write) -#define __NR_write (__NR_Linux + 1) -#endif - -#if !defined(__NR_open) -#define __NR_open (__NR_Linux + 2) -#endif - -#if !defined(__NR_close) -#define __NR_close (__NR_Linux + 3) -#endif - -#if !defined(__NR_stat) -#define __NR_stat (__NR_Linux + 4) -#endif - -#if !defined(__NR_fstat) -#define __NR_fstat (__NR_Linux + 5) -#endif - -#if !defined(__NR_lstat) -#define __NR_lstat (__NR_Linux + 6) -#endif - -#if !defined(__NR_poll) -#define __NR_poll (__NR_Linux + 7) -#endif - -#if !defined(__NR_lseek) -#define __NR_lseek (__NR_Linux + 8) -#endif - -#if !defined(__NR_mmap) -#define __NR_mmap (__NR_Linux + 9) -#endif - -#if !defined(__NR_mprotect) -#define __NR_mprotect (__NR_Linux + 10) -#endif - -#if !defined(__NR_munmap) -#define __NR_munmap (__NR_Linux + 11) -#endif - -#if !defined(__NR_brk) -#define __NR_brk (__NR_Linux + 12) -#endif - -#if !defined(__NR_rt_sigaction) -#define __NR_rt_sigaction (__NR_Linux + 13) -#endif - -#if !defined(__NR_rt_sigprocmask) -#define __NR_rt_sigprocmask (__NR_Linux + 14) -#endif - -#if !defined(__NR_ioctl) -#define __NR_ioctl (__NR_Linux + 15) -#endif - -#if !defined(__NR_pread64) -#define __NR_pread64 (__NR_Linux + 16) -#endif - -#if !defined(__NR_pwrite64) -#define __NR_pwrite64 (__NR_Linux + 17) -#endif - -#if !defined(__NR_readv) -#define __NR_readv (__NR_Linux + 18) -#endif - -#if !defined(__NR_writev) -#define __NR_writev (__NR_Linux + 19) -#endif - -#if !defined(__NR_access) -#define __NR_access (__NR_Linux + 20) -#endif - -#if !defined(__NR_pipe) -#define __NR_pipe (__NR_Linux + 21) -#endif - -#if !defined(__NR__newselect) -#define __NR__newselect (__NR_Linux + 22) -#endif - -#if !defined(__NR_sched_yield) -#define __NR_sched_yield (__NR_Linux + 23) -#endif - -#if !defined(__NR_mremap) -#define __NR_mremap (__NR_Linux + 24) -#endif - -#if !defined(__NR_msync) -#define __NR_msync (__NR_Linux + 25) -#endif - -#if !defined(__NR_mincore) -#define __NR_mincore (__NR_Linux + 26) -#endif - -#if !defined(__NR_madvise) -#define __NR_madvise (__NR_Linux + 27) -#endif - -#if !defined(__NR_shmget) -#define __NR_shmget (__NR_Linux + 28) -#endif - -#if !defined(__NR_shmat) -#define __NR_shmat (__NR_Linux + 29) -#endif - -#if !defined(__NR_shmctl) -#define __NR_shmctl (__NR_Linux + 30) -#endif - -#if !defined(__NR_dup) -#define __NR_dup (__NR_Linux + 31) -#endif - -#if !defined(__NR_dup2) -#define __NR_dup2 (__NR_Linux + 32) -#endif - -#if !defined(__NR_pause) -#define __NR_pause (__NR_Linux + 33) -#endif - -#if !defined(__NR_nanosleep) -#define __NR_nanosleep (__NR_Linux + 34) -#endif - -#if !defined(__NR_getitimer) -#define __NR_getitimer (__NR_Linux + 35) -#endif - -#if !defined(__NR_setitimer) -#define __NR_setitimer (__NR_Linux + 36) -#endif - -#if !defined(__NR_alarm) -#define __NR_alarm (__NR_Linux + 37) -#endif - -#if !defined(__NR_getpid) -#define __NR_getpid (__NR_Linux + 38) -#endif - -#if !defined(__NR_sendfile) -#define __NR_sendfile (__NR_Linux + 39) -#endif - -#if !defined(__NR_socket) -#define __NR_socket (__NR_Linux + 40) -#endif - -#if !defined(__NR_connect) -#define __NR_connect (__NR_Linux + 41) -#endif - -#if !defined(__NR_accept) -#define __NR_accept (__NR_Linux + 42) -#endif - -#if !defined(__NR_sendto) -#define __NR_sendto (__NR_Linux + 43) -#endif - -#if !defined(__NR_recvfrom) -#define __NR_recvfrom (__NR_Linux + 44) -#endif - -#if !defined(__NR_sendmsg) -#define __NR_sendmsg (__NR_Linux + 45) -#endif - -#if !defined(__NR_recvmsg) -#define __NR_recvmsg (__NR_Linux + 46) -#endif - -#if !defined(__NR_shutdown) -#define __NR_shutdown (__NR_Linux + 47) -#endif - -#if !defined(__NR_bind) -#define __NR_bind (__NR_Linux + 48) -#endif - -#if !defined(__NR_listen) -#define __NR_listen (__NR_Linux + 49) -#endif - -#if !defined(__NR_getsockname) -#define __NR_getsockname (__NR_Linux + 50) -#endif - -#if !defined(__NR_getpeername) -#define __NR_getpeername (__NR_Linux + 51) -#endif - -#if !defined(__NR_socketpair) -#define __NR_socketpair (__NR_Linux + 52) -#endif - -#if !defined(__NR_setsockopt) -#define __NR_setsockopt (__NR_Linux + 53) -#endif - -#if !defined(__NR_getsockopt) -#define __NR_getsockopt (__NR_Linux + 54) -#endif - -#if !defined(__NR_clone) -#define __NR_clone (__NR_Linux + 55) -#endif - -#if !defined(__NR_fork) -#define __NR_fork (__NR_Linux + 56) -#endif - -#if !defined(__NR_execve) -#define __NR_execve (__NR_Linux + 57) -#endif - -#if !defined(__NR_exit) -#define __NR_exit (__NR_Linux + 58) -#endif - -#if !defined(__NR_wait4) -#define __NR_wait4 (__NR_Linux + 59) -#endif - -#if !defined(__NR_kill) -#define __NR_kill (__NR_Linux + 60) -#endif - -#if !defined(__NR_uname) -#define __NR_uname (__NR_Linux + 61) -#endif - -#if !defined(__NR_semget) -#define __NR_semget (__NR_Linux + 62) -#endif - -#if !defined(__NR_semop) -#define __NR_semop (__NR_Linux + 63) -#endif - -#if !defined(__NR_semctl) -#define __NR_semctl (__NR_Linux + 64) -#endif - -#if !defined(__NR_shmdt) -#define __NR_shmdt (__NR_Linux + 65) -#endif - -#if !defined(__NR_msgget) -#define __NR_msgget (__NR_Linux + 66) -#endif - -#if !defined(__NR_msgsnd) -#define __NR_msgsnd (__NR_Linux + 67) -#endif - -#if !defined(__NR_msgrcv) -#define __NR_msgrcv (__NR_Linux + 68) -#endif - -#if !defined(__NR_msgctl) -#define __NR_msgctl (__NR_Linux + 69) -#endif - -#if !defined(__NR_fcntl) -#define __NR_fcntl (__NR_Linux + 70) -#endif - -#if !defined(__NR_flock) -#define __NR_flock (__NR_Linux + 71) -#endif - -#if !defined(__NR_fsync) -#define __NR_fsync (__NR_Linux + 72) -#endif - -#if !defined(__NR_fdatasync) -#define __NR_fdatasync (__NR_Linux + 73) -#endif - -#if !defined(__NR_truncate) -#define __NR_truncate (__NR_Linux + 74) -#endif - -#if !defined(__NR_ftruncate) -#define __NR_ftruncate (__NR_Linux + 75) -#endif - -#if !defined(__NR_getdents) -#define __NR_getdents (__NR_Linux + 76) -#endif - -#if !defined(__NR_getcwd) -#define __NR_getcwd (__NR_Linux + 77) -#endif - -#if !defined(__NR_chdir) -#define __NR_chdir (__NR_Linux + 78) -#endif - -#if !defined(__NR_fchdir) -#define __NR_fchdir (__NR_Linux + 79) -#endif - -#if !defined(__NR_rename) -#define __NR_rename (__NR_Linux + 80) -#endif - -#if !defined(__NR_mkdir) -#define __NR_mkdir (__NR_Linux + 81) -#endif - -#if !defined(__NR_rmdir) -#define __NR_rmdir (__NR_Linux + 82) -#endif - -#if !defined(__NR_creat) -#define __NR_creat (__NR_Linux + 83) -#endif - -#if !defined(__NR_link) -#define __NR_link (__NR_Linux + 84) -#endif - -#if !defined(__NR_unlink) -#define __NR_unlink (__NR_Linux + 85) -#endif - -#if !defined(__NR_symlink) -#define __NR_symlink (__NR_Linux + 86) -#endif - -#if !defined(__NR_readlink) -#define __NR_readlink (__NR_Linux + 87) -#endif - -#if !defined(__NR_chmod) -#define __NR_chmod (__NR_Linux + 88) -#endif - -#if !defined(__NR_fchmod) -#define __NR_fchmod (__NR_Linux + 89) -#endif - -#if !defined(__NR_chown) -#define __NR_chown (__NR_Linux + 90) -#endif - -#if !defined(__NR_fchown) -#define __NR_fchown (__NR_Linux + 91) -#endif - -#if !defined(__NR_lchown) -#define __NR_lchown (__NR_Linux + 92) -#endif - -#if !defined(__NR_umask) -#define __NR_umask (__NR_Linux + 93) -#endif - -#if !defined(__NR_gettimeofday) -#define __NR_gettimeofday (__NR_Linux + 94) -#endif - -#if !defined(__NR_getrlimit) -#define __NR_getrlimit (__NR_Linux + 95) -#endif - -#if !defined(__NR_getrusage) -#define __NR_getrusage (__NR_Linux + 96) -#endif - -#if !defined(__NR_sysinfo) -#define __NR_sysinfo (__NR_Linux + 97) -#endif - -#if !defined(__NR_times) -#define __NR_times (__NR_Linux + 98) -#endif - -#if !defined(__NR_ptrace) -#define __NR_ptrace (__NR_Linux + 99) -#endif - -#if !defined(__NR_getuid) -#define __NR_getuid (__NR_Linux + 100) -#endif - -#if !defined(__NR_syslog) -#define __NR_syslog (__NR_Linux + 101) -#endif - -#if !defined(__NR_getgid) -#define __NR_getgid (__NR_Linux + 102) -#endif - -#if !defined(__NR_setuid) -#define __NR_setuid (__NR_Linux + 103) -#endif - -#if !defined(__NR_setgid) -#define __NR_setgid (__NR_Linux + 104) -#endif - -#if !defined(__NR_geteuid) -#define __NR_geteuid (__NR_Linux + 105) -#endif - -#if !defined(__NR_getegid) -#define __NR_getegid (__NR_Linux + 106) -#endif - -#if !defined(__NR_setpgid) -#define __NR_setpgid (__NR_Linux + 107) -#endif - -#if !defined(__NR_getppid) -#define __NR_getppid (__NR_Linux + 108) -#endif - -#if !defined(__NR_getpgrp) -#define __NR_getpgrp (__NR_Linux + 109) -#endif - -#if !defined(__NR_setsid) -#define __NR_setsid (__NR_Linux + 110) -#endif - -#if !defined(__NR_setreuid) -#define __NR_setreuid (__NR_Linux + 111) -#endif - -#if !defined(__NR_setregid) -#define __NR_setregid (__NR_Linux + 112) -#endif - -#if !defined(__NR_getgroups) -#define __NR_getgroups (__NR_Linux + 113) -#endif - -#if !defined(__NR_setgroups) -#define __NR_setgroups (__NR_Linux + 114) -#endif - -#if !defined(__NR_setresuid) -#define __NR_setresuid (__NR_Linux + 115) -#endif - -#if !defined(__NR_getresuid) -#define __NR_getresuid (__NR_Linux + 116) -#endif - -#if !defined(__NR_setresgid) -#define __NR_setresgid (__NR_Linux + 117) -#endif - -#if !defined(__NR_getresgid) -#define __NR_getresgid (__NR_Linux + 118) -#endif - -#if !defined(__NR_getpgid) -#define __NR_getpgid (__NR_Linux + 119) -#endif - -#if !defined(__NR_setfsuid) -#define __NR_setfsuid (__NR_Linux + 120) -#endif - -#if !defined(__NR_setfsgid) -#define __NR_setfsgid (__NR_Linux + 121) -#endif - -#if !defined(__NR_getsid) -#define __NR_getsid (__NR_Linux + 122) -#endif - -#if !defined(__NR_capget) -#define __NR_capget (__NR_Linux + 123) -#endif - -#if !defined(__NR_capset) -#define __NR_capset (__NR_Linux + 124) -#endif - -#if !defined(__NR_rt_sigpending) -#define __NR_rt_sigpending (__NR_Linux + 125) -#endif - -#if !defined(__NR_rt_sigtimedwait) -#define __NR_rt_sigtimedwait (__NR_Linux + 126) -#endif - -#if !defined(__NR_rt_sigqueueinfo) -#define __NR_rt_sigqueueinfo (__NR_Linux + 127) -#endif - -#if !defined(__NR_rt_sigsuspend) -#define __NR_rt_sigsuspend (__NR_Linux + 128) -#endif - -#if !defined(__NR_sigaltstack) -#define __NR_sigaltstack (__NR_Linux + 129) -#endif - -#if !defined(__NR_utime) -#define __NR_utime (__NR_Linux + 130) -#endif - -#if !defined(__NR_mknod) -#define __NR_mknod (__NR_Linux + 131) -#endif - -#if !defined(__NR_personality) -#define __NR_personality (__NR_Linux + 132) -#endif - -#if !defined(__NR_ustat) -#define __NR_ustat (__NR_Linux + 133) -#endif - -#if !defined(__NR_statfs) -#define __NR_statfs (__NR_Linux + 134) -#endif - -#if !defined(__NR_fstatfs) -#define __NR_fstatfs (__NR_Linux + 135) -#endif - -#if !defined(__NR_sysfs) -#define __NR_sysfs (__NR_Linux + 136) -#endif - -#if !defined(__NR_getpriority) -#define __NR_getpriority (__NR_Linux + 137) -#endif - -#if !defined(__NR_setpriority) -#define __NR_setpriority (__NR_Linux + 138) -#endif - -#if !defined(__NR_sched_setparam) -#define __NR_sched_setparam (__NR_Linux + 139) -#endif - -#if !defined(__NR_sched_getparam) -#define __NR_sched_getparam (__NR_Linux + 140) -#endif - -#if !defined(__NR_sched_setscheduler) -#define __NR_sched_setscheduler (__NR_Linux + 141) -#endif - -#if !defined(__NR_sched_getscheduler) -#define __NR_sched_getscheduler (__NR_Linux + 142) -#endif - -#if !defined(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_max (__NR_Linux + 143) -#endif - -#if !defined(__NR_sched_get_priority_min) -#define __NR_sched_get_priority_min (__NR_Linux + 144) -#endif - -#if !defined(__NR_sched_rr_get_interval) -#define __NR_sched_rr_get_interval (__NR_Linux + 145) -#endif - -#if !defined(__NR_mlock) -#define __NR_mlock (__NR_Linux + 146) -#endif - -#if !defined(__NR_munlock) -#define __NR_munlock (__NR_Linux + 147) -#endif - -#if !defined(__NR_mlockall) -#define __NR_mlockall (__NR_Linux + 148) -#endif - -#if !defined(__NR_munlockall) -#define __NR_munlockall (__NR_Linux + 149) -#endif - -#if !defined(__NR_vhangup) -#define __NR_vhangup (__NR_Linux + 150) -#endif - -#if !defined(__NR_pivot_root) -#define __NR_pivot_root (__NR_Linux + 151) -#endif - -#if !defined(__NR__sysctl) -#define __NR__sysctl (__NR_Linux + 152) -#endif - -#if !defined(__NR_prctl) -#define __NR_prctl (__NR_Linux + 153) -#endif - -#if !defined(__NR_adjtimex) -#define __NR_adjtimex (__NR_Linux + 154) -#endif - -#if !defined(__NR_setrlimit) -#define __NR_setrlimit (__NR_Linux + 155) -#endif - -#if !defined(__NR_chroot) -#define __NR_chroot (__NR_Linux + 156) -#endif - -#if !defined(__NR_sync) -#define __NR_sync (__NR_Linux + 157) -#endif - -#if !defined(__NR_acct) -#define __NR_acct (__NR_Linux + 158) -#endif - -#if !defined(__NR_settimeofday) -#define __NR_settimeofday (__NR_Linux + 159) -#endif - -#if !defined(__NR_mount) -#define __NR_mount (__NR_Linux + 160) -#endif - -#if !defined(__NR_umount2) -#define __NR_umount2 (__NR_Linux + 161) -#endif - -#if !defined(__NR_swapon) -#define __NR_swapon (__NR_Linux + 162) -#endif - -#if !defined(__NR_swapoff) -#define __NR_swapoff (__NR_Linux + 163) -#endif - -#if !defined(__NR_reboot) -#define __NR_reboot (__NR_Linux + 164) -#endif - -#if !defined(__NR_sethostname) -#define __NR_sethostname (__NR_Linux + 165) -#endif - -#if !defined(__NR_setdomainname) -#define __NR_setdomainname (__NR_Linux + 166) -#endif - -#if !defined(__NR_create_module) -#define __NR_create_module (__NR_Linux + 167) -#endif - -#if !defined(__NR_init_module) -#define __NR_init_module (__NR_Linux + 168) -#endif - -#if !defined(__NR_delete_module) -#define __NR_delete_module (__NR_Linux + 169) -#endif - -#if !defined(__NR_get_kernel_syms) -#define __NR_get_kernel_syms (__NR_Linux + 170) -#endif - -#if !defined(__NR_query_module) -#define __NR_query_module (__NR_Linux + 171) -#endif - -#if !defined(__NR_quotactl) -#define __NR_quotactl (__NR_Linux + 172) -#endif - -#if !defined(__NR_nfsservctl) -#define __NR_nfsservctl (__NR_Linux + 173) -#endif - -#if !defined(__NR_getpmsg) -#define __NR_getpmsg (__NR_Linux + 174) -#endif - -#if !defined(__NR_putpmsg) -#define __NR_putpmsg (__NR_Linux + 175) -#endif - -#if !defined(__NR_afs_syscall) -#define __NR_afs_syscall (__NR_Linux + 176) -#endif - -#if !defined(__NR_reserved177) -#define __NR_reserved177 (__NR_Linux + 177) -#endif - -#if !defined(__NR_gettid) -#define __NR_gettid (__NR_Linux + 178) -#endif - -#if !defined(__NR_readahead) -#define __NR_readahead (__NR_Linux + 179) -#endif - -#if !defined(__NR_setxattr) -#define __NR_setxattr (__NR_Linux + 180) -#endif - -#if !defined(__NR_lsetxattr) -#define __NR_lsetxattr (__NR_Linux + 181) -#endif - -#if !defined(__NR_fsetxattr) -#define __NR_fsetxattr (__NR_Linux + 182) -#endif - -#if !defined(__NR_getxattr) -#define __NR_getxattr (__NR_Linux + 183) -#endif - -#if !defined(__NR_lgetxattr) -#define __NR_lgetxattr (__NR_Linux + 184) -#endif - -#if !defined(__NR_fgetxattr) -#define __NR_fgetxattr (__NR_Linux + 185) -#endif - -#if !defined(__NR_listxattr) -#define __NR_listxattr (__NR_Linux + 186) -#endif - -#if !defined(__NR_llistxattr) -#define __NR_llistxattr (__NR_Linux + 187) -#endif - -#if !defined(__NR_flistxattr) -#define __NR_flistxattr (__NR_Linux + 188) -#endif - -#if !defined(__NR_removexattr) -#define __NR_removexattr (__NR_Linux + 189) -#endif - -#if !defined(__NR_lremovexattr) -#define __NR_lremovexattr (__NR_Linux + 190) -#endif - -#if !defined(__NR_fremovexattr) -#define __NR_fremovexattr (__NR_Linux + 191) -#endif - -#if !defined(__NR_tkill) -#define __NR_tkill (__NR_Linux + 192) -#endif - -#if !defined(__NR_reserved193) -#define __NR_reserved193 (__NR_Linux + 193) -#endif - -#if !defined(__NR_futex) -#define __NR_futex (__NR_Linux + 194) -#endif - -#if !defined(__NR_sched_setaffinity) -#define __NR_sched_setaffinity (__NR_Linux + 195) -#endif - -#if !defined(__NR_sched_getaffinity) -#define __NR_sched_getaffinity (__NR_Linux + 196) -#endif - -#if !defined(__NR_cacheflush) -#define __NR_cacheflush (__NR_Linux + 197) -#endif - -#if !defined(__NR_cachectl) -#define __NR_cachectl (__NR_Linux + 198) -#endif - -#if !defined(__NR_sysmips) -#define __NR_sysmips (__NR_Linux + 199) -#endif - -#if !defined(__NR_io_setup) -#define __NR_io_setup (__NR_Linux + 200) -#endif - -#if !defined(__NR_io_destroy) -#define __NR_io_destroy (__NR_Linux + 201) -#endif - -#if !defined(__NR_io_getevents) -#define __NR_io_getevents (__NR_Linux + 202) -#endif - -#if !defined(__NR_io_submit) -#define __NR_io_submit (__NR_Linux + 203) -#endif - -#if !defined(__NR_io_cancel) -#define __NR_io_cancel (__NR_Linux + 204) -#endif - -#if !defined(__NR_exit_group) -#define __NR_exit_group (__NR_Linux + 205) -#endif - -#if !defined(__NR_lookup_dcookie) -#define __NR_lookup_dcookie (__NR_Linux + 206) -#endif - -#if !defined(__NR_epoll_create) -#define __NR_epoll_create (__NR_Linux + 207) -#endif - -#if !defined(__NR_epoll_ctl) -#define __NR_epoll_ctl (__NR_Linux + 208) -#endif - -#if !defined(__NR_epoll_wait) -#define __NR_epoll_wait (__NR_Linux + 209) -#endif - -#if !defined(__NR_remap_file_pages) -#define __NR_remap_file_pages (__NR_Linux + 210) -#endif - -#if !defined(__NR_rt_sigreturn) -#define __NR_rt_sigreturn (__NR_Linux + 211) -#endif - -#if !defined(__NR_set_tid_address) -#define __NR_set_tid_address (__NR_Linux + 212) -#endif - -#if !defined(__NR_restart_syscall) -#define __NR_restart_syscall (__NR_Linux + 213) -#endif - -#if !defined(__NR_semtimedop) -#define __NR_semtimedop (__NR_Linux + 214) -#endif - -#if !defined(__NR_fadvise64) -#define __NR_fadvise64 (__NR_Linux + 215) -#endif - -#if !defined(__NR_timer_create) -#define __NR_timer_create (__NR_Linux + 216) -#endif - -#if !defined(__NR_timer_settime) -#define __NR_timer_settime (__NR_Linux + 217) -#endif - -#if !defined(__NR_timer_gettime) -#define __NR_timer_gettime (__NR_Linux + 218) -#endif - -#if !defined(__NR_timer_getoverrun) -#define __NR_timer_getoverrun (__NR_Linux + 219) -#endif - -#if !defined(__NR_timer_delete) -#define __NR_timer_delete (__NR_Linux + 220) -#endif - -#if !defined(__NR_clock_settime) -#define __NR_clock_settime (__NR_Linux + 221) -#endif - -#if !defined(__NR_clock_gettime) -#define __NR_clock_gettime (__NR_Linux + 222) -#endif - -#if !defined(__NR_clock_getres) -#define __NR_clock_getres (__NR_Linux + 223) -#endif - -#if !defined(__NR_clock_nanosleep) -#define __NR_clock_nanosleep (__NR_Linux + 224) -#endif - -#if !defined(__NR_tgkill) -#define __NR_tgkill (__NR_Linux + 225) -#endif - -#if !defined(__NR_utimes) -#define __NR_utimes (__NR_Linux + 226) -#endif - -#if !defined(__NR_mbind) -#define __NR_mbind (__NR_Linux + 227) -#endif - -#if !defined(__NR_get_mempolicy) -#define __NR_get_mempolicy (__NR_Linux + 228) -#endif - -#if !defined(__NR_set_mempolicy) -#define __NR_set_mempolicy (__NR_Linux + 229) -#endif - -#if !defined(__NR_mq_open) -#define __NR_mq_open (__NR_Linux + 230) -#endif - -#if !defined(__NR_mq_unlink) -#define __NR_mq_unlink (__NR_Linux + 231) -#endif - -#if !defined(__NR_mq_timedsend) -#define __NR_mq_timedsend (__NR_Linux + 232) -#endif - -#if !defined(__NR_mq_timedreceive) -#define __NR_mq_timedreceive (__NR_Linux + 233) -#endif - -#if !defined(__NR_mq_notify) -#define __NR_mq_notify (__NR_Linux + 234) -#endif - -#if !defined(__NR_mq_getsetattr) -#define __NR_mq_getsetattr (__NR_Linux + 235) -#endif - -#if !defined(__NR_vserver) -#define __NR_vserver (__NR_Linux + 236) -#endif - -#if !defined(__NR_waitid) -#define __NR_waitid (__NR_Linux + 237) -#endif - -/* #define __NR_sys_setaltroot (__NR_Linux + 238) */ - -#if !defined(__NR_add_key) -#define __NR_add_key (__NR_Linux + 239) -#endif - -#if !defined(__NR_request_key) -#define __NR_request_key (__NR_Linux + 240) -#endif - -#if !defined(__NR_keyctl) -#define __NR_keyctl (__NR_Linux + 241) -#endif - -#if !defined(__NR_set_thread_area) -#define __NR_set_thread_area (__NR_Linux + 242) -#endif - -#if !defined(__NR_inotify_init) -#define __NR_inotify_init (__NR_Linux + 243) -#endif - -#if !defined(__NR_inotify_add_watch) -#define __NR_inotify_add_watch (__NR_Linux + 244) -#endif - -#if !defined(__NR_inotify_rm_watch) -#define __NR_inotify_rm_watch (__NR_Linux + 245) -#endif - -#if !defined(__NR_migrate_pages) -#define __NR_migrate_pages (__NR_Linux + 246) -#endif - -#if !defined(__NR_openat) -#define __NR_openat (__NR_Linux + 247) -#endif - -#if !defined(__NR_mkdirat) -#define __NR_mkdirat (__NR_Linux + 248) -#endif - -#if !defined(__NR_mknodat) -#define __NR_mknodat (__NR_Linux + 249) -#endif - -#if !defined(__NR_fchownat) -#define __NR_fchownat (__NR_Linux + 250) -#endif - -#if !defined(__NR_futimesat) -#define __NR_futimesat (__NR_Linux + 251) -#endif - -#if !defined(__NR_newfstatat) -#define __NR_newfstatat (__NR_Linux + 252) -#endif - -#if !defined(__NR_unlinkat) -#define __NR_unlinkat (__NR_Linux + 253) -#endif - -#if !defined(__NR_renameat) -#define __NR_renameat (__NR_Linux + 254) -#endif - -#if !defined(__NR_linkat) -#define __NR_linkat (__NR_Linux + 255) -#endif - -#if !defined(__NR_symlinkat) -#define __NR_symlinkat (__NR_Linux + 256) -#endif - -#if !defined(__NR_readlinkat) -#define __NR_readlinkat (__NR_Linux + 257) -#endif - -#if !defined(__NR_fchmodat) -#define __NR_fchmodat (__NR_Linux + 258) -#endif - -#if !defined(__NR_faccessat) -#define __NR_faccessat (__NR_Linux + 259) -#endif - -#if !defined(__NR_pselect6) -#define __NR_pselect6 (__NR_Linux + 260) -#endif - -#if !defined(__NR_ppoll) -#define __NR_ppoll (__NR_Linux + 261) -#endif - -#if !defined(__NR_unshare) -#define __NR_unshare (__NR_Linux + 262) -#endif - -#if !defined(__NR_splice) -#define __NR_splice (__NR_Linux + 263) -#endif - -#if !defined(__NR_sync_file_range) -#define __NR_sync_file_range (__NR_Linux + 264) -#endif - -#if !defined(__NR_tee) -#define __NR_tee (__NR_Linux + 265) -#endif - -#if !defined(__NR_vmsplice) -#define __NR_vmsplice (__NR_Linux + 266) -#endif - -#if !defined(__NR_move_pages) -#define __NR_move_pages (__NR_Linux + 267) -#endif - -#if !defined(__NR_set_robust_list) -#define __NR_set_robust_list (__NR_Linux + 268) -#endif - -#if !defined(__NR_get_robust_list) -#define __NR_get_robust_list (__NR_Linux + 269) -#endif - -#if !defined(__NR_kexec_load) -#define __NR_kexec_load (__NR_Linux + 270) -#endif - -#if !defined(__NR_getcpu) -#define __NR_getcpu (__NR_Linux + 271) -#endif - -#if !defined(__NR_epoll_pwait) -#define __NR_epoll_pwait (__NR_Linux + 272) -#endif - -#if !defined(__NR_ioprio_set) -#define __NR_ioprio_set (__NR_Linux + 273) -#endif - -#if !defined(__NR_ioprio_get) -#define __NR_ioprio_get (__NR_Linux + 274) -#endif - -#if !defined(__NR_utimensat) -#define __NR_utimensat (__NR_Linux + 275) -#endif - -#if !defined(__NR_signalfd) -#define __NR_signalfd (__NR_Linux + 276) -#endif - -#if !defined(__NR_timerfd) -#define __NR_timerfd (__NR_Linux + 277) -#endif - -#if !defined(__NR_eventfd) -#define __NR_eventfd (__NR_Linux + 278) -#endif - -#if !defined(__NR_fallocate) -#define __NR_fallocate (__NR_Linux + 279) -#endif - -#if !defined(__NR_timerfd_create) -#define __NR_timerfd_create (__NR_Linux + 280) -#endif - -#if !defined(__NR_timerfd_gettime) -#define __NR_timerfd_gettime (__NR_Linux + 281) -#endif - -#if !defined(__NR_timerfd_settime) -#define __NR_timerfd_settime (__NR_Linux + 282) -#endif - -#if !defined(__NR_signalfd4) -#define __NR_signalfd4 (__NR_Linux + 283) -#endif - -#if !defined(__NR_eventfd2) -#define __NR_eventfd2 (__NR_Linux + 284) -#endif - -#if !defined(__NR_epoll_create1) -#define __NR_epoll_create1 (__NR_Linux + 285) -#endif - -#if !defined(__NR_dup3) -#define __NR_dup3 (__NR_Linux + 286) -#endif - -#if !defined(__NR_pipe2) -#define __NR_pipe2 (__NR_Linux + 287) -#endif - -#if !defined(__NR_inotify_init1) -#define __NR_inotify_init1 (__NR_Linux + 288) -#endif - -#if !defined(__NR_preadv) -#define __NR_preadv (__NR_Linux + 289) -#endif - -#if !defined(__NR_pwritev) -#define __NR_pwritev (__NR_Linux + 290) -#endif - -#if !defined(__NR_rt_tgsigqueueinfo) -#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291) -#endif - -#if !defined(__NR_perf_event_open) -#define __NR_perf_event_open (__NR_Linux + 292) -#endif - -#if !defined(__NR_accept4) -#define __NR_accept4 (__NR_Linux + 293) -#endif - -#if !defined(__NR_recvmmsg) -#define __NR_recvmmsg (__NR_Linux + 294) -#endif - -#if !defined(__NR_fanotify_init) -#define __NR_fanotify_init (__NR_Linux + 295) -#endif - -#if !defined(__NR_fanotify_mark) -#define __NR_fanotify_mark (__NR_Linux + 296) -#endif - -#if !defined(__NR_prlimit64) -#define __NR_prlimit64 (__NR_Linux + 297) -#endif - -#if !defined(__NR_name_to_handle_at) -#define __NR_name_to_handle_at (__NR_Linux + 298) -#endif - -#if !defined(__NR_open_by_handle_at) -#define __NR_open_by_handle_at (__NR_Linux + 299) -#endif - -#if !defined(__NR_clock_adjtime) -#define __NR_clock_adjtime (__NR_Linux + 300) -#endif - -#if !defined(__NR_syncfs) -#define __NR_syncfs (__NR_Linux + 301) -#endif - -#if !defined(__NR_sendmmsg) -#define __NR_sendmmsg (__NR_Linux + 302) -#endif - -#if !defined(__NR_setns) -#define __NR_setns (__NR_Linux + 303) -#endif - -#if !defined(__NR_process_vm_readv) -#define __NR_process_vm_readv (__NR_Linux + 304) -#endif - -#if !defined(__NR_process_vm_writev) -#define __NR_process_vm_writev (__NR_Linux + 305) -#endif - -#if !defined(__NR_kcmp) -#define __NR_kcmp (__NR_Linux + 306) -#endif - -#if !defined(__NR_finit_module) -#define __NR_finit_module (__NR_Linux + 307) -#endif - -#if !defined(__NR_getdents64) -#define __NR_getdents64 (__NR_Linux + 308) -#endif - -#if !defined(__NR_sched_setattr) -#define __NR_sched_setattr (__NR_Linux + 309) -#endif - -#if !defined(__NR_sched_getattr) -#define __NR_sched_getattr (__NR_Linux + 310) -#endif - -#if !defined(__NR_renameat2) -#define __NR_renameat2 (__NR_Linux + 311) -#endif - -#if !defined(__NR_seccomp) -#define __NR_seccomp (__NR_Linux + 312) -#endif - -#if !defined(__NR_getrandom) -#define __NR_getrandom (__NR_Linux + 313) -#endif - -#if !defined(__NR_memfd_create) -#define __NR_memfd_create (__NR_Linux + 314) -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_MIPS64_LINUX_SYSCALLS_H_ diff --git a/sandbox/linux/system_headers/mips_linux_syscalls.h b/sandbox/linux/system_headers/mips_linux_syscalls.h deleted file mode 100644 index 784d6b8ae0..0000000000 --- a/sandbox/linux/system_headers/mips_linux_syscalls.h +++ /dev/null @@ -1,1436 +0,0 @@ -// Copyright 2014 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. - -// Generated from the Linux kernel's calls.S. -#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_SYSCALLS_H_ - -#if !defined(__mips__) || (_MIPS_SIM != _ABIO32) -#error "Including header on wrong architecture" -#endif - -// __NR_Linux, is defined in <asm/unistd.h>. -#include <asm/unistd.h> - -#if !defined(__NR_syscall) -#define __NR_syscall (__NR_Linux + 0) -#endif - -#if !defined(__NR_exit) -#define __NR_exit (__NR_Linux + 1) -#endif - -#if !defined(__NR_fork) -#define __NR_fork (__NR_Linux + 2) -#endif - -#if !defined(__NR_read) -#define __NR_read (__NR_Linux + 3) -#endif - -#if !defined(__NR_write) -#define __NR_write (__NR_Linux + 4) -#endif - -#if !defined(__NR_open) -#define __NR_open (__NR_Linux + 5) -#endif - -#if !defined(__NR_close) -#define __NR_close (__NR_Linux + 6) -#endif - -#if !defined(__NR_waitpid) -#define __NR_waitpid (__NR_Linux + 7) -#endif - -#if !defined(__NR_creat) -#define __NR_creat (__NR_Linux + 8) -#endif - -#if !defined(__NR_link) -#define __NR_link (__NR_Linux + 9) -#endif - -#if !defined(__NR_unlink) -#define __NR_unlink (__NR_Linux + 10) -#endif - -#if !defined(__NR_execve) -#define __NR_execve (__NR_Linux + 11) -#endif - -#if !defined(__NR_chdir) -#define __NR_chdir (__NR_Linux + 12) -#endif - -#if !defined(__NR_time) -#define __NR_time (__NR_Linux + 13) -#endif - -#if !defined(__NR_mknod) -#define __NR_mknod (__NR_Linux + 14) -#endif - -#if !defined(__NR_chmod) -#define __NR_chmod (__NR_Linux + 15) -#endif - -#if !defined(__NR_lchown) -#define __NR_lchown (__NR_Linux + 16) -#endif - -#if !defined(__NR_break) -#define __NR_break (__NR_Linux + 17) -#endif - -#if !defined(__NR_unused18) -#define __NR_unused18 (__NR_Linux + 18) -#endif - -#if !defined(__NR_lseek) -#define __NR_lseek (__NR_Linux + 19) -#endif - -#if !defined(__NR_getpid) -#define __NR_getpid (__NR_Linux + 20) -#endif - -#if !defined(__NR_mount) -#define __NR_mount (__NR_Linux + 21) -#endif - -#if !defined(__NR_umount) -#define __NR_umount (__NR_Linux + 22) -#endif - -#if !defined(__NR_setuid) -#define __NR_setuid (__NR_Linux + 23) -#endif - -#if !defined(__NR_getuid) -#define __NR_getuid (__NR_Linux + 24) -#endif - -#if !defined(__NR_stime) -#define __NR_stime (__NR_Linux + 25) -#endif - -#if !defined(__NR_ptrace) -#define __NR_ptrace (__NR_Linux + 26) -#endif - -#if !defined(__NR_alarm) -#define __NR_alarm (__NR_Linux + 27) -#endif - -#if !defined(__NR_unused28) -#define __NR_unused28 (__NR_Linux + 28) -#endif - -#if !defined(__NR_pause) -#define __NR_pause (__NR_Linux + 29) -#endif - -#if !defined(__NR_utime) -#define __NR_utime (__NR_Linux + 30) -#endif - -#if !defined(__NR_stty) -#define __NR_stty (__NR_Linux + 31) -#endif - -#if !defined(__NR_gtty) -#define __NR_gtty (__NR_Linux + 32) -#endif - -#if !defined(__NR_access) -#define __NR_access (__NR_Linux + 33) -#endif - -#if !defined(__NR_nice) -#define __NR_nice (__NR_Linux + 34) -#endif - -#if !defined(__NR_ftime) -#define __NR_ftime (__NR_Linux + 35) -#endif - -#if !defined(__NR_sync) -#define __NR_sync (__NR_Linux + 36) -#endif - -#if !defined(__NR_kill) -#define __NR_kill (__NR_Linux + 37) -#endif - -#if !defined(__NR_rename) -#define __NR_rename (__NR_Linux + 38) -#endif - -#if !defined(__NR_mkdir) -#define __NR_mkdir (__NR_Linux + 39) -#endif - -#if !defined(__NR_rmdir) -#define __NR_rmdir (__NR_Linux + 40) -#endif - -#if !defined(__NR_dup) -#define __NR_dup (__NR_Linux + 41) -#endif - -#if !defined(__NR_pipe) -#define __NR_pipe (__NR_Linux + 42) -#endif - -#if !defined(__NR_times) -#define __NR_times (__NR_Linux + 43) -#endif - -#if !defined(__NR_prof) -#define __NR_prof (__NR_Linux + 44) -#endif - -#if !defined(__NR_brk) -#define __NR_brk (__NR_Linux + 45) -#endif - -#if !defined(__NR_setgid) -#define __NR_setgid (__NR_Linux + 46) -#endif - -#if !defined(__NR_getgid) -#define __NR_getgid (__NR_Linux + 47) -#endif - -#if !defined(__NR_signal) -#define __NR_signal (__NR_Linux + 48) -#endif - -#if !defined(__NR_geteuid) -#define __NR_geteuid (__NR_Linux + 49) -#endif - -#if !defined(__NR_getegid) -#define __NR_getegid (__NR_Linux + 50) -#endif - -#if !defined(__NR_acct) -#define __NR_acct (__NR_Linux + 51) -#endif - -#if !defined(__NR_umount2) -#define __NR_umount2 (__NR_Linux + 52) -#endif - -#if !defined(__NR_lock) -#define __NR_lock (__NR_Linux + 53) -#endif - -#if !defined(__NR_ioctl) -#define __NR_ioctl (__NR_Linux + 54) -#endif - -#if !defined(__NR_fcntl) -#define __NR_fcntl (__NR_Linux + 55) -#endif - -#if !defined(__NR_mpx) -#define __NR_mpx (__NR_Linux + 56) -#endif - -#if !defined(__NR_setpgid) -#define __NR_setpgid (__NR_Linux + 57) -#endif - -#if !defined(__NR_ulimit) -#define __NR_ulimit (__NR_Linux + 58) -#endif - -#if !defined(__NR_unused59) -#define __NR_unused59 (__NR_Linux + 59) -#endif - -#if !defined(__NR_umask) -#define __NR_umask (__NR_Linux + 60) -#endif - -#if !defined(__NR_chroot) -#define __NR_chroot (__NR_Linux + 61) -#endif - -#if !defined(__NR_ustat) -#define __NR_ustat (__NR_Linux + 62) -#endif - -#if !defined(__NR_dup2) -#define __NR_dup2 (__NR_Linux + 63) -#endif - -#if !defined(__NR_getppid) -#define __NR_getppid (__NR_Linux + 64) -#endif - -#if !defined(__NR_getpgrp) -#define __NR_getpgrp (__NR_Linux + 65) -#endif - -#if !defined(__NR_setsid) -#define __NR_setsid (__NR_Linux + 66) -#endif - -#if !defined(__NR_sigaction) -#define __NR_sigaction (__NR_Linux + 67) -#endif - -#if !defined(__NR_sgetmask) -#define __NR_sgetmask (__NR_Linux + 68) -#endif - -#if !defined(__NR_ssetmask) -#define __NR_ssetmask (__NR_Linux + 69) -#endif - -#if !defined(__NR_setreuid) -#define __NR_setreuid (__NR_Linux + 70) -#endif - -#if !defined(__NR_setregid) -#define __NR_setregid (__NR_Linux + 71) -#endif - -#if !defined(__NR_sigsuspend) -#define __NR_sigsuspend (__NR_Linux + 72) -#endif - -#if !defined(__NR_sigpending) -#define __NR_sigpending (__NR_Linux + 73) -#endif - -#if !defined(__NR_sethostname) -#define __NR_sethostname (__NR_Linux + 74) -#endif - -#if !defined(__NR_setrlimit) -#define __NR_setrlimit (__NR_Linux + 75) -#endif - -#if !defined(__NR_getrlimit) -#define __NR_getrlimit (__NR_Linux + 76) -#endif - -#if !defined(__NR_getrusage) -#define __NR_getrusage (__NR_Linux + 77) -#endif - -#if !defined(__NR_gettimeofday) -#define __NR_gettimeofday (__NR_Linux + 78) -#endif - -#if !defined(__NR_settimeofday) -#define __NR_settimeofday (__NR_Linux + 79) -#endif - -#if !defined(__NR_getgroups) -#define __NR_getgroups (__NR_Linux + 80) -#endif - -#if !defined(__NR_setgroups) -#define __NR_setgroups (__NR_Linux + 81) -#endif - -#if !defined(__NR_reserved82) -#define __NR_reserved82 (__NR_Linux + 82) -#endif - -#if !defined(__NR_symlink) -#define __NR_symlink (__NR_Linux + 83) -#endif - -#if !defined(__NR_unused84) -#define __NR_unused84 (__NR_Linux + 84) -#endif - -#if !defined(__NR_readlink) -#define __NR_readlink (__NR_Linux + 85) -#endif - -#if !defined(__NR_uselib) -#define __NR_uselib (__NR_Linux + 86) -#endif - -#if !defined(__NR_swapon) -#define __NR_swapon (__NR_Linux + 87) -#endif - -#if !defined(__NR_reboot) -#define __NR_reboot (__NR_Linux + 88) -#endif - -#if !defined(__NR_readdir) -#define __NR_readdir (__NR_Linux + 89) -#endif - -#if !defined(__NR_mmap) -#define __NR_mmap (__NR_Linux + 90) -#endif - -#if !defined(__NR_munmap) -#define __NR_munmap (__NR_Linux + 91) -#endif - -#if !defined(__NR_truncate) -#define __NR_truncate (__NR_Linux + 92) -#endif - -#if !defined(__NR_ftruncate) -#define __NR_ftruncate (__NR_Linux + 93) -#endif - -#if !defined(__NR_fchmod) -#define __NR_fchmod (__NR_Linux + 94) -#endif - -#if !defined(__NR_fchown) -#define __NR_fchown (__NR_Linux + 95) -#endif - -#if !defined(__NR_getpriority) -#define __NR_getpriority (__NR_Linux + 96) -#endif - -#if !defined(__NR_setpriority) -#define __NR_setpriority (__NR_Linux + 97) -#endif - -#if !defined(__NR_profil) -#define __NR_profil (__NR_Linux + 98) -#endif - -#if !defined(__NR_statfs) -#define __NR_statfs (__NR_Linux + 99) -#endif - -#if !defined(__NR_fstatfs) -#define __NR_fstatfs (__NR_Linux + 100) -#endif - -#if !defined(__NR_ioperm) -#define __NR_ioperm (__NR_Linux + 101) -#endif - -#if !defined(__NR_socketcall) -#define __NR_socketcall (__NR_Linux + 102) -#endif - -#if !defined(__NR_syslog) -#define __NR_syslog (__NR_Linux + 103) -#endif - -#if !defined(__NR_setitimer) -#define __NR_setitimer (__NR_Linux + 104) -#endif - -#if !defined(__NR_getitimer) -#define __NR_getitimer (__NR_Linux + 105) -#endif - -#if !defined(__NR_stat) -#define __NR_stat (__NR_Linux + 106) -#endif - -#if !defined(__NR_lstat) -#define __NR_lstat (__NR_Linux + 107) -#endif - -#if !defined(__NR_fstat) -#define __NR_fstat (__NR_Linux + 108) -#endif - -#if !defined(__NR_unused109) -#define __NR_unused109 (__NR_Linux + 109) -#endif - -#if !defined(__NR_iopl) -#define __NR_iopl (__NR_Linux + 110) -#endif - -#if !defined(__NR_vhangup) -#define __NR_vhangup (__NR_Linux + 111) -#endif - -#if !defined(__NR_idle) -#define __NR_idle (__NR_Linux + 112) -#endif - -#if !defined(__NR_vm86) -#define __NR_vm86 (__NR_Linux + 113) -#endif - -#if !defined(__NR_wait4) -#define __NR_wait4 (__NR_Linux + 114) -#endif - -#if !defined(__NR_swapoff) -#define __NR_swapoff (__NR_Linux + 115) -#endif - -#if !defined(__NR_sysinfo) -#define __NR_sysinfo (__NR_Linux + 116) -#endif - -#if !defined(__NR_ipc) -#define __NR_ipc (__NR_Linux + 117) -#endif - -#if !defined(__NR_fsync) -#define __NR_fsync (__NR_Linux + 118) -#endif - -#if !defined(__NR_sigreturn) -#define __NR_sigreturn (__NR_Linux + 119) -#endif - -#if !defined(__NR_clone) -#define __NR_clone (__NR_Linux + 120) -#endif - -#if !defined(__NR_setdomainname) -#define __NR_setdomainname (__NR_Linux + 121) -#endif - -#if !defined(__NR_uname) -#define __NR_uname (__NR_Linux + 122) -#endif - -#if !defined(__NR_modify_ldt) -#define __NR_modify_ldt (__NR_Linux + 123) -#endif - -#if !defined(__NR_adjtimex) -#define __NR_adjtimex (__NR_Linux + 124) -#endif - -#if !defined(__NR_mprotect) -#define __NR_mprotect (__NR_Linux + 125) -#endif - -#if !defined(__NR_sigprocmask) -#define __NR_sigprocmask (__NR_Linux + 126) -#endif - -#if !defined(__NR_create_module) -#define __NR_create_module (__NR_Linux + 127) -#endif - -#if !defined(__NR_init_module) -#define __NR_init_module (__NR_Linux + 128) -#endif - -#if !defined(__NR_delete_module) -#define __NR_delete_module (__NR_Linux + 129) -#endif - -#if !defined(__NR_get_kernel_syms) -#define __NR_get_kernel_syms (__NR_Linux + 130) -#endif - -#if !defined(__NR_quotactl) -#define __NR_quotactl (__NR_Linux + 131) -#endif - -#if !defined(__NR_getpgid) -#define __NR_getpgid (__NR_Linux + 132) -#endif - -#if !defined(__NR_fchdir) -#define __NR_fchdir (__NR_Linux + 133) -#endif - -#if !defined(__NR_bdflush) -#define __NR_bdflush (__NR_Linux + 134) -#endif - -#if !defined(__NR_sysfs) -#define __NR_sysfs (__NR_Linux + 135) -#endif - -#if !defined(__NR_personality) -#define __NR_personality (__NR_Linux + 136) -#endif - -#if !defined(__NR_afs_syscall) -#define __NR_afs_syscall \ - (__NR_Linux + 137) /* Syscall for Andrew File System \ - */ -#endif - -#if !defined(__NR_setfsuid) -#define __NR_setfsuid (__NR_Linux + 138) -#endif - -#if !defined(__NR_setfsgid) -#define __NR_setfsgid (__NR_Linux + 139) -#endif - -#if !defined(__NR__llseek) -#define __NR__llseek (__NR_Linux + 140) -#endif - -#if !defined(__NR_getdents) -#define __NR_getdents (__NR_Linux + 141) -#endif - -#if !defined(__NR__newselect) -#define __NR__newselect (__NR_Linux + 142) -#endif - -#if !defined(__NR_flock) -#define __NR_flock (__NR_Linux + 143) -#endif - -#if !defined(__NR_msync) -#define __NR_msync (__NR_Linux + 144) -#endif - -#if !defined(__NR_readv) -#define __NR_readv (__NR_Linux + 145) -#endif - -#if !defined(__NR_writev) -#define __NR_writev (__NR_Linux + 146) -#endif - -#if !defined(__NR_cacheflush) -#define __NR_cacheflush (__NR_Linux + 147) -#endif - -#if !defined(__NR_cachectl) -#define __NR_cachectl (__NR_Linux + 148) -#endif - -#if !defined(__NR_sysmips) -#define __NR_sysmips (__NR_Linux + 149) -#endif - -#if !defined(__NR_unused150) -#define __NR_unused150 (__NR_Linux + 150) -#endif - -#if !defined(__NR_getsid) -#define __NR_getsid (__NR_Linux + 151) -#endif - -#if !defined(__NR_fdatasync) -#define __NR_fdatasync (__NR_Linux + 152) -#endif - -#if !defined(__NR__sysctl) -#define __NR__sysctl (__NR_Linux + 153) -#endif - -#if !defined(__NR_mlock) -#define __NR_mlock (__NR_Linux + 154) -#endif - -#if !defined(__NR_munlock) -#define __NR_munlock (__NR_Linux + 155) -#endif - -#if !defined(__NR_mlockall) -#define __NR_mlockall (__NR_Linux + 156) -#endif - -#if !defined(__NR_munlockall) -#define __NR_munlockall (__NR_Linux + 157) -#endif - -#if !defined(__NR_sched_setparam) -#define __NR_sched_setparam (__NR_Linux + 158) -#endif - -#if !defined(__NR_sched_getparam) -#define __NR_sched_getparam (__NR_Linux + 159) -#endif - -#if !defined(__NR_sched_setscheduler) -#define __NR_sched_setscheduler (__NR_Linux + 160) -#endif - -#if !defined(__NR_sched_getscheduler) -#define __NR_sched_getscheduler (__NR_Linux + 161) -#endif - -#if !defined(__NR_sched_yield) -#define __NR_sched_yield (__NR_Linux + 162) -#endif - -#if !defined(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_max (__NR_Linux + 163) -#endif - -#if !defined(__NR_sched_get_priority_min) -#define __NR_sched_get_priority_min (__NR_Linux + 164) -#endif - -#if !defined(__NR_sched_rr_get_interval) -#define __NR_sched_rr_get_interval (__NR_Linux + 165) -#endif - -#if !defined(__NR_nanosleep) -#define __NR_nanosleep (__NR_Linux + 166) -#endif - -#if !defined(__NR_mremap) -#define __NR_mremap (__NR_Linux + 167) -#endif - -#if !defined(__NR_accept) -#define __NR_accept (__NR_Linux + 168) -#endif - -#if !defined(__NR_bind) -#define __NR_bind (__NR_Linux + 169) -#endif - -#if !defined(__NR_connect) -#define __NR_connect (__NR_Linux + 170) -#endif - -#if !defined(__NR_getpeername) -#define __NR_getpeername (__NR_Linux + 171) -#endif - -#if !defined(__NR_getsockname) -#define __NR_getsockname (__NR_Linux + 172) -#endif - -#if !defined(__NR_getsockopt) -#define __NR_getsockopt (__NR_Linux + 173) -#endif - -#if !defined(__NR_listen) -#define __NR_listen (__NR_Linux + 174) -#endif - -#if !defined(__NR_recv) -#define __NR_recv (__NR_Linux + 175) -#endif - -#if !defined(__NR_recvfrom) -#define __NR_recvfrom (__NR_Linux + 176) -#endif - -#if !defined(__NR_recvmsg) -#define __NR_recvmsg (__NR_Linux + 177) -#endif - -#if !defined(__NR_send) -#define __NR_send (__NR_Linux + 178) -#endif - -#if !defined(__NR_sendmsg) -#define __NR_sendmsg (__NR_Linux + 179) -#endif - -#if !defined(__NR_sendto) -#define __NR_sendto (__NR_Linux + 180) -#endif - -#if !defined(__NR_setsockopt) -#define __NR_setsockopt (__NR_Linux + 181) -#endif - -#if !defined(__NR_shutdown) -#define __NR_shutdown (__NR_Linux + 182) -#endif - -#if !defined(__NR_socket) -#define __NR_socket (__NR_Linux + 183) -#endif - -#if !defined(__NR_socketpair) -#define __NR_socketpair (__NR_Linux + 184) -#endif - -#if !defined(__NR_setresuid) -#define __NR_setresuid (__NR_Linux + 185) -#endif - -#if !defined(__NR_getresuid) -#define __NR_getresuid (__NR_Linux + 186) -#endif - -#if !defined(__NR_query_module) -#define __NR_query_module (__NR_Linux + 187) -#endif - -#if !defined(__NR_poll) -#define __NR_poll (__NR_Linux + 188) -#endif - -#if !defined(__NR_nfsservctl) -#define __NR_nfsservctl (__NR_Linux + 189) -#endif - -#if !defined(__NR_setresgid) -#define __NR_setresgid (__NR_Linux + 190) -#endif - -#if !defined(__NR_getresgid) -#define __NR_getresgid (__NR_Linux + 191) -#endif - -#if !defined(__NR_prctl) -#define __NR_prctl (__NR_Linux + 192) -#endif - -#if !defined(__NR_rt_sigreturn) -#define __NR_rt_sigreturn (__NR_Linux + 193) -#endif - -#if !defined(__NR_rt_sigaction) -#define __NR_rt_sigaction (__NR_Linux + 194) -#endif - -#if !defined(__NR_rt_sigprocmask) -#define __NR_rt_sigprocmask (__NR_Linux + 195) -#endif - -#if !defined(__NR_rt_sigpending) -#define __NR_rt_sigpending (__NR_Linux + 196) -#endif - -#if !defined(__NR_rt_sigtimedwait) -#define __NR_rt_sigtimedwait (__NR_Linux + 197) -#endif - -#if !defined(__NR_rt_sigqueueinfo) -#define __NR_rt_sigqueueinfo (__NR_Linux + 198) -#endif - -#if !defined(__NR_rt_sigsuspend) -#define __NR_rt_sigsuspend (__NR_Linux + 199) -#endif - -#if !defined(__NR_pread64) -#define __NR_pread64 (__NR_Linux + 200) -#endif - -#if !defined(__NR_pwrite64) -#define __NR_pwrite64 (__NR_Linux + 201) -#endif - -#if !defined(__NR_chown) -#define __NR_chown (__NR_Linux + 202) -#endif - -#if !defined(__NR_getcwd) -#define __NR_getcwd (__NR_Linux + 203) -#endif - -#if !defined(__NR_capget) -#define __NR_capget (__NR_Linux + 204) -#endif - -#if !defined(__NR_capset) -#define __NR_capset (__NR_Linux + 205) -#endif - -#if !defined(__NR_sigaltstack) -#define __NR_sigaltstack (__NR_Linux + 206) -#endif - -#if !defined(__NR_sendfile) -#define __NR_sendfile (__NR_Linux + 207) -#endif - -#if !defined(__NR_getpmsg) -#define __NR_getpmsg (__NR_Linux + 208) -#endif - -#if !defined(__NR_putpmsg) -#define __NR_putpmsg (__NR_Linux + 209) -#endif - -#if !defined(__NR_mmap2) -#define __NR_mmap2 (__NR_Linux + 210) -#endif - -#if !defined(__NR_truncate64) -#define __NR_truncate64 (__NR_Linux + 211) -#endif - -#if !defined(__NR_ftruncate64) -#define __NR_ftruncate64 (__NR_Linux + 212) -#endif - -#if !defined(__NR_stat64) -#define __NR_stat64 (__NR_Linux + 213) -#endif - -#if !defined(__NR_lstat64) -#define __NR_lstat64 (__NR_Linux + 214) -#endif - -#if !defined(__NR_fstat64) -#define __NR_fstat64 (__NR_Linux + 215) -#endif - -#if !defined(__NR_pivot_root) -#define __NR_pivot_root (__NR_Linux + 216) -#endif - -#if !defined(__NR_mincore) -#define __NR_mincore (__NR_Linux + 217) -#endif - -#if !defined(__NR_madvise) -#define __NR_madvise (__NR_Linux + 218) -#endif - -#if !defined(__NR_getdents64) -#define __NR_getdents64 (__NR_Linux + 219) -#endif - -#if !defined(__NR_fcntl64) -#define __NR_fcntl64 (__NR_Linux + 220) -#endif - -#if !defined(__NR_reserved221) -#define __NR_reserved221 (__NR_Linux + 221) -#endif - -#if !defined(__NR_gettid) -#define __NR_gettid (__NR_Linux + 222) -#endif - -#if !defined(__NR_readahead) -#define __NR_readahead (__NR_Linux + 223) -#endif - -#if !defined(__NR_setxattr) -#define __NR_setxattr (__NR_Linux + 224) -#endif - -#if !defined(__NR_lsetxattr) -#define __NR_lsetxattr (__NR_Linux + 225) -#endif - -#if !defined(__NR_fsetxattr) -#define __NR_fsetxattr (__NR_Linux + 226) -#endif - -#if !defined(__NR_getxattr) -#define __NR_getxattr (__NR_Linux + 227) -#endif - -#if !defined(__NR_lgetxattr) -#define __NR_lgetxattr (__NR_Linux + 228) -#endif - -#if !defined(__NR_fgetxattr) -#define __NR_fgetxattr (__NR_Linux + 229) -#endif - -#if !defined(__NR_listxattr) -#define __NR_listxattr (__NR_Linux + 230) -#endif - -#if !defined(__NR_llistxattr) -#define __NR_llistxattr (__NR_Linux + 231) -#endif - -#if !defined(__NR_flistxattr) -#define __NR_flistxattr (__NR_Linux + 232) -#endif - -#if !defined(__NR_removexattr) -#define __NR_removexattr (__NR_Linux + 233) -#endif - -#if !defined(__NR_lremovexattr) -#define __NR_lremovexattr (__NR_Linux + 234) -#endif - -#if !defined(__NR_fremovexattr) -#define __NR_fremovexattr (__NR_Linux + 235) -#endif - -#if !defined(__NR_tkill) -#define __NR_tkill (__NR_Linux + 236) -#endif - -#if !defined(__NR_sendfile64) -#define __NR_sendfile64 (__NR_Linux + 237) -#endif - -#if !defined(__NR_futex) -#define __NR_futex (__NR_Linux + 238) -#endif - -#if !defined(__NR_sched_setaffinity) -#define __NR_sched_setaffinity (__NR_Linux + 239) -#endif - -#if !defined(__NR_sched_getaffinity) -#define __NR_sched_getaffinity (__NR_Linux + 240) -#endif - -#if !defined(__NR_io_setup) -#define __NR_io_setup (__NR_Linux + 241) -#endif - -#if !defined(__NR_io_destroy) -#define __NR_io_destroy (__NR_Linux + 242) -#endif - -#if !defined(__NR_io_getevents) -#define __NR_io_getevents (__NR_Linux + 243) -#endif - -#if !defined(__NR_io_submit) -#define __NR_io_submit (__NR_Linux + 244) -#endif - -#if !defined(__NR_io_cancel) -#define __NR_io_cancel (__NR_Linux + 245) -#endif - -#if !defined(__NR_exit_group) -#define __NR_exit_group (__NR_Linux + 246) -#endif - -#if !defined(__NR_lookup_dcookie) -#define __NR_lookup_dcookie (__NR_Linux + 247) -#endif - -#if !defined(__NR_epoll_create) -#define __NR_epoll_create (__NR_Linux + 248) -#endif - -#if !defined(__NR_epoll_ctl) -#define __NR_epoll_ctl (__NR_Linux + 249) -#endif - -#if !defined(__NR_epoll_wait) -#define __NR_epoll_wait (__NR_Linux + 250) -#endif - -#if !defined(__NR_remap_file_pages) -#define __NR_remap_file_pages (__NR_Linux + 251) -#endif - -#if !defined(__NR_set_tid_address) -#define __NR_set_tid_address (__NR_Linux + 252) -#endif - -#if !defined(__NR_restart_syscall) -#define __NR_restart_syscall (__NR_Linux + 253) -#endif - -#if !defined(__NR_fadvise64) -#define __NR_fadvise64 (__NR_Linux + 254) -#endif - -#if !defined(__NR_statfs64) -#define __NR_statfs64 (__NR_Linux + 255) -#endif - -#if !defined(__NR_fstatfs64) -#define __NR_fstatfs64 (__NR_Linux + 256) -#endif - -#if !defined(__NR_timer_create) -#define __NR_timer_create (__NR_Linux + 257) -#endif - -#if !defined(__NR_timer_settime) -#define __NR_timer_settime (__NR_Linux + 258) -#endif - -#if !defined(__NR_timer_gettime) -#define __NR_timer_gettime (__NR_Linux + 259) -#endif - -#if !defined(__NR_timer_getoverrun) -#define __NR_timer_getoverrun (__NR_Linux + 260) -#endif - -#if !defined(__NR_timer_delete) -#define __NR_timer_delete (__NR_Linux + 261) -#endif - -#if !defined(__NR_clock_settime) -#define __NR_clock_settime (__NR_Linux + 262) -#endif - -#if !defined(__NR_clock_gettime) -#define __NR_clock_gettime (__NR_Linux + 263) -#endif - -#if !defined(__NR_clock_getres) -#define __NR_clock_getres (__NR_Linux + 264) -#endif - -#if !defined(__NR_clock_nanosleep) -#define __NR_clock_nanosleep (__NR_Linux + 265) -#endif - -#if !defined(__NR_tgkill) -#define __NR_tgkill (__NR_Linux + 266) -#endif - -#if !defined(__NR_utimes) -#define __NR_utimes (__NR_Linux + 267) -#endif - -#if !defined(__NR_mbind) -#define __NR_mbind (__NR_Linux + 268) -#endif - -#if !defined(__NR_get_mempolicy) -#define __NR_get_mempolicy (__NR_Linux + 269) -#endif - -#if !defined(__NR_set_mempolicy) -#define __NR_set_mempolicy (__NR_Linux + 270) -#endif - -#if !defined(__NR_mq_open) -#define __NR_mq_open (__NR_Linux + 271) -#endif - -#if !defined(__NR_mq_unlink) -#define __NR_mq_unlink (__NR_Linux + 272) -#endif - -#if !defined(__NR_mq_timedsend) -#define __NR_mq_timedsend (__NR_Linux + 273) -#endif - -#if !defined(__NR_mq_timedreceive) -#define __NR_mq_timedreceive (__NR_Linux + 274) -#endif - -#if !defined(__NR_mq_notify) -#define __NR_mq_notify (__NR_Linux + 275) -#endif - -#if !defined(__NR_mq_getsetattr) -#define __NR_mq_getsetattr (__NR_Linux + 276) -#endif - -#if !defined(__NR_vserver) -#define __NR_vserver (__NR_Linux + 277) -#endif - -#if !defined(__NR_waitid) -#define __NR_waitid (__NR_Linux + 278) -#endif - -/* #define __NR_sys_setaltroot (__NR_Linux + 279) */ - -#if !defined(__NR_add_key) -#define __NR_add_key (__NR_Linux + 280) -#endif - -#if !defined(__NR_request_key) -#define __NR_request_key (__NR_Linux + 281) -#endif - -#if !defined(__NR_keyctl) -#define __NR_keyctl (__NR_Linux + 282) -#endif - -#if !defined(__NR_set_thread_area) -#define __NR_set_thread_area (__NR_Linux + 283) -#endif - -#if !defined(__NR_inotify_init) -#define __NR_inotify_init (__NR_Linux + 284) -#endif - -#if !defined(__NR_inotify_add_watch) -#define __NR_inotify_add_watch (__NR_Linux + 285) -#endif - -#if !defined(__NR_inotify_rm_watch) -#define __NR_inotify_rm_watch (__NR_Linux + 286) -#endif - -#if !defined(__NR_migrate_pages) -#define __NR_migrate_pages (__NR_Linux + 287) -#endif - -#if !defined(__NR_openat) -#define __NR_openat (__NR_Linux + 288) -#endif - -#if !defined(__NR_mkdirat) -#define __NR_mkdirat (__NR_Linux + 289) -#endif - -#if !defined(__NR_mknodat) -#define __NR_mknodat (__NR_Linux + 290) -#endif - -#if !defined(__NR_fchownat) -#define __NR_fchownat (__NR_Linux + 291) -#endif - -#if !defined(__NR_futimesat) -#define __NR_futimesat (__NR_Linux + 292) -#endif - -#if !defined(__NR_fstatat64) -#define __NR_fstatat64 (__NR_Linux + 293) -#endif - -#if !defined(__NR_unlinkat) -#define __NR_unlinkat (__NR_Linux + 294) -#endif - -#if !defined(__NR_renameat) -#define __NR_renameat (__NR_Linux + 295) -#endif - -#if !defined(__NR_linkat) -#define __NR_linkat (__NR_Linux + 296) -#endif - -#if !defined(__NR_symlinkat) -#define __NR_symlinkat (__NR_Linux + 297) -#endif - -#if !defined(__NR_readlinkat) -#define __NR_readlinkat (__NR_Linux + 298) -#endif - -#if !defined(__NR_fchmodat) -#define __NR_fchmodat (__NR_Linux + 299) -#endif - -#if !defined(__NR_faccessat) -#define __NR_faccessat (__NR_Linux + 300) -#endif - -#if !defined(__NR_pselect6) -#define __NR_pselect6 (__NR_Linux + 301) -#endif - -#if !defined(__NR_ppoll) -#define __NR_ppoll (__NR_Linux + 302) -#endif - -#if !defined(__NR_unshare) -#define __NR_unshare (__NR_Linux + 303) -#endif - -#if !defined(__NR_splice) -#define __NR_splice (__NR_Linux + 304) -#endif - -#if !defined(__NR_sync_file_range) -#define __NR_sync_file_range (__NR_Linux + 305) -#endif - -#if !defined(__NR_tee) -#define __NR_tee (__NR_Linux + 306) -#endif - -#if !defined(__NR_vmsplice) -#define __NR_vmsplice (__NR_Linux + 307) -#endif - -#if !defined(__NR_move_pages) -#define __NR_move_pages (__NR_Linux + 308) -#endif - -#if !defined(__NR_set_robust_list) -#define __NR_set_robust_list (__NR_Linux + 309) -#endif - -#if !defined(__NR_get_robust_list) -#define __NR_get_robust_list (__NR_Linux + 310) -#endif - -#if !defined(__NR_kexec_load) -#define __NR_kexec_load (__NR_Linux + 311) -#endif - -#if !defined(__NR_getcpu) -#define __NR_getcpu (__NR_Linux + 312) -#endif - -#if !defined(__NR_epoll_pwait) -#define __NR_epoll_pwait (__NR_Linux + 313) -#endif - -#if !defined(__NR_ioprio_set) -#define __NR_ioprio_set (__NR_Linux + 314) -#endif - -#if !defined(__NR_ioprio_get) -#define __NR_ioprio_get (__NR_Linux + 315) -#endif - -#if !defined(__NR_utimensat) -#define __NR_utimensat (__NR_Linux + 316) -#endif - -#if !defined(__NR_signalfd) -#define __NR_signalfd (__NR_Linux + 317) -#endif - -#if !defined(__NR_timerfd) -#define __NR_timerfd (__NR_Linux + 318) -#endif - -#if !defined(__NR_eventfd) -#define __NR_eventfd (__NR_Linux + 319) -#endif - -#if !defined(__NR_eventfd) -#define __NR_eventfd (__NR_Linux + 320) -#endif - -#if !defined(__NR_timerfd_create) -#define __NR_timerfd_create (__NR_Linux + 321) -#endif - -#if !defined(__NR_timerfd_gettime) -#define __NR_timerfd_gettime (__NR_Linux + 322) -#endif - -#if !defined(__NR_timerfd_settime) -#define __NR_timerfd_settime (__NR_Linux + 323) -#endif - -#if !defined(__NR_signalfd4) -#define __NR_signalfd4 (__NR_Linux + 324) -#endif - -#if !defined(__NR_eventfd2) -#define __NR_eventfd2 (__NR_Linux + 325) -#endif - -#if !defined(__NR_epoll_create1) -#define __NR_epoll_create1 (__NR_Linux + 326) -#endif - -#if !defined(__NR_dup3) -#define __NR_dup3 (__NR_Linux + 327) -#endif - -#if !defined(__NR_pipe2) -#define __NR_pipe2 (__NR_Linux + 328) -#endif - -#if !defined(__NR_inotify_init1) -#define __NR_inotify_init1 (__NR_Linux + 329) -#endif - -#if !defined(__NR_preadv) -#define __NR_preadv (__NR_Linux + 330) -#endif - -#if !defined(__NR_pwritev) -#define __NR_pwritev (__NR_Linux + 331) -#endif - -#if !defined(__NR_rt_tgsigqueueinfo) -#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332) -#endif - -#if !defined(__NR_perf_event_open) -#define __NR_perf_event_open (__NR_Linux + 333) -#endif - -#if !defined(__NR_accept4) -#define __NR_accept4 (__NR_Linux + 334) -#endif - -#if !defined(__NR_recvmmsg) -#define __NR_recvmmsg (__NR_Linux + 335) -#endif - -#if !defined(__NR_fanotify_init) -#define __NR_fanotify_init (__NR_Linux + 336) -#endif - -#if !defined(__NR_fanotify_mark) -#define __NR_fanotify_mark (__NR_Linux + 337) -#endif - -#if !defined(__NR_prlimit64) -#define __NR_prlimit64 (__NR_Linux + 338) -#endif - -#if !defined(__NR_name_to_handle_at) -#define __NR_name_to_handle_at (__NR_Linux + 339) -#endif - -#if !defined(__NR_open_by_handle_at) -#define __NR_open_by_handle_at (__NR_Linux + 340) -#endif - -#if !defined(__NR_clock_adjtime) -#define __NR_clock_adjtime (__NR_Linux + 341) -#endif - -#if !defined(__NR_syncfs) -#define __NR_syncfs (__NR_Linux + 342) -#endif - -#if !defined(__NR_sendmmsg) -#define __NR_sendmmsg (__NR_Linux + 343) -#endif - -#if !defined(__NR_setns) -#define __NR_setns (__NR_Linux + 344) -#endif - -#if !defined(__NR_process_vm_readv) -#define __NR_process_vm_readv (__NR_Linux + 345) -#endif - -#if !defined(__NR_process_vm_writev) -#define __NR_process_vm_writev (__NR_Linux + 346) -#endif - -#if !defined(__NR_kcmp) -#define __NR_kcmp (__NR_Linux + 347) -#endif - -#if !defined(__NR_finit_module) -#define __NR_finit_module (__NR_Linux + 348) -#endif - -#if !defined(__NR_sched_setattr) -#define __NR_sched_setattr (__NR_Linux + 349) -#endif - -#if !defined(__NR_sched_getattr) -#define __NR_sched_getattr (__NR_Linux + 350) -#endif - -#if !defined(__NR_renameat2) -#define __NR_renameat2 (__NR_Linux + 351) -#endif - -#if !defined(__NR_seccomp) -#define __NR_seccomp (__NR_Linux + 352) -#endif - -#if !defined(__NR_getrandom) -#define __NR_getrandom (__NR_Linux + 353) -#endif - -#if !defined(__NR_memfd_create) -#define __NR_memfd_create (__NR_Linux + 354) -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_SYSCALLS_H_ diff --git a/sandbox/linux/system_headers/mips_linux_ucontext.h b/sandbox/linux/system_headers/mips_linux_ucontext.h deleted file mode 100644 index 774bf312ea..0000000000 --- a/sandbox/linux/system_headers/mips_linux_ucontext.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 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_LINUX_SYSTEM_HEADERS_MIPS_LINUX_UCONTEXT_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_UCONTEXT_H_ - -#include <stdint.h> - -// This is mostly copied from breakpad (common/android/include/sys/ucontext.h), -// except we do use sigset_t for uc_sigmask instead of a custom type. -#if !defined(__BIONIC_HAVE_UCONTEXT_T) -// Ensure that 'stack_t' is defined. -#include <asm/signal.h> - -// We also need greg_t for the sandbox, include it in this header as well. -typedef unsigned long greg_t; - -typedef struct { - uint32_t regmask; - uint32_t status; - uint64_t pc; - uint64_t gregs[32]; - uint64_t fpregs[32]; - uint32_t acx; - uint32_t fpc_csr; - uint32_t fpc_eir; - uint32_t used_math; - uint32_t dsp; - uint64_t mdhi; - uint64_t mdlo; - uint32_t hi1; - uint32_t lo1; - uint32_t hi2; - uint32_t lo2; - uint32_t hi3; - uint32_t lo3; -} mcontext_t; - -typedef struct ucontext { - uint32_t uc_flags; - struct ucontext* uc_link; - stack_t uc_stack; - mcontext_t uc_mcontext; - sigset_t uc_sigmask; - // Other fields are not used by Google Breakpad. Don't define them. -} ucontext_t; - -#else -#include <sys/ucontext.h> -#endif // __BIONIC_HAVE_UCONTEXT_T - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_UCONTEXT_H_ diff --git a/sandbox/linux/system_headers/x86_32_linux_syscalls.h b/sandbox/linux/system_headers/x86_32_linux_syscalls.h deleted file mode 100644 index a6afc62d99..0000000000 --- a/sandbox/linux/system_headers/x86_32_linux_syscalls.h +++ /dev/null @@ -1,1426 +0,0 @@ -// Copyright (c) 2012 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. - -// Generated from the Linux kernel's syscall_32.tbl. -#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_X86_32_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_X86_32_LINUX_SYSCALLS_H_ - -#if !defined(__i386__) -#error "Including header on wrong architecture" -#endif - -#if !defined(__NR_restart_syscall) -#define __NR_restart_syscall 0 -#endif - -#if !defined(__NR_exit) -#define __NR_exit 1 -#endif - -#if !defined(__NR_fork) -#define __NR_fork 2 -#endif - -#if !defined(__NR_read) -#define __NR_read 3 -#endif - -#if !defined(__NR_write) -#define __NR_write 4 -#endif - -#if !defined(__NR_open) -#define __NR_open 5 -#endif - -#if !defined(__NR_close) -#define __NR_close 6 -#endif - -#if !defined(__NR_waitpid) -#define __NR_waitpid 7 -#endif - -#if !defined(__NR_creat) -#define __NR_creat 8 -#endif - -#if !defined(__NR_link) -#define __NR_link 9 -#endif - -#if !defined(__NR_unlink) -#define __NR_unlink 10 -#endif - -#if !defined(__NR_execve) -#define __NR_execve 11 -#endif - -#if !defined(__NR_chdir) -#define __NR_chdir 12 -#endif - -#if !defined(__NR_time) -#define __NR_time 13 -#endif - -#if !defined(__NR_mknod) -#define __NR_mknod 14 -#endif - -#if !defined(__NR_chmod) -#define __NR_chmod 15 -#endif - -#if !defined(__NR_lchown) -#define __NR_lchown 16 -#endif - -#if !defined(__NR_break) -#define __NR_break 17 -#endif - -#if !defined(__NR_oldstat) -#define __NR_oldstat 18 -#endif - -#if !defined(__NR_lseek) -#define __NR_lseek 19 -#endif - -#if !defined(__NR_getpid) -#define __NR_getpid 20 -#endif - -#if !defined(__NR_mount) -#define __NR_mount 21 -#endif - -#if !defined(__NR_umount) -#define __NR_umount 22 -#endif - -#if !defined(__NR_setuid) -#define __NR_setuid 23 -#endif - -#if !defined(__NR_getuid) -#define __NR_getuid 24 -#endif - -#if !defined(__NR_stime) -#define __NR_stime 25 -#endif - -#if !defined(__NR_ptrace) -#define __NR_ptrace 26 -#endif - -#if !defined(__NR_alarm) -#define __NR_alarm 27 -#endif - -#if !defined(__NR_oldfstat) -#define __NR_oldfstat 28 -#endif - -#if !defined(__NR_pause) -#define __NR_pause 29 -#endif - -#if !defined(__NR_utime) -#define __NR_utime 30 -#endif - -#if !defined(__NR_stty) -#define __NR_stty 31 -#endif - -#if !defined(__NR_gtty) -#define __NR_gtty 32 -#endif - -#if !defined(__NR_access) -#define __NR_access 33 -#endif - -#if !defined(__NR_nice) -#define __NR_nice 34 -#endif - -#if !defined(__NR_ftime) -#define __NR_ftime 35 -#endif - -#if !defined(__NR_sync) -#define __NR_sync 36 -#endif - -#if !defined(__NR_kill) -#define __NR_kill 37 -#endif - -#if !defined(__NR_rename) -#define __NR_rename 38 -#endif - -#if !defined(__NR_mkdir) -#define __NR_mkdir 39 -#endif - -#if !defined(__NR_rmdir) -#define __NR_rmdir 40 -#endif - -#if !defined(__NR_dup) -#define __NR_dup 41 -#endif - -#if !defined(__NR_pipe) -#define __NR_pipe 42 -#endif - -#if !defined(__NR_times) -#define __NR_times 43 -#endif - -#if !defined(__NR_prof) -#define __NR_prof 44 -#endif - -#if !defined(__NR_brk) -#define __NR_brk 45 -#endif - -#if !defined(__NR_setgid) -#define __NR_setgid 46 -#endif - -#if !defined(__NR_getgid) -#define __NR_getgid 47 -#endif - -#if !defined(__NR_signal) -#define __NR_signal 48 -#endif - -#if !defined(__NR_geteuid) -#define __NR_geteuid 49 -#endif - -#if !defined(__NR_getegid) -#define __NR_getegid 50 -#endif - -#if !defined(__NR_acct) -#define __NR_acct 51 -#endif - -#if !defined(__NR_umount2) -#define __NR_umount2 52 -#endif - -#if !defined(__NR_lock) -#define __NR_lock 53 -#endif - -#if !defined(__NR_ioctl) -#define __NR_ioctl 54 -#endif - -#if !defined(__NR_fcntl) -#define __NR_fcntl 55 -#endif - -#if !defined(__NR_mpx) -#define __NR_mpx 56 -#endif - -#if !defined(__NR_setpgid) -#define __NR_setpgid 57 -#endif - -#if !defined(__NR_ulimit) -#define __NR_ulimit 58 -#endif - -#if !defined(__NR_oldolduname) -#define __NR_oldolduname 59 -#endif - -#if !defined(__NR_umask) -#define __NR_umask 60 -#endif - -#if !defined(__NR_chroot) -#define __NR_chroot 61 -#endif - -#if !defined(__NR_ustat) -#define __NR_ustat 62 -#endif - -#if !defined(__NR_dup2) -#define __NR_dup2 63 -#endif - -#if !defined(__NR_getppid) -#define __NR_getppid 64 -#endif - -#if !defined(__NR_getpgrp) -#define __NR_getpgrp 65 -#endif - -#if !defined(__NR_setsid) -#define __NR_setsid 66 -#endif - -#if !defined(__NR_sigaction) -#define __NR_sigaction 67 -#endif - -#if !defined(__NR_sgetmask) -#define __NR_sgetmask 68 -#endif - -#if !defined(__NR_ssetmask) -#define __NR_ssetmask 69 -#endif - -#if !defined(__NR_setreuid) -#define __NR_setreuid 70 -#endif - -#if !defined(__NR_setregid) -#define __NR_setregid 71 -#endif - -#if !defined(__NR_sigsuspend) -#define __NR_sigsuspend 72 -#endif - -#if !defined(__NR_sigpending) -#define __NR_sigpending 73 -#endif - -#if !defined(__NR_sethostname) -#define __NR_sethostname 74 -#endif - -#if !defined(__NR_setrlimit) -#define __NR_setrlimit 75 -#endif - -#if !defined(__NR_getrlimit) -#define __NR_getrlimit 76 -#endif - -#if !defined(__NR_getrusage) -#define __NR_getrusage 77 -#endif - -#if !defined(__NR_gettimeofday) -#define __NR_gettimeofday 78 -#endif - -#if !defined(__NR_settimeofday) -#define __NR_settimeofday 79 -#endif - -#if !defined(__NR_getgroups) -#define __NR_getgroups 80 -#endif - -#if !defined(__NR_setgroups) -#define __NR_setgroups 81 -#endif - -#if !defined(__NR_select) -#define __NR_select 82 -#endif - -#if !defined(__NR_symlink) -#define __NR_symlink 83 -#endif - -#if !defined(__NR_oldlstat) -#define __NR_oldlstat 84 -#endif - -#if !defined(__NR_readlink) -#define __NR_readlink 85 -#endif - -#if !defined(__NR_uselib) -#define __NR_uselib 86 -#endif - -#if !defined(__NR_swapon) -#define __NR_swapon 87 -#endif - -#if !defined(__NR_reboot) -#define __NR_reboot 88 -#endif - -#if !defined(__NR_readdir) -#define __NR_readdir 89 -#endif - -#if !defined(__NR_mmap) -#define __NR_mmap 90 -#endif - -#if !defined(__NR_munmap) -#define __NR_munmap 91 -#endif - -#if !defined(__NR_truncate) -#define __NR_truncate 92 -#endif - -#if !defined(__NR_ftruncate) -#define __NR_ftruncate 93 -#endif - -#if !defined(__NR_fchmod) -#define __NR_fchmod 94 -#endif - -#if !defined(__NR_fchown) -#define __NR_fchown 95 -#endif - -#if !defined(__NR_getpriority) -#define __NR_getpriority 96 -#endif - -#if !defined(__NR_setpriority) -#define __NR_setpriority 97 -#endif - -#if !defined(__NR_profil) -#define __NR_profil 98 -#endif - -#if !defined(__NR_statfs) -#define __NR_statfs 99 -#endif - -#if !defined(__NR_fstatfs) -#define __NR_fstatfs 100 -#endif - -#if !defined(__NR_ioperm) -#define __NR_ioperm 101 -#endif - -#if !defined(__NR_socketcall) -#define __NR_socketcall 102 -#endif - -#if !defined(__NR_syslog) -#define __NR_syslog 103 -#endif - -#if !defined(__NR_setitimer) -#define __NR_setitimer 104 -#endif - -#if !defined(__NR_getitimer) -#define __NR_getitimer 105 -#endif - -#if !defined(__NR_stat) -#define __NR_stat 106 -#endif - -#if !defined(__NR_lstat) -#define __NR_lstat 107 -#endif - -#if !defined(__NR_fstat) -#define __NR_fstat 108 -#endif - -#if !defined(__NR_olduname) -#define __NR_olduname 109 -#endif - -#if !defined(__NR_iopl) -#define __NR_iopl 110 -#endif - -#if !defined(__NR_vhangup) -#define __NR_vhangup 111 -#endif - -#if !defined(__NR_idle) -#define __NR_idle 112 -#endif - -#if !defined(__NR_vm86old) -#define __NR_vm86old 113 -#endif - -#if !defined(__NR_wait4) -#define __NR_wait4 114 -#endif - -#if !defined(__NR_swapoff) -#define __NR_swapoff 115 -#endif - -#if !defined(__NR_sysinfo) -#define __NR_sysinfo 116 -#endif - -#if !defined(__NR_ipc) -#define __NR_ipc 117 -#endif - -#if !defined(__NR_fsync) -#define __NR_fsync 118 -#endif - -#if !defined(__NR_sigreturn) -#define __NR_sigreturn 119 -#endif - -#if !defined(__NR_clone) -#define __NR_clone 120 -#endif - -#if !defined(__NR_setdomainname) -#define __NR_setdomainname 121 -#endif - -#if !defined(__NR_uname) -#define __NR_uname 122 -#endif - -#if !defined(__NR_modify_ldt) -#define __NR_modify_ldt 123 -#endif - -#if !defined(__NR_adjtimex) -#define __NR_adjtimex 124 -#endif - -#if !defined(__NR_mprotect) -#define __NR_mprotect 125 -#endif - -#if !defined(__NR_sigprocmask) -#define __NR_sigprocmask 126 -#endif - -#if !defined(__NR_create_module) -#define __NR_create_module 127 -#endif - -#if !defined(__NR_init_module) -#define __NR_init_module 128 -#endif - -#if !defined(__NR_delete_module) -#define __NR_delete_module 129 -#endif - -#if !defined(__NR_get_kernel_syms) -#define __NR_get_kernel_syms 130 -#endif - -#if !defined(__NR_quotactl) -#define __NR_quotactl 131 -#endif - -#if !defined(__NR_getpgid) -#define __NR_getpgid 132 -#endif - -#if !defined(__NR_fchdir) -#define __NR_fchdir 133 -#endif - -#if !defined(__NR_bdflush) -#define __NR_bdflush 134 -#endif - -#if !defined(__NR_sysfs) -#define __NR_sysfs 135 -#endif - -#if !defined(__NR_personality) -#define __NR_personality 136 -#endif - -#if !defined(__NR_afs_syscall) -#define __NR_afs_syscall 137 -#endif - -#if !defined(__NR_setfsuid) -#define __NR_setfsuid 138 -#endif - -#if !defined(__NR_setfsgid) -#define __NR_setfsgid 139 -#endif - -#if !defined(__NR__llseek) -#define __NR__llseek 140 -#endif - -#if !defined(__NR_getdents) -#define __NR_getdents 141 -#endif - -#if !defined(__NR__newselect) -#define __NR__newselect 142 -#endif - -#if !defined(__NR_flock) -#define __NR_flock 143 -#endif - -#if !defined(__NR_msync) -#define __NR_msync 144 -#endif - -#if !defined(__NR_readv) -#define __NR_readv 145 -#endif - -#if !defined(__NR_writev) -#define __NR_writev 146 -#endif - -#if !defined(__NR_getsid) -#define __NR_getsid 147 -#endif - -#if !defined(__NR_fdatasync) -#define __NR_fdatasync 148 -#endif - -#if !defined(__NR__sysctl) -#define __NR__sysctl 149 -#endif - -#if !defined(__NR_mlock) -#define __NR_mlock 150 -#endif - -#if !defined(__NR_munlock) -#define __NR_munlock 151 -#endif - -#if !defined(__NR_mlockall) -#define __NR_mlockall 152 -#endif - -#if !defined(__NR_munlockall) -#define __NR_munlockall 153 -#endif - -#if !defined(__NR_sched_setparam) -#define __NR_sched_setparam 154 -#endif - -#if !defined(__NR_sched_getparam) -#define __NR_sched_getparam 155 -#endif - -#if !defined(__NR_sched_setscheduler) -#define __NR_sched_setscheduler 156 -#endif - -#if !defined(__NR_sched_getscheduler) -#define __NR_sched_getscheduler 157 -#endif - -#if !defined(__NR_sched_yield) -#define __NR_sched_yield 158 -#endif - -#if !defined(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_max 159 -#endif - -#if !defined(__NR_sched_get_priority_min) -#define __NR_sched_get_priority_min 160 -#endif - -#if !defined(__NR_sched_rr_get_interval) -#define __NR_sched_rr_get_interval 161 -#endif - -#if !defined(__NR_nanosleep) -#define __NR_nanosleep 162 -#endif - -#if !defined(__NR_mremap) -#define __NR_mremap 163 -#endif - -#if !defined(__NR_setresuid) -#define __NR_setresuid 164 -#endif - -#if !defined(__NR_getresuid) -#define __NR_getresuid 165 -#endif - -#if !defined(__NR_vm86) -#define __NR_vm86 166 -#endif - -#if !defined(__NR_query_module) -#define __NR_query_module 167 -#endif - -#if !defined(__NR_poll) -#define __NR_poll 168 -#endif - -#if !defined(__NR_nfsservctl) -#define __NR_nfsservctl 169 -#endif - -#if !defined(__NR_setresgid) -#define __NR_setresgid 170 -#endif - -#if !defined(__NR_getresgid) -#define __NR_getresgid 171 -#endif - -#if !defined(__NR_prctl) -#define __NR_prctl 172 -#endif - -#if !defined(__NR_rt_sigreturn) -#define __NR_rt_sigreturn 173 -#endif - -#if !defined(__NR_rt_sigaction) -#define __NR_rt_sigaction 174 -#endif - -#if !defined(__NR_rt_sigprocmask) -#define __NR_rt_sigprocmask 175 -#endif - -#if !defined(__NR_rt_sigpending) -#define __NR_rt_sigpending 176 -#endif - -#if !defined(__NR_rt_sigtimedwait) -#define __NR_rt_sigtimedwait 177 -#endif - -#if !defined(__NR_rt_sigqueueinfo) -#define __NR_rt_sigqueueinfo 178 -#endif - -#if !defined(__NR_rt_sigsuspend) -#define __NR_rt_sigsuspend 179 -#endif - -#if !defined(__NR_pread64) -#define __NR_pread64 180 -#endif - -#if !defined(__NR_pwrite64) -#define __NR_pwrite64 181 -#endif - -#if !defined(__NR_chown) -#define __NR_chown 182 -#endif - -#if !defined(__NR_getcwd) -#define __NR_getcwd 183 -#endif - -#if !defined(__NR_capget) -#define __NR_capget 184 -#endif - -#if !defined(__NR_capset) -#define __NR_capset 185 -#endif - -#if !defined(__NR_sigaltstack) -#define __NR_sigaltstack 186 -#endif - -#if !defined(__NR_sendfile) -#define __NR_sendfile 187 -#endif - -#if !defined(__NR_getpmsg) -#define __NR_getpmsg 188 -#endif - -#if !defined(__NR_putpmsg) -#define __NR_putpmsg 189 -#endif - -#if !defined(__NR_vfork) -#define __NR_vfork 190 -#endif - -#if !defined(__NR_ugetrlimit) -#define __NR_ugetrlimit 191 -#endif - -#if !defined(__NR_mmap2) -#define __NR_mmap2 192 -#endif - -#if !defined(__NR_truncate64) -#define __NR_truncate64 193 -#endif - -#if !defined(__NR_ftruncate64) -#define __NR_ftruncate64 194 -#endif - -#if !defined(__NR_stat64) -#define __NR_stat64 195 -#endif - -#if !defined(__NR_lstat64) -#define __NR_lstat64 196 -#endif - -#if !defined(__NR_fstat64) -#define __NR_fstat64 197 -#endif - -#if !defined(__NR_lchown32) -#define __NR_lchown32 198 -#endif - -#if !defined(__NR_getuid32) -#define __NR_getuid32 199 -#endif - -#if !defined(__NR_getgid32) -#define __NR_getgid32 200 -#endif - -#if !defined(__NR_geteuid32) -#define __NR_geteuid32 201 -#endif - -#if !defined(__NR_getegid32) -#define __NR_getegid32 202 -#endif - -#if !defined(__NR_setreuid32) -#define __NR_setreuid32 203 -#endif - -#if !defined(__NR_setregid32) -#define __NR_setregid32 204 -#endif - -#if !defined(__NR_getgroups32) -#define __NR_getgroups32 205 -#endif - -#if !defined(__NR_setgroups32) -#define __NR_setgroups32 206 -#endif - -#if !defined(__NR_fchown32) -#define __NR_fchown32 207 -#endif - -#if !defined(__NR_setresuid32) -#define __NR_setresuid32 208 -#endif - -#if !defined(__NR_getresuid32) -#define __NR_getresuid32 209 -#endif - -#if !defined(__NR_setresgid32) -#define __NR_setresgid32 210 -#endif - -#if !defined(__NR_getresgid32) -#define __NR_getresgid32 211 -#endif - -#if !defined(__NR_chown32) -#define __NR_chown32 212 -#endif - -#if !defined(__NR_setuid32) -#define __NR_setuid32 213 -#endif - -#if !defined(__NR_setgid32) -#define __NR_setgid32 214 -#endif - -#if !defined(__NR_setfsuid32) -#define __NR_setfsuid32 215 -#endif - -#if !defined(__NR_setfsgid32) -#define __NR_setfsgid32 216 -#endif - -#if !defined(__NR_pivot_root) -#define __NR_pivot_root 217 -#endif - -#if !defined(__NR_mincore) -#define __NR_mincore 218 -#endif - -#if !defined(__NR_madvise) -#define __NR_madvise 219 -#endif - -#if !defined(__NR_getdents64) -#define __NR_getdents64 220 -#endif - -#if !defined(__NR_fcntl64) -#define __NR_fcntl64 221 -#endif - -#if !defined(__NR_gettid) -#define __NR_gettid 224 -#endif - -#if !defined(__NR_readahead) -#define __NR_readahead 225 -#endif - -#if !defined(__NR_setxattr) -#define __NR_setxattr 226 -#endif - -#if !defined(__NR_lsetxattr) -#define __NR_lsetxattr 227 -#endif - -#if !defined(__NR_fsetxattr) -#define __NR_fsetxattr 228 -#endif - -#if !defined(__NR_getxattr) -#define __NR_getxattr 229 -#endif - -#if !defined(__NR_lgetxattr) -#define __NR_lgetxattr 230 -#endif - -#if !defined(__NR_fgetxattr) -#define __NR_fgetxattr 231 -#endif - -#if !defined(__NR_listxattr) -#define __NR_listxattr 232 -#endif - -#if !defined(__NR_llistxattr) -#define __NR_llistxattr 233 -#endif - -#if !defined(__NR_flistxattr) -#define __NR_flistxattr 234 -#endif - -#if !defined(__NR_removexattr) -#define __NR_removexattr 235 -#endif - -#if !defined(__NR_lremovexattr) -#define __NR_lremovexattr 236 -#endif - -#if !defined(__NR_fremovexattr) -#define __NR_fremovexattr 237 -#endif - -#if !defined(__NR_tkill) -#define __NR_tkill 238 -#endif - -#if !defined(__NR_sendfile64) -#define __NR_sendfile64 239 -#endif - -#if !defined(__NR_futex) -#define __NR_futex 240 -#endif - -#if !defined(__NR_sched_setaffinity) -#define __NR_sched_setaffinity 241 -#endif - -#if !defined(__NR_sched_getaffinity) -#define __NR_sched_getaffinity 242 -#endif - -#if !defined(__NR_set_thread_area) -#define __NR_set_thread_area 243 -#endif - -#if !defined(__NR_get_thread_area) -#define __NR_get_thread_area 244 -#endif - -#if !defined(__NR_io_setup) -#define __NR_io_setup 245 -#endif - -#if !defined(__NR_io_destroy) -#define __NR_io_destroy 246 -#endif - -#if !defined(__NR_io_getevents) -#define __NR_io_getevents 247 -#endif - -#if !defined(__NR_io_submit) -#define __NR_io_submit 248 -#endif - -#if !defined(__NR_io_cancel) -#define __NR_io_cancel 249 -#endif - -#if !defined(__NR_fadvise64) -#define __NR_fadvise64 250 -#endif - -#if !defined(__NR_exit_group) -#define __NR_exit_group 252 -#endif - -#if !defined(__NR_lookup_dcookie) -#define __NR_lookup_dcookie 253 -#endif - -#if !defined(__NR_epoll_create) -#define __NR_epoll_create 254 -#endif - -#if !defined(__NR_epoll_ctl) -#define __NR_epoll_ctl 255 -#endif - -#if !defined(__NR_epoll_wait) -#define __NR_epoll_wait 256 -#endif - -#if !defined(__NR_remap_file_pages) -#define __NR_remap_file_pages 257 -#endif - -#if !defined(__NR_set_tid_address) -#define __NR_set_tid_address 258 -#endif - -#if !defined(__NR_timer_create) -#define __NR_timer_create 259 -#endif - -#if !defined(__NR_timer_settime) -#define __NR_timer_settime 260 -#endif - -#if !defined(__NR_timer_gettime) -#define __NR_timer_gettime 261 -#endif - -#if !defined(__NR_timer_getoverrun) -#define __NR_timer_getoverrun 262 -#endif - -#if !defined(__NR_timer_delete) -#define __NR_timer_delete 263 -#endif - -#if !defined(__NR_clock_settime) -#define __NR_clock_settime 264 -#endif - -#if !defined(__NR_clock_gettime) -#define __NR_clock_gettime 265 -#endif - -#if !defined(__NR_clock_getres) -#define __NR_clock_getres 266 -#endif - -#if !defined(__NR_clock_nanosleep) -#define __NR_clock_nanosleep 267 -#endif - -#if !defined(__NR_statfs64) -#define __NR_statfs64 268 -#endif - -#if !defined(__NR_fstatfs64) -#define __NR_fstatfs64 269 -#endif - -#if !defined(__NR_tgkill) -#define __NR_tgkill 270 -#endif - -#if !defined(__NR_utimes) -#define __NR_utimes 271 -#endif - -#if !defined(__NR_fadvise64_64) -#define __NR_fadvise64_64 272 -#endif - -#if !defined(__NR_vserver) -#define __NR_vserver 273 -#endif - -#if !defined(__NR_mbind) -#define __NR_mbind 274 -#endif - -#if !defined(__NR_get_mempolicy) -#define __NR_get_mempolicy 275 -#endif - -#if !defined(__NR_set_mempolicy) -#define __NR_set_mempolicy 276 -#endif - -#if !defined(__NR_mq_open) -#define __NR_mq_open 277 -#endif - -#if !defined(__NR_mq_unlink) -#define __NR_mq_unlink 278 -#endif - -#if !defined(__NR_mq_timedsend) -#define __NR_mq_timedsend 279 -#endif - -#if !defined(__NR_mq_timedreceive) -#define __NR_mq_timedreceive 280 -#endif - -#if !defined(__NR_mq_notify) -#define __NR_mq_notify 281 -#endif - -#if !defined(__NR_mq_getsetattr) -#define __NR_mq_getsetattr 282 -#endif - -#if !defined(__NR_kexec_load) -#define __NR_kexec_load 283 -#endif - -#if !defined(__NR_waitid) -#define __NR_waitid 284 -#endif - -#if !defined(__NR_add_key) -#define __NR_add_key 286 -#endif - -#if !defined(__NR_request_key) -#define __NR_request_key 287 -#endif - -#if !defined(__NR_keyctl) -#define __NR_keyctl 288 -#endif - -#if !defined(__NR_ioprio_set) -#define __NR_ioprio_set 289 -#endif - -#if !defined(__NR_ioprio_get) -#define __NR_ioprio_get 290 -#endif - -#if !defined(__NR_inotify_init) -#define __NR_inotify_init 291 -#endif - -#if !defined(__NR_inotify_add_watch) -#define __NR_inotify_add_watch 292 -#endif - -#if !defined(__NR_inotify_rm_watch) -#define __NR_inotify_rm_watch 293 -#endif - -#if !defined(__NR_migrate_pages) -#define __NR_migrate_pages 294 -#endif - -#if !defined(__NR_openat) -#define __NR_openat 295 -#endif - -#if !defined(__NR_mkdirat) -#define __NR_mkdirat 296 -#endif - -#if !defined(__NR_mknodat) -#define __NR_mknodat 297 -#endif - -#if !defined(__NR_fchownat) -#define __NR_fchownat 298 -#endif - -#if !defined(__NR_futimesat) -#define __NR_futimesat 299 -#endif - -#if !defined(__NR_fstatat64) -#define __NR_fstatat64 300 -#endif - -#if !defined(__NR_unlinkat) -#define __NR_unlinkat 301 -#endif - -#if !defined(__NR_renameat) -#define __NR_renameat 302 -#endif - -#if !defined(__NR_linkat) -#define __NR_linkat 303 -#endif - -#if !defined(__NR_symlinkat) -#define __NR_symlinkat 304 -#endif - -#if !defined(__NR_readlinkat) -#define __NR_readlinkat 305 -#endif - -#if !defined(__NR_fchmodat) -#define __NR_fchmodat 306 -#endif - -#if !defined(__NR_faccessat) -#define __NR_faccessat 307 -#endif - -#if !defined(__NR_pselect6) -#define __NR_pselect6 308 -#endif - -#if !defined(__NR_ppoll) -#define __NR_ppoll 309 -#endif - -#if !defined(__NR_unshare) -#define __NR_unshare 310 -#endif - -#if !defined(__NR_set_robust_list) -#define __NR_set_robust_list 311 -#endif - -#if !defined(__NR_get_robust_list) -#define __NR_get_robust_list 312 -#endif - -#if !defined(__NR_splice) -#define __NR_splice 313 -#endif - -#if !defined(__NR_sync_file_range) -#define __NR_sync_file_range 314 -#endif - -#if !defined(__NR_tee) -#define __NR_tee 315 -#endif - -#if !defined(__NR_vmsplice) -#define __NR_vmsplice 316 -#endif - -#if !defined(__NR_move_pages) -#define __NR_move_pages 317 -#endif - -#if !defined(__NR_getcpu) -#define __NR_getcpu 318 -#endif - -#if !defined(__NR_epoll_pwait) -#define __NR_epoll_pwait 319 -#endif - -#if !defined(__NR_utimensat) -#define __NR_utimensat 320 -#endif - -#if !defined(__NR_signalfd) -#define __NR_signalfd 321 -#endif - -#if !defined(__NR_timerfd_create) -#define __NR_timerfd_create 322 -#endif - -#if !defined(__NR_eventfd) -#define __NR_eventfd 323 -#endif - -#if !defined(__NR_fallocate) -#define __NR_fallocate 324 -#endif - -#if !defined(__NR_timerfd_settime) -#define __NR_timerfd_settime 325 -#endif - -#if !defined(__NR_timerfd_gettime) -#define __NR_timerfd_gettime 326 -#endif - -#if !defined(__NR_signalfd4) -#define __NR_signalfd4 327 -#endif - -#if !defined(__NR_eventfd2) -#define __NR_eventfd2 328 -#endif - -#if !defined(__NR_epoll_create1) -#define __NR_epoll_create1 329 -#endif - -#if !defined(__NR_dup3) -#define __NR_dup3 330 -#endif - -#if !defined(__NR_pipe2) -#define __NR_pipe2 331 -#endif - -#if !defined(__NR_inotify_init1) -#define __NR_inotify_init1 332 -#endif - -#if !defined(__NR_preadv) -#define __NR_preadv 333 -#endif - -#if !defined(__NR_pwritev) -#define __NR_pwritev 334 -#endif - -#if !defined(__NR_rt_tgsigqueueinfo) -#define __NR_rt_tgsigqueueinfo 335 -#endif - -#if !defined(__NR_perf_event_open) -#define __NR_perf_event_open 336 -#endif - -#if !defined(__NR_recvmmsg) -#define __NR_recvmmsg 337 -#endif - -#if !defined(__NR_fanotify_init) -#define __NR_fanotify_init 338 -#endif - -#if !defined(__NR_fanotify_mark) -#define __NR_fanotify_mark 339 -#endif - -#if !defined(__NR_prlimit64) -#define __NR_prlimit64 340 -#endif - -#if !defined(__NR_name_to_handle_at) -#define __NR_name_to_handle_at 341 -#endif - -#if !defined(__NR_open_by_handle_at) -#define __NR_open_by_handle_at 342 -#endif - -#if !defined(__NR_clock_adjtime) -#define __NR_clock_adjtime 343 -#endif - -#if !defined(__NR_syncfs) -#define __NR_syncfs 344 -#endif - -#if !defined(__NR_sendmmsg) -#define __NR_sendmmsg 345 -#endif - -#if !defined(__NR_setns) -#define __NR_setns 346 -#endif - -#if !defined(__NR_process_vm_readv) -#define __NR_process_vm_readv 347 -#endif - -#if !defined(__NR_process_vm_writev) -#define __NR_process_vm_writev 348 -#endif - -#if !defined(__NR_kcmp) -#define __NR_kcmp 349 -#endif - -#if !defined(__NR_finit_module) -#define __NR_finit_module 350 -#endif - -#if !defined(__NR_sched_setattr) -#define __NR_sched_setattr 351 -#endif - -#if !defined(__NR_sched_getattr) -#define __NR_sched_getattr 352 -#endif - -#if !defined(__NR_renameat2) -#define __NR_renameat2 353 -#endif - -#if !defined(__NR_seccomp) -#define __NR_seccomp 354 -#endif - -#if !defined(__NR_getrandom) -#define __NR_getrandom 355 -#endif - -#if !defined(__NR_memfd_create) -#define __NR_memfd_create 356 -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_X86_32_LINUX_SYSCALLS_H_ - diff --git a/sandbox/linux/system_headers/x86_64_linux_syscalls.h b/sandbox/linux/system_headers/x86_64_linux_syscalls.h deleted file mode 100644 index 349504aee4..0000000000 --- a/sandbox/linux/system_headers/x86_64_linux_syscalls.h +++ /dev/null @@ -1,1294 +0,0 @@ -// Copyright (c) 2012 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. - -// Generated from the Linux kernel's syscall_64.tbl. -#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_SYSCALLS_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_SYSCALLS_H_ - -#if !defined(__x86_64__) -#error "Including header on wrong architecture" -#endif - -#if !defined(__NR_read) -#define __NR_read 0 -#endif - -#if !defined(__NR_write) -#define __NR_write 1 -#endif - -#if !defined(__NR_open) -#define __NR_open 2 -#endif - -#if !defined(__NR_close) -#define __NR_close 3 -#endif - -#if !defined(__NR_stat) -#define __NR_stat 4 -#endif - -#if !defined(__NR_fstat) -#define __NR_fstat 5 -#endif - -#if !defined(__NR_lstat) -#define __NR_lstat 6 -#endif - -#if !defined(__NR_poll) -#define __NR_poll 7 -#endif - -#if !defined(__NR_lseek) -#define __NR_lseek 8 -#endif - -#if !defined(__NR_mmap) -#define __NR_mmap 9 -#endif - -#if !defined(__NR_mprotect) -#define __NR_mprotect 10 -#endif - -#if !defined(__NR_munmap) -#define __NR_munmap 11 -#endif - -#if !defined(__NR_brk) -#define __NR_brk 12 -#endif - -#if !defined(__NR_rt_sigaction) -#define __NR_rt_sigaction 13 -#endif - -#if !defined(__NR_rt_sigprocmask) -#define __NR_rt_sigprocmask 14 -#endif - -#if !defined(__NR_rt_sigreturn) -#define __NR_rt_sigreturn 15 -#endif - -#if !defined(__NR_ioctl) -#define __NR_ioctl 16 -#endif - -#if !defined(__NR_pread64) -#define __NR_pread64 17 -#endif - -#if !defined(__NR_pwrite64) -#define __NR_pwrite64 18 -#endif - -#if !defined(__NR_readv) -#define __NR_readv 19 -#endif - -#if !defined(__NR_writev) -#define __NR_writev 20 -#endif - -#if !defined(__NR_access) -#define __NR_access 21 -#endif - -#if !defined(__NR_pipe) -#define __NR_pipe 22 -#endif - -#if !defined(__NR_select) -#define __NR_select 23 -#endif - -#if !defined(__NR_sched_yield) -#define __NR_sched_yield 24 -#endif - -#if !defined(__NR_mremap) -#define __NR_mremap 25 -#endif - -#if !defined(__NR_msync) -#define __NR_msync 26 -#endif - -#if !defined(__NR_mincore) -#define __NR_mincore 27 -#endif - -#if !defined(__NR_madvise) -#define __NR_madvise 28 -#endif - -#if !defined(__NR_shmget) -#define __NR_shmget 29 -#endif - -#if !defined(__NR_shmat) -#define __NR_shmat 30 -#endif - -#if !defined(__NR_shmctl) -#define __NR_shmctl 31 -#endif - -#if !defined(__NR_dup) -#define __NR_dup 32 -#endif - -#if !defined(__NR_dup2) -#define __NR_dup2 33 -#endif - -#if !defined(__NR_pause) -#define __NR_pause 34 -#endif - -#if !defined(__NR_nanosleep) -#define __NR_nanosleep 35 -#endif - -#if !defined(__NR_getitimer) -#define __NR_getitimer 36 -#endif - -#if !defined(__NR_alarm) -#define __NR_alarm 37 -#endif - -#if !defined(__NR_setitimer) -#define __NR_setitimer 38 -#endif - -#if !defined(__NR_getpid) -#define __NR_getpid 39 -#endif - -#if !defined(__NR_sendfile) -#define __NR_sendfile 40 -#endif - -#if !defined(__NR_socket) -#define __NR_socket 41 -#endif - -#if !defined(__NR_connect) -#define __NR_connect 42 -#endif - -#if !defined(__NR_accept) -#define __NR_accept 43 -#endif - -#if !defined(__NR_sendto) -#define __NR_sendto 44 -#endif - -#if !defined(__NR_recvfrom) -#define __NR_recvfrom 45 -#endif - -#if !defined(__NR_sendmsg) -#define __NR_sendmsg 46 -#endif - -#if !defined(__NR_recvmsg) -#define __NR_recvmsg 47 -#endif - -#if !defined(__NR_shutdown) -#define __NR_shutdown 48 -#endif - -#if !defined(__NR_bind) -#define __NR_bind 49 -#endif - -#if !defined(__NR_listen) -#define __NR_listen 50 -#endif - -#if !defined(__NR_getsockname) -#define __NR_getsockname 51 -#endif - -#if !defined(__NR_getpeername) -#define __NR_getpeername 52 -#endif - -#if !defined(__NR_socketpair) -#define __NR_socketpair 53 -#endif - -#if !defined(__NR_setsockopt) -#define __NR_setsockopt 54 -#endif - -#if !defined(__NR_getsockopt) -#define __NR_getsockopt 55 -#endif - -#if !defined(__NR_clone) -#define __NR_clone 56 -#endif - -#if !defined(__NR_fork) -#define __NR_fork 57 -#endif - -#if !defined(__NR_vfork) -#define __NR_vfork 58 -#endif - -#if !defined(__NR_execve) -#define __NR_execve 59 -#endif - -#if !defined(__NR_exit) -#define __NR_exit 60 -#endif - -#if !defined(__NR_wait4) -#define __NR_wait4 61 -#endif - -#if !defined(__NR_kill) -#define __NR_kill 62 -#endif - -#if !defined(__NR_uname) -#define __NR_uname 63 -#endif - -#if !defined(__NR_semget) -#define __NR_semget 64 -#endif - -#if !defined(__NR_semop) -#define __NR_semop 65 -#endif - -#if !defined(__NR_semctl) -#define __NR_semctl 66 -#endif - -#if !defined(__NR_shmdt) -#define __NR_shmdt 67 -#endif - -#if !defined(__NR_msgget) -#define __NR_msgget 68 -#endif - -#if !defined(__NR_msgsnd) -#define __NR_msgsnd 69 -#endif - -#if !defined(__NR_msgrcv) -#define __NR_msgrcv 70 -#endif - -#if !defined(__NR_msgctl) -#define __NR_msgctl 71 -#endif - -#if !defined(__NR_fcntl) -#define __NR_fcntl 72 -#endif - -#if !defined(__NR_flock) -#define __NR_flock 73 -#endif - -#if !defined(__NR_fsync) -#define __NR_fsync 74 -#endif - -#if !defined(__NR_fdatasync) -#define __NR_fdatasync 75 -#endif - -#if !defined(__NR_truncate) -#define __NR_truncate 76 -#endif - -#if !defined(__NR_ftruncate) -#define __NR_ftruncate 77 -#endif - -#if !defined(__NR_getdents) -#define __NR_getdents 78 -#endif - -#if !defined(__NR_getcwd) -#define __NR_getcwd 79 -#endif - -#if !defined(__NR_chdir) -#define __NR_chdir 80 -#endif - -#if !defined(__NR_fchdir) -#define __NR_fchdir 81 -#endif - -#if !defined(__NR_rename) -#define __NR_rename 82 -#endif - -#if !defined(__NR_mkdir) -#define __NR_mkdir 83 -#endif - -#if !defined(__NR_rmdir) -#define __NR_rmdir 84 -#endif - -#if !defined(__NR_creat) -#define __NR_creat 85 -#endif - -#if !defined(__NR_link) -#define __NR_link 86 -#endif - -#if !defined(__NR_unlink) -#define __NR_unlink 87 -#endif - -#if !defined(__NR_symlink) -#define __NR_symlink 88 -#endif - -#if !defined(__NR_readlink) -#define __NR_readlink 89 -#endif - -#if !defined(__NR_chmod) -#define __NR_chmod 90 -#endif - -#if !defined(__NR_fchmod) -#define __NR_fchmod 91 -#endif - -#if !defined(__NR_chown) -#define __NR_chown 92 -#endif - -#if !defined(__NR_fchown) -#define __NR_fchown 93 -#endif - -#if !defined(__NR_lchown) -#define __NR_lchown 94 -#endif - -#if !defined(__NR_umask) -#define __NR_umask 95 -#endif - -#if !defined(__NR_gettimeofday) -#define __NR_gettimeofday 96 -#endif - -#if !defined(__NR_getrlimit) -#define __NR_getrlimit 97 -#endif - -#if !defined(__NR_getrusage) -#define __NR_getrusage 98 -#endif - -#if !defined(__NR_sysinfo) -#define __NR_sysinfo 99 -#endif - -#if !defined(__NR_times) -#define __NR_times 100 -#endif - -#if !defined(__NR_ptrace) -#define __NR_ptrace 101 -#endif - -#if !defined(__NR_getuid) -#define __NR_getuid 102 -#endif - -#if !defined(__NR_syslog) -#define __NR_syslog 103 -#endif - -#if !defined(__NR_getgid) -#define __NR_getgid 104 -#endif - -#if !defined(__NR_setuid) -#define __NR_setuid 105 -#endif - -#if !defined(__NR_setgid) -#define __NR_setgid 106 -#endif - -#if !defined(__NR_geteuid) -#define __NR_geteuid 107 -#endif - -#if !defined(__NR_getegid) -#define __NR_getegid 108 -#endif - -#if !defined(__NR_setpgid) -#define __NR_setpgid 109 -#endif - -#if !defined(__NR_getppid) -#define __NR_getppid 110 -#endif - -#if !defined(__NR_getpgrp) -#define __NR_getpgrp 111 -#endif - -#if !defined(__NR_setsid) -#define __NR_setsid 112 -#endif - -#if !defined(__NR_setreuid) -#define __NR_setreuid 113 -#endif - -#if !defined(__NR_setregid) -#define __NR_setregid 114 -#endif - -#if !defined(__NR_getgroups) -#define __NR_getgroups 115 -#endif - -#if !defined(__NR_setgroups) -#define __NR_setgroups 116 -#endif - -#if !defined(__NR_setresuid) -#define __NR_setresuid 117 -#endif - -#if !defined(__NR_getresuid) -#define __NR_getresuid 118 -#endif - -#if !defined(__NR_setresgid) -#define __NR_setresgid 119 -#endif - -#if !defined(__NR_getresgid) -#define __NR_getresgid 120 -#endif - -#if !defined(__NR_getpgid) -#define __NR_getpgid 121 -#endif - -#if !defined(__NR_setfsuid) -#define __NR_setfsuid 122 -#endif - -#if !defined(__NR_setfsgid) -#define __NR_setfsgid 123 -#endif - -#if !defined(__NR_getsid) -#define __NR_getsid 124 -#endif - -#if !defined(__NR_capget) -#define __NR_capget 125 -#endif - -#if !defined(__NR_capset) -#define __NR_capset 126 -#endif - -#if !defined(__NR_rt_sigpending) -#define __NR_rt_sigpending 127 -#endif - -#if !defined(__NR_rt_sigtimedwait) -#define __NR_rt_sigtimedwait 128 -#endif - -#if !defined(__NR_rt_sigqueueinfo) -#define __NR_rt_sigqueueinfo 129 -#endif - -#if !defined(__NR_rt_sigsuspend) -#define __NR_rt_sigsuspend 130 -#endif - -#if !defined(__NR_sigaltstack) -#define __NR_sigaltstack 131 -#endif - -#if !defined(__NR_utime) -#define __NR_utime 132 -#endif - -#if !defined(__NR_mknod) -#define __NR_mknod 133 -#endif - -#if !defined(__NR_uselib) -#define __NR_uselib 134 -#endif - -#if !defined(__NR_personality) -#define __NR_personality 135 -#endif - -#if !defined(__NR_ustat) -#define __NR_ustat 136 -#endif - -#if !defined(__NR_statfs) -#define __NR_statfs 137 -#endif - -#if !defined(__NR_fstatfs) -#define __NR_fstatfs 138 -#endif - -#if !defined(__NR_sysfs) -#define __NR_sysfs 139 -#endif - -#if !defined(__NR_getpriority) -#define __NR_getpriority 140 -#endif - -#if !defined(__NR_setpriority) -#define __NR_setpriority 141 -#endif - -#if !defined(__NR_sched_setparam) -#define __NR_sched_setparam 142 -#endif - -#if !defined(__NR_sched_getparam) -#define __NR_sched_getparam 143 -#endif - -#if !defined(__NR_sched_setscheduler) -#define __NR_sched_setscheduler 144 -#endif - -#if !defined(__NR_sched_getscheduler) -#define __NR_sched_getscheduler 145 -#endif - -#if !defined(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_max 146 -#endif - -#if !defined(__NR_sched_get_priority_min) -#define __NR_sched_get_priority_min 147 -#endif - -#if !defined(__NR_sched_rr_get_interval) -#define __NR_sched_rr_get_interval 148 -#endif - -#if !defined(__NR_mlock) -#define __NR_mlock 149 -#endif - -#if !defined(__NR_munlock) -#define __NR_munlock 150 -#endif - -#if !defined(__NR_mlockall) -#define __NR_mlockall 151 -#endif - -#if !defined(__NR_munlockall) -#define __NR_munlockall 152 -#endif - -#if !defined(__NR_vhangup) -#define __NR_vhangup 153 -#endif - -#if !defined(__NR_modify_ldt) -#define __NR_modify_ldt 154 -#endif - -#if !defined(__NR_pivot_root) -#define __NR_pivot_root 155 -#endif - -#if !defined(__NR__sysctl) -#define __NR__sysctl 156 -#endif - -#if !defined(__NR_prctl) -#define __NR_prctl 157 -#endif - -#if !defined(__NR_arch_prctl) -#define __NR_arch_prctl 158 -#endif - -#if !defined(__NR_adjtimex) -#define __NR_adjtimex 159 -#endif - -#if !defined(__NR_setrlimit) -#define __NR_setrlimit 160 -#endif - -#if !defined(__NR_chroot) -#define __NR_chroot 161 -#endif - -#if !defined(__NR_sync) -#define __NR_sync 162 -#endif - -#if !defined(__NR_acct) -#define __NR_acct 163 -#endif - -#if !defined(__NR_settimeofday) -#define __NR_settimeofday 164 -#endif - -#if !defined(__NR_mount) -#define __NR_mount 165 -#endif - -#if !defined(__NR_umount2) -#define __NR_umount2 166 -#endif - -#if !defined(__NR_swapon) -#define __NR_swapon 167 -#endif - -#if !defined(__NR_swapoff) -#define __NR_swapoff 168 -#endif - -#if !defined(__NR_reboot) -#define __NR_reboot 169 -#endif - -#if !defined(__NR_sethostname) -#define __NR_sethostname 170 -#endif - -#if !defined(__NR_setdomainname) -#define __NR_setdomainname 171 -#endif - -#if !defined(__NR_iopl) -#define __NR_iopl 172 -#endif - -#if !defined(__NR_ioperm) -#define __NR_ioperm 173 -#endif - -#if !defined(__NR_create_module) -#define __NR_create_module 174 -#endif - -#if !defined(__NR_init_module) -#define __NR_init_module 175 -#endif - -#if !defined(__NR_delete_module) -#define __NR_delete_module 176 -#endif - -#if !defined(__NR_get_kernel_syms) -#define __NR_get_kernel_syms 177 -#endif - -#if !defined(__NR_query_module) -#define __NR_query_module 178 -#endif - -#if !defined(__NR_quotactl) -#define __NR_quotactl 179 -#endif - -#if !defined(__NR_nfsservctl) -#define __NR_nfsservctl 180 -#endif - -#if !defined(__NR_getpmsg) -#define __NR_getpmsg 181 -#endif - -#if !defined(__NR_putpmsg) -#define __NR_putpmsg 182 -#endif - -#if !defined(__NR_afs_syscall) -#define __NR_afs_syscall 183 -#endif - -#if !defined(__NR_tuxcall) -#define __NR_tuxcall 184 -#endif - -#if !defined(__NR_security) -#define __NR_security 185 -#endif - -#if !defined(__NR_gettid) -#define __NR_gettid 186 -#endif - -#if !defined(__NR_readahead) -#define __NR_readahead 187 -#endif - -#if !defined(__NR_setxattr) -#define __NR_setxattr 188 -#endif - -#if !defined(__NR_lsetxattr) -#define __NR_lsetxattr 189 -#endif - -#if !defined(__NR_fsetxattr) -#define __NR_fsetxattr 190 -#endif - -#if !defined(__NR_getxattr) -#define __NR_getxattr 191 -#endif - -#if !defined(__NR_lgetxattr) -#define __NR_lgetxattr 192 -#endif - -#if !defined(__NR_fgetxattr) -#define __NR_fgetxattr 193 -#endif - -#if !defined(__NR_listxattr) -#define __NR_listxattr 194 -#endif - -#if !defined(__NR_llistxattr) -#define __NR_llistxattr 195 -#endif - -#if !defined(__NR_flistxattr) -#define __NR_flistxattr 196 -#endif - -#if !defined(__NR_removexattr) -#define __NR_removexattr 197 -#endif - -#if !defined(__NR_lremovexattr) -#define __NR_lremovexattr 198 -#endif - -#if !defined(__NR_fremovexattr) -#define __NR_fremovexattr 199 -#endif - -#if !defined(__NR_tkill) -#define __NR_tkill 200 -#endif - -#if !defined(__NR_time) -#define __NR_time 201 -#endif - -#if !defined(__NR_futex) -#define __NR_futex 202 -#endif - -#if !defined(__NR_sched_setaffinity) -#define __NR_sched_setaffinity 203 -#endif - -#if !defined(__NR_sched_getaffinity) -#define __NR_sched_getaffinity 204 -#endif - -#if !defined(__NR_set_thread_area) -#define __NR_set_thread_area 205 -#endif - -#if !defined(__NR_io_setup) -#define __NR_io_setup 206 -#endif - -#if !defined(__NR_io_destroy) -#define __NR_io_destroy 207 -#endif - -#if !defined(__NR_io_getevents) -#define __NR_io_getevents 208 -#endif - -#if !defined(__NR_io_submit) -#define __NR_io_submit 209 -#endif - -#if !defined(__NR_io_cancel) -#define __NR_io_cancel 210 -#endif - -#if !defined(__NR_get_thread_area) -#define __NR_get_thread_area 211 -#endif - -#if !defined(__NR_lookup_dcookie) -#define __NR_lookup_dcookie 212 -#endif - -#if !defined(__NR_epoll_create) -#define __NR_epoll_create 213 -#endif - -#if !defined(__NR_epoll_ctl_old) -#define __NR_epoll_ctl_old 214 -#endif - -#if !defined(__NR_epoll_wait_old) -#define __NR_epoll_wait_old 215 -#endif - -#if !defined(__NR_remap_file_pages) -#define __NR_remap_file_pages 216 -#endif - -#if !defined(__NR_getdents64) -#define __NR_getdents64 217 -#endif - -#if !defined(__NR_set_tid_address) -#define __NR_set_tid_address 218 -#endif - -#if !defined(__NR_restart_syscall) -#define __NR_restart_syscall 219 -#endif - -#if !defined(__NR_semtimedop) -#define __NR_semtimedop 220 -#endif - -#if !defined(__NR_fadvise64) -#define __NR_fadvise64 221 -#endif - -#if !defined(__NR_timer_create) -#define __NR_timer_create 222 -#endif - -#if !defined(__NR_timer_settime) -#define __NR_timer_settime 223 -#endif - -#if !defined(__NR_timer_gettime) -#define __NR_timer_gettime 224 -#endif - -#if !defined(__NR_timer_getoverrun) -#define __NR_timer_getoverrun 225 -#endif - -#if !defined(__NR_timer_delete) -#define __NR_timer_delete 226 -#endif - -#if !defined(__NR_clock_settime) -#define __NR_clock_settime 227 -#endif - -#if !defined(__NR_clock_gettime) -#define __NR_clock_gettime 228 -#endif - -#if !defined(__NR_clock_getres) -#define __NR_clock_getres 229 -#endif - -#if !defined(__NR_clock_nanosleep) -#define __NR_clock_nanosleep 230 -#endif - -#if !defined(__NR_exit_group) -#define __NR_exit_group 231 -#endif - -#if !defined(__NR_epoll_wait) -#define __NR_epoll_wait 232 -#endif - -#if !defined(__NR_epoll_ctl) -#define __NR_epoll_ctl 233 -#endif - -#if !defined(__NR_tgkill) -#define __NR_tgkill 234 -#endif - -#if !defined(__NR_utimes) -#define __NR_utimes 235 -#endif - -#if !defined(__NR_vserver) -#define __NR_vserver 236 -#endif - -#if !defined(__NR_mbind) -#define __NR_mbind 237 -#endif - -#if !defined(__NR_set_mempolicy) -#define __NR_set_mempolicy 238 -#endif - -#if !defined(__NR_get_mempolicy) -#define __NR_get_mempolicy 239 -#endif - -#if !defined(__NR_mq_open) -#define __NR_mq_open 240 -#endif - -#if !defined(__NR_mq_unlink) -#define __NR_mq_unlink 241 -#endif - -#if !defined(__NR_mq_timedsend) -#define __NR_mq_timedsend 242 -#endif - -#if !defined(__NR_mq_timedreceive) -#define __NR_mq_timedreceive 243 -#endif - -#if !defined(__NR_mq_notify) -#define __NR_mq_notify 244 -#endif - -#if !defined(__NR_mq_getsetattr) -#define __NR_mq_getsetattr 245 -#endif - -#if !defined(__NR_kexec_load) -#define __NR_kexec_load 246 -#endif - -#if !defined(__NR_waitid) -#define __NR_waitid 247 -#endif - -#if !defined(__NR_add_key) -#define __NR_add_key 248 -#endif - -#if !defined(__NR_request_key) -#define __NR_request_key 249 -#endif - -#if !defined(__NR_keyctl) -#define __NR_keyctl 250 -#endif - -#if !defined(__NR_ioprio_set) -#define __NR_ioprio_set 251 -#endif - -#if !defined(__NR_ioprio_get) -#define __NR_ioprio_get 252 -#endif - -#if !defined(__NR_inotify_init) -#define __NR_inotify_init 253 -#endif - -#if !defined(__NR_inotify_add_watch) -#define __NR_inotify_add_watch 254 -#endif - -#if !defined(__NR_inotify_rm_watch) -#define __NR_inotify_rm_watch 255 -#endif - -#if !defined(__NR_migrate_pages) -#define __NR_migrate_pages 256 -#endif - -#if !defined(__NR_openat) -#define __NR_openat 257 -#endif - -#if !defined(__NR_mkdirat) -#define __NR_mkdirat 258 -#endif - -#if !defined(__NR_mknodat) -#define __NR_mknodat 259 -#endif - -#if !defined(__NR_fchownat) -#define __NR_fchownat 260 -#endif - -#if !defined(__NR_futimesat) -#define __NR_futimesat 261 -#endif - -#if !defined(__NR_newfstatat) -#define __NR_newfstatat 262 -#endif - -#if !defined(__NR_unlinkat) -#define __NR_unlinkat 263 -#endif - -#if !defined(__NR_renameat) -#define __NR_renameat 264 -#endif - -#if !defined(__NR_linkat) -#define __NR_linkat 265 -#endif - -#if !defined(__NR_symlinkat) -#define __NR_symlinkat 266 -#endif - -#if !defined(__NR_readlinkat) -#define __NR_readlinkat 267 -#endif - -#if !defined(__NR_fchmodat) -#define __NR_fchmodat 268 -#endif - -#if !defined(__NR_faccessat) -#define __NR_faccessat 269 -#endif - -#if !defined(__NR_pselect6) -#define __NR_pselect6 270 -#endif - -#if !defined(__NR_ppoll) -#define __NR_ppoll 271 -#endif - -#if !defined(__NR_unshare) -#define __NR_unshare 272 -#endif - -#if !defined(__NR_set_robust_list) -#define __NR_set_robust_list 273 -#endif - -#if !defined(__NR_get_robust_list) -#define __NR_get_robust_list 274 -#endif - -#if !defined(__NR_splice) -#define __NR_splice 275 -#endif - -#if !defined(__NR_tee) -#define __NR_tee 276 -#endif - -#if !defined(__NR_sync_file_range) -#define __NR_sync_file_range 277 -#endif - -#if !defined(__NR_vmsplice) -#define __NR_vmsplice 278 -#endif - -#if !defined(__NR_move_pages) -#define __NR_move_pages 279 -#endif - -#if !defined(__NR_utimensat) -#define __NR_utimensat 280 -#endif - -#if !defined(__NR_epoll_pwait) -#define __NR_epoll_pwait 281 -#endif - -#if !defined(__NR_signalfd) -#define __NR_signalfd 282 -#endif - -#if !defined(__NR_timerfd_create) -#define __NR_timerfd_create 283 -#endif - -#if !defined(__NR_eventfd) -#define __NR_eventfd 284 -#endif - -#if !defined(__NR_fallocate) -#define __NR_fallocate 285 -#endif - -#if !defined(__NR_timerfd_settime) -#define __NR_timerfd_settime 286 -#endif - -#if !defined(__NR_timerfd_gettime) -#define __NR_timerfd_gettime 287 -#endif - -#if !defined(__NR_accept4) -#define __NR_accept4 288 -#endif - -#if !defined(__NR_signalfd4) -#define __NR_signalfd4 289 -#endif - -#if !defined(__NR_eventfd2) -#define __NR_eventfd2 290 -#endif - -#if !defined(__NR_epoll_create1) -#define __NR_epoll_create1 291 -#endif - -#if !defined(__NR_dup3) -#define __NR_dup3 292 -#endif - -#if !defined(__NR_pipe2) -#define __NR_pipe2 293 -#endif - -#if !defined(__NR_inotify_init1) -#define __NR_inotify_init1 294 -#endif - -#if !defined(__NR_preadv) -#define __NR_preadv 295 -#endif - -#if !defined(__NR_pwritev) -#define __NR_pwritev 296 -#endif - -#if !defined(__NR_rt_tgsigqueueinfo) -#define __NR_rt_tgsigqueueinfo 297 -#endif - -#if !defined(__NR_perf_event_open) -#define __NR_perf_event_open 298 -#endif - -#if !defined(__NR_recvmmsg) -#define __NR_recvmmsg 299 -#endif - -#if !defined(__NR_fanotify_init) -#define __NR_fanotify_init 300 -#endif - -#if !defined(__NR_fanotify_mark) -#define __NR_fanotify_mark 301 -#endif - -#if !defined(__NR_prlimit64) -#define __NR_prlimit64 302 -#endif - -#if !defined(__NR_name_to_handle_at) -#define __NR_name_to_handle_at 303 -#endif - -#if !defined(__NR_open_by_handle_at) -#define __NR_open_by_handle_at 304 -#endif - -#if !defined(__NR_clock_adjtime) -#define __NR_clock_adjtime 305 -#endif - -#if !defined(__NR_syncfs) -#define __NR_syncfs 306 -#endif - -#if !defined(__NR_sendmmsg) -#define __NR_sendmmsg 307 -#endif - -#if !defined(__NR_setns) -#define __NR_setns 308 -#endif - -#if !defined(__NR_getcpu) -#define __NR_getcpu 309 -#endif - -#if !defined(__NR_process_vm_readv) -#define __NR_process_vm_readv 310 -#endif - -#if !defined(__NR_process_vm_writev) -#define __NR_process_vm_writev 311 -#endif - -#if !defined(__NR_kcmp) -#define __NR_kcmp 312 -#endif - -#if !defined(__NR_finit_module) -#define __NR_finit_module 313 -#endif - -#if !defined(__NR_sched_setattr) -#define __NR_sched_setattr 314 -#endif - -#if !defined(__NR_sched_getattr) -#define __NR_sched_getattr 315 -#endif - -#if !defined(__NR_renameat2) -#define __NR_renameat2 316 -#endif - -#if !defined(__NR_seccomp) -#define __NR_seccomp 317 -#endif - -#if !defined(__NR_getrandom) -#define __NR_getrandom 318 -#endif - -#if !defined(__NR_memfd_create) -#define __NR_memfd_create 319 -#endif - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_SYSCALLS_H_ - diff --git a/sandbox/linux/system_headers/x86_64_linux_ucontext.h b/sandbox/linux/system_headers/x86_64_linux_ucontext.h deleted file mode 100644 index 1f1abe642f..0000000000 --- a/sandbox/linux/system_headers/x86_64_linux_ucontext.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2014 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_LINUX_SYSTEM_HEADERS_X86_64_LINUX_UCONTEXT_H_ -#define SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_UCONTEXT_H_ - -#include <stdint.h> - -// We do something compatible with glibc. Hopefully, at some point Android will -// provide that for us, and __BIONIC_HAVE_UCONTEXT_T should be defined. -// Spec: -// http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/libc-ddefs.html#AEN5668 - -#if !defined(__BIONIC_HAVE_UCONTEXT_T) -#include <asm/sigcontext.h> - -struct _libc_fpxreg { - unsigned short significand[4]; - unsigned short exponent; - unsigned short padding[3]; -}; - -struct _libc_xmmreg { - uint32_t element[4]; -}; - -struct _libc_fpstate { - uint16_t cwd; - uint16_t swd; - uint16_t twd; - uint16_t fop; - uint64_t rip; - uint64_t rdp; - uint32_t mxcsr; - uint32_t mxcsr_mask; - struct _libc_fpxreg _st[8]; - struct _libc_xmmreg _xmm[16]; - uint32_t padding[24]; -}; - -typedef uint64_t greg_t; - -typedef struct { - greg_t gregs[23]; - struct _libc_fpstate* fpregs; - unsigned long __reserved1[8]; -} mcontext_t; - -enum { - REG_R8 = 0, - REG_R9, - REG_R10, - REG_R11, - REG_R12, - REG_R13, - REG_R14, - REG_R15, - REG_RDI, - REG_RSI, - REG_RBP, - REG_RBX, - REG_RDX, - REG_RAX, - REG_RCX, - REG_RSP, - REG_RIP, - REG_EFL, - REG_CSGSFS, - REG_ERR, - REG_TRAPNO, - REG_OLDMASK, - REG_CR2, - NGREG, -}; - -typedef struct ucontext { - unsigned long uc_flags; - struct ucontext* uc_link; - stack_t uc_stack; - mcontext_t uc_mcontext; - sigset_t uc_sigmask; - struct _libc_fpstate __fpregs_mem; -} ucontext_t; - -#else -#include <sys/ucontext.h> -#endif // __BIONIC_HAVE_UCONTEXT_T - -#endif // SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_UCONTEXT_H_ diff --git a/sandbox/mac/BUILD.gn b/sandbox/mac/BUILD.gn deleted file mode 100644 index 5174b54f81..0000000000 --- a/sandbox/mac/BUILD.gn +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2014 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. - -import("//build/config/mac/mac_sdk.gni") -import("//testing/test.gni") - -component("sandbox") { - sources = [ - "bootstrap_sandbox.cc", - "bootstrap_sandbox.h", - "launchd_interception_server.cc", - "launchd_interception_server.h", - "mach_message_server.cc", - "mach_message_server.h", - "message_server.h", - "os_compatibility.cc", - "os_compatibility.h", - "policy.cc", - "policy.h", - "pre_exec_delegate.cc", - "pre_exec_delegate.h", - "xpc.h", - "xpc_message_server.cc", - "xpc_message_server.h", - ] - - defines = [ "SANDBOX_IMPLEMENTATION" ] - libs = [ "bsm" ] - - deps = [ - "//base", - ] -} - -component("seatbelt") { - sources = [ - "sandbox_compiler.cc", - "sandbox_compiler.h", - "seatbelt.cc", - "seatbelt.h", - "seatbelt_export.h", - ] - libs = [ "sandbox" ] - defines = [ "SEATBELT_IMPLEMENTATION" ] -} - -test("sandbox_mac_unittests") { - sources = [ - "bootstrap_sandbox_unittest.mm", - "policy_unittest.cc", - "sandbox_mac_compiler_unittest.mm", - "sandbox_mac_compiler_v2_unittest.mm", - "xpc_message_server_unittest.cc", - ] - - libs = [ - "CoreFoundation.framework", - "Foundation.framework", - ] - - deps = [ - ":sandbox", - ":seatbelt", - "//base", - "//base/test:run_all_unittests", - "//testing/gtest", - ] -} diff --git a/sandbox/mac/message_server.h b/sandbox/mac/message_server.h deleted file mode 100644 index 6ee119bd5e..0000000000 --- a/sandbox/mac/message_server.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2014 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_MESSAGE_SERVER_H_ -#define SANDBOX_MAC_MESSAGE_SERVER_H_ - -#include <mach/mach.h> -#include <unistd.h> - -#include "sandbox/mac/xpc.h" - -namespace sandbox { - -// A message received by a MessageServer. Each concrete implementation of -// that interface will handle the fields of this union appropriately. -// Consumers should treat this as an opaque handle. -union IPCMessage { - mach_msg_header_t* mach; - xpc_object_t xpc; -}; - -// A delegate interface for MessageServer that handles processing of -// incoming intercepted IPC messages. -class MessageDemuxer { - public: - // Handle a |request| message. The message is owned by the server. Use the - // server's methods to create and send a reply message. - virtual void DemuxMessage(IPCMessage request) = 0; - - protected: - virtual ~MessageDemuxer() {} -}; - -// An interaface for an IPC server that implements Mach messaging semantics. -// The concrete implementation may be powered by raw Mach messages, XPC, or -// some other technology. This interface is the abstraction on top of those -// that enables message interception. -class MessageServer { - public: - virtual ~MessageServer() {} - - // Initializes the class and starts running the message server. If this - // returns false, no other methods may be called on this class. - virtual bool Initialize() = 0; - - // Blocks the calling thread while the server shuts down. This prevents - // the server from receiving new messages. After this method is called, - // no other methods may be called on this class. - virtual void Shutdown() = 0; - - // Given a received request message, returns the PID of the sending process. - virtual pid_t GetMessageSenderPID(IPCMessage request) = 0; - - // Creates a reply message from a request message. The result is owned by - // the server. - virtual IPCMessage CreateReply(IPCMessage request) = 0; - - // Sends a reply message. Returns true if the message was sent successfully. - virtual bool SendReply(IPCMessage reply) = 0; - - // Forwards the original |request| to the |destination| for handling. - virtual void ForwardMessage(IPCMessage request, mach_port_t destination) = 0; - - // Replies to the received |request| message by creating a reply and setting - // the specified |error_code| in a field that is interpreted by the - // underlying IPC system. - virtual void RejectMessage(IPCMessage request, int error_code) = 0; - - // Returns the Mach port on which the MessageServer is listening. - virtual mach_port_t GetServerPort() const = 0; -}; - -} // namespace sandbox - -#endif // SANDBOX_MAC_MESSAGE_SERVER_H_ diff --git a/sandbox/sandbox_export.h b/sandbox/sandbox_export.h deleted file mode 100644 index 35d6a1ba26..0000000000 --- a/sandbox/sandbox_export.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2014 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_SANDBOX_EXPORT_H_ -#define SANDBOX_SANDBOX_EXPORT_H_ - -#if defined(WIN32) -#error "sandbox_export.h does not support WIN32." -#endif - -#if defined(COMPONENT_BUILD) - -#if defined(SANDBOX_IMPLEMENTATION) -#define SANDBOX_EXPORT __attribute__((visibility("default"))) -#else -#define SANDBOX_EXPORT -#endif // defined(SANDBOX_IMPLEMENTATION) - -#else // defined(COMPONENT_BUILD) - -#define SANDBOX_EXPORT - -#endif // defined(COMPONENT_BUILD) - -#endif // SANDBOX_SANDBOX_EXPORT_H_ diff --git a/sandbox/win/BUILD.gn b/sandbox/win/BUILD.gn deleted file mode 100644 index 1d51220c5a..0000000000 --- a/sandbox/win/BUILD.gn +++ /dev/null @@ -1,329 +0,0 @@ -# Copyright 2014 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. - -import("//testing/test.gni") - -# This needs to be a static library rather than a sources set because small -# portions of this are used in some contexts (like chrome_elf), and it -# doesnn't seem to dead-code strip very well. This saves 12K on chrome_elf.dll, -# over a source set, for example. -static_library("sandbox") { - sources = [ - "src/acl.cc", - "src/acl.h", - "src/broker_services.cc", - "src/broker_services.h", - "src/crosscall_client.h", - "src/crosscall_params.h", - "src/crosscall_server.cc", - "src/crosscall_server.h", - "src/eat_resolver.cc", - "src/eat_resolver.h", - "src/filesystem_dispatcher.cc", - "src/filesystem_dispatcher.h", - "src/filesystem_interception.cc", - "src/filesystem_interception.h", - "src/filesystem_policy.cc", - "src/filesystem_policy.h", - "src/handle_closer.cc", - "src/handle_closer.h", - "src/handle_closer_agent.cc", - "src/handle_closer_agent.h", - "src/interception.cc", - "src/interception.h", - "src/interception_agent.cc", - "src/interception_agent.h", - "src/interception_internal.h", - "src/interceptors.h", - "src/internal_types.h", - "src/ipc_tags.h", - "src/job.cc", - "src/job.h", - "src/named_pipe_dispatcher.cc", - "src/named_pipe_dispatcher.h", - "src/named_pipe_interception.cc", - "src/named_pipe_interception.h", - "src/named_pipe_policy.cc", - "src/named_pipe_policy.h", - "src/nt_internals.h", - "src/policy_broker.cc", - "src/policy_broker.h", - "src/policy_engine_opcodes.cc", - "src/policy_engine_opcodes.h", - "src/policy_engine_params.h", - "src/policy_engine_processor.cc", - "src/policy_engine_processor.h", - "src/policy_low_level.cc", - "src/policy_low_level.h", - "src/policy_params.h", - "src/policy_target.cc", - "src/policy_target.h", - "src/process_mitigations.cc", - "src/process_mitigations.h", - "src/process_mitigations_win32k_dispatcher.cc", - "src/process_mitigations_win32k_dispatcher.h", - "src/process_mitigations_win32k_interception.cc", - "src/process_mitigations_win32k_interception.h", - "src/process_mitigations_win32k_policy.cc", - "src/process_mitigations_win32k_policy.h", - "src/process_thread_dispatcher.cc", - "src/process_thread_dispatcher.h", - "src/process_thread_interception.cc", - "src/process_thread_interception.h", - "src/process_thread_policy.cc", - "src/process_thread_policy.h", - "src/registry_dispatcher.cc", - "src/registry_dispatcher.h", - "src/registry_interception.cc", - "src/registry_interception.h", - "src/registry_policy.cc", - "src/registry_policy.h", - "src/resolver.cc", - "src/resolver.h", - "src/restricted_token.cc", - "src/restricted_token.h", - "src/restricted_token_utils.cc", - "src/restricted_token_utils.h", - "src/sandbox.cc", - "src/sandbox.h", - "src/sandbox_factory.h", - "src/sandbox_globals.cc", - "src/sandbox_nt_types.h", - "src/sandbox_nt_util.cc", - "src/sandbox_nt_util.h", - "src/sandbox_policy.h", - "src/sandbox_policy_base.cc", - "src/sandbox_policy_base.h", - "src/sandbox_rand.cc", - "src/sandbox_rand.h", - "src/sandbox_types.h", - "src/sandbox_utils.cc", - "src/sandbox_utils.h", - "src/security_level.h", - "src/service_resolver.cc", - "src/service_resolver.h", - "src/sharedmem_ipc_client.cc", - "src/sharedmem_ipc_client.h", - "src/sharedmem_ipc_server.cc", - "src/sharedmem_ipc_server.h", - "src/sid.cc", - "src/sid.h", - "src/sync_dispatcher.cc", - "src/sync_dispatcher.h", - "src/sync_interception.cc", - "src/sync_interception.h", - "src/sync_policy.cc", - "src/sync_policy.h", - "src/target_interceptions.cc", - "src/target_interceptions.h", - "src/target_process.cc", - "src/target_process.h", - "src/target_services.cc", - "src/target_services.h", - "src/top_level_dispatcher.cc", - "src/top_level_dispatcher.h", - "src/win2k_threadpool.cc", - "src/win2k_threadpool.h", - "src/win_utils.cc", - "src/win_utils.h", - "src/window.cc", - "src/window.h", - ] - - if (current_cpu == "x64") { - sources += [ - "src/interceptors_64.cc", - "src/interceptors_64.h", - "src/resolver_64.cc", - "src/service_resolver_64.cc", - ] - } else if (current_cpu == "x86") { - sources += [ - "src/resolver_32.cc", - "src/service_resolver_32.cc", - "src/sidestep/ia32_modrm_map.cpp", - "src/sidestep/ia32_opcode_map.cpp", - "src/sidestep/mini_disassembler.cpp", - "src/sidestep/mini_disassembler.h", - "src/sidestep/mini_disassembler_types.h", - "src/sidestep/preamble_patcher.h", - "src/sidestep/preamble_patcher_with_stub.cpp", - "src/sidestep_resolver.cc", - "src/sidestep_resolver.h", - ] - } - - # Disable sanitizer coverage in the sandbox code. The sandbox code runs before - # sanitizer coverage can initialize. http://crbug.com/484711 - configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ] - configs += - [ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ] - - configs += [ "//build/config:precompiled_headers" ] - - deps = [ - "//base", - "//base:base_static", - ] -} - -test("sbox_integration_tests") { - sources = [ - "src/address_sanitizer_test.cc", - "src/app_container_test.cc", - "src/file_policy_test.cc", - "src/handle_closer_test.cc", - "src/handle_inheritance_test.cc", - "src/integrity_level_test.cc", - "src/ipc_ping_test.cc", - "src/lpc_policy_test.cc", - "src/named_pipe_policy_test.cc", - "src/policy_target_test.cc", - "src/process_mitigations_test.cc", - "src/process_policy_test.cc", - "src/registry_policy_test.cc", - "src/restricted_token_test.cc", - "src/sync_policy_test.cc", - "src/sync_policy_test.h", - "src/unload_dll_test.cc", - "tests/common/controller.cc", - "tests/common/controller.h", - "tests/common/test_utils.cc", - "tests/common/test_utils.h", - "tests/integration_tests/cfi_unittest.cc", - "tests/integration_tests/integration_tests.cc", - "tests/integration_tests/integration_tests_common.h", - "tests/integration_tests/integration_tests_test.cc", - ] - - deps = [ - ":sandbox", - "//base/test:test_support", - "//testing/gtest", - ] - - data_deps = [ - ":cfi_unittest_exe", - ":sbox_integration_test_hook_dll", - ":sbox_integration_test_win_proc", - ] - - libs = [ "dxva2.lib" ] -} - -executable("cfi_unittest_exe") { - sources = [ - "tests/integration_tests/cfi_unittest_exe.cc", - ] - deps = [ - "//base", - "//build/config/sanitizers:deps", - "//build/win:default_exe_manifest", - ] -} - -loadable_module("sbox_integration_test_hook_dll") { - sources = [ - "tests/integration_tests/hooking_dll.cc", - "tests/integration_tests/integration_tests_common.h", - ] -} - -executable("sbox_integration_test_win_proc") { - sources = [ - "tests/integration_tests/hooking_win_proc.cc", - "tests/integration_tests/integration_tests_common.h", - ] - - configs -= [ "//build/config/win:console" ] - configs += [ "//build/config/win:windowed" ] -} - -test("sbox_validation_tests") { - sources = [ - "tests/common/controller.cc", - "tests/common/controller.h", - "tests/validation_tests/commands.cc", - "tests/validation_tests/commands.h", - "tests/validation_tests/suite.cc", - "tests/validation_tests/unit_tests.cc", - ] - - deps = [ - ":sandbox", - "//base/test:test_support", - "//testing/gtest", - ] - - libs = [ "shlwapi.lib" ] -} - -test("sbox_unittests") { - sources = [ - "src/interception_unittest.cc", - "src/ipc_unittest.cc", - "src/job_unittest.cc", - "src/policy_engine_unittest.cc", - "src/policy_low_level_unittest.cc", - "src/policy_opcodes_unittest.cc", - "src/restricted_token_unittest.cc", - "src/sandbox_nt_util_unittest.cc", - "src/service_resolver_unittest.cc", - "src/sid_unittest.cc", - "src/threadpool_unittest.cc", - "src/win_utils_unittest.cc", - "tests/common/test_utils.cc", - "tests/common/test_utils.h", - "tests/unit_tests/unit_tests.cc", - ] - - deps = [ - ":sandbox", - "//base/test:test_support", - "//testing/gtest", - ] -} - -test("sandbox_poc") { - sources = [ - "sandbox_poc/main_ui_window.cc", - "sandbox_poc/main_ui_window.h", - "sandbox_poc/resource.h", - "sandbox_poc/sandbox.cc", - "sandbox_poc/sandbox.h", - "sandbox_poc/sandbox.ico", - "sandbox_poc/sandbox.rc", - ] - - configs -= [ "//build/config/win:console" ] - configs += [ "//build/config/win:windowed" ] - - libs = [ "comctl32.lib" ] - - deps = [ - ":pocdll", - ":sandbox", - ] -} - -shared_library("pocdll") { - sources = [ - "sandbox_poc/pocdll/exports.h", - "sandbox_poc/pocdll/fs.cc", - "sandbox_poc/pocdll/handles.cc", - "sandbox_poc/pocdll/invasive.cc", - "sandbox_poc/pocdll/network.cc", - "sandbox_poc/pocdll/pocdll.cc", - "sandbox_poc/pocdll/processes_and_threads.cc", - "sandbox_poc/pocdll/registry.cc", - "sandbox_poc/pocdll/spyware.cc", - "sandbox_poc/pocdll/utils.h", - ] - - defines = [ "POCDLL_EXPORTS" ] - - deps = [ - "//build/config/sanitizers:deps", - ] -} diff --git a/sandbox/win/sandbox_poc/pocdll/exports.h b/sandbox/win/sandbox_poc/pocdll/exports.h deleted file mode 100644 index 66a07d6b78..0000000000 --- a/sandbox/win/sandbox_poc/pocdll/exports.h +++ /dev/null @@ -1,89 +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_SANDBOX_POC_POCDLL_EXPORTS_H__ -#define SANDBOX_SANDBOX_POC_POCDLL_EXPORTS_H__ - -#include <windows.h> - -#ifdef POCDLL_EXPORTS -#define POCDLL_API __declspec(dllexport) __cdecl -#else -#define POCDLL_API __declspec(dllimport) __cdecl -#endif - -extern "C" { -// Tries to open several known system path and outputs -// the result. -// "log" is the handle of the log file. -void POCDLL_API TestFileSystem(HANDLE log); - -// Tries to find all handles open in the process and prints the name of the -// resource references by the handle along with the access right. -// "log" is the handle of the log file. -void POCDLL_API TestGetHandle(HANDLE log); - -// Creates a lot of threads until it cannot create more. The goal of this -// function is to determine if it's possible to crash the machine when we -// flood the machine with new threads -// "log" is the handle of the log file. -void POCDLL_API TestThreadBombing(HANDLE log); - -// Takes all cpu of the machine. For each processor on the machine we assign -// a thread. This thread will compute a mathematical expression over and over -// to take all cpu. -// "log" is the handle of the log file. -// Note: here we are using the affinity to find out how many processors are on -// the machine and to force a thread to run only on a given processor. -void POCDLL_API TestTakeAllCpu(HANDLE log); - -// Creates memory in the heap until it fails 5 times in a row and prints the -// amount of memory created. This function is used to find out if it's possible -// to take all memory on the machine and crash the system. -// "log" is the handle of the log file. -void POCDLL_API TestUseAllMemory(HANDLE log); - -// Creates millions of kernel objects. This function is used to find out if it's -// possible to crash the system if we create too many kernel objects and if we -// hold too many handles. All those kernel objects are unnamed. -// "log" is the handle of the log file. -void POCDLL_API TestCreateObjects(HANDLE log); - -// Receives a hwnd and tries to close it. This is the callback for EnumWindows. -// It will be called for each window(hwnd) on the system. -// "log" is the handle of the log file. -// Always returns TRUE to tell the system that we want to continue the -// enumeration. -void POCDLL_API TestCloseHWND(HANDLE log); - -// Tries to listen on the port 88. -// "log" is the handle of the log file. -void POCDLL_API TestNetworkListen(HANDLE log); - -// Lists all processes on the system and tries to open them -// "log" is the handle of the log file. -void POCDLL_API TestProcesses(HANDLE log); - -// Lists all threads on the system and tries to open them -// "log" is the handle of the log file. -void POCDLL_API TestThreads(HANDLE log); - -// Tries to open some known system registry key and outputs the result. -// "log" is the handle of the log file. -void POCDLL_API TestRegistry(HANDLE log); - -// Records all keystrokes typed for 15 seconds and then display them. -// "log" is the handle of the log file. -void POCDLL_API TestSpyKeys(HANDLE log); - -// Tries to read pixels on the monitor and output if the operation -// failes or succeeded. -// "log" is the handle of the log file. -void POCDLL_API TestSpyScreen(HANDLE log); - -// Runs all tests except those who are invasive -void POCDLL_API Run(HANDLE log); -} - -#endif // SANDBOX_SANDBOX_POC_POCDLL_EXPORTS_H__ diff --git a/sandbox/win/sandbox_poc/pocdll/pocdll.vcproj b/sandbox/win/sandbox_poc/pocdll/pocdll.vcproj deleted file mode 100644 index 8e4e31fc6a..0000000000 --- a/sandbox/win/sandbox_poc/pocdll/pocdll.vcproj +++ /dev/null @@ -1,218 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="pocdll" - ProjectGUID="{AE5BFB87-850E-4454-B01D-58E7D8BAC224}" - RootNamespace="pocdll" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - ConfigurationType="2" - 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" - PreprocessorDefinitions="POCDLL_EXPORTS" - UsePrecompiledHeader="2" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - ModuleDefinitionFile="" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - EmbedManifest="false" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - ConfigurationType="2" - 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" - PreprocessorDefinitions="POCDLL_EXPORTS" - UsePrecompiledHeader="0" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - ModuleDefinitionFile="" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - EmbedManifest="false" - /> - <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=".\exports.h" - > - </File> - <File - RelativePath=".\fs.cc" - > - </File> - <File - RelativePath=".\handles.cc" - > - </File> - <File - RelativePath=".\invasive.cc" - > - </File> - <File - RelativePath=".\network.cc" - > - </File> - <File - RelativePath=".\pocdll.cc" - > - </File> - <File - RelativePath=".\processes_and_threads.cc" - > - </File> - <File - RelativePath=".\registry.cc" - > - </File> - <File - RelativePath=".\spyware.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> - <File - RelativePath=".\utils.h" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/sandbox/win/sandbox_poc/pocdll/utils.h b/sandbox/win/sandbox_poc/pocdll/utils.h deleted file mode 100644 index 0a6ad377fd..0000000000 --- a/sandbox/win/sandbox_poc/pocdll/utils.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2010 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_SANDBOX_POC_POCDLL_UTILS_H__ -#define SANDBOX_SANDBOX_POC_POCDLL_UTILS_H__ - -#include <stdio.h> -#include <io.h> - -#include "base/macros.h" - -// Class to convert a HANDLE to a FILE *. The FILE * is closed when the -// object goes out of scope -class HandleToFile { - public: - HandleToFile() { - file_ = NULL; - }; - - // Note: c_file_handle_ does not need to be closed because fclose does it. - ~HandleToFile() { - if (file_) { - fflush(file_); - fclose(file_); - } - }; - - // Translates a HANDLE (handle) to a FILE * opened with the mode "mode". - // The return value is the FILE * or NULL if there is an error. - FILE* Translate(HANDLE handle, const char *mode) { - if (file_) { - return NULL; - } - - HANDLE new_handle; - BOOL result = ::DuplicateHandle(::GetCurrentProcess(), - handle, - ::GetCurrentProcess(), - &new_handle, - 0, // Don't ask for a specific - // desired access. - FALSE, // Not inheritable. - DUPLICATE_SAME_ACCESS); - - if (!result) { - return NULL; - } - - int c_file_handle = _open_osfhandle(reinterpret_cast<LONG_PTR>(new_handle), - 0); // No flags - if (-1 == c_file_handle) { - return NULL; - } - - file_ = _fdopen(c_file_handle, mode); - return file_; - }; - private: - // the FILE* returned. We need to closed it at the end. - FILE* file_; - - DISALLOW_COPY_AND_ASSIGN(HandleToFile); -}; - -#endif // SANDBOX_SANDBOX_POC_POCDLL_UTILS_H__ diff --git a/sandbox/win/sandbox_poc/resource.h b/sandbox/win/sandbox_poc/resource.h deleted file mode 100644 index 87ff920ca4..0000000000 --- a/sandbox/win/sandbox_poc/resource.h +++ /dev/null @@ -1,30 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by sandbox.rc -// -#define IDI_SANDBOX 107 -#define IDR_MENU_MAIN_UI 129 -#define IDD_LAUNCH_DLL 130 -#define IDC_RADIO_POCDLL 1000 -#define IDC_RADIO_CUSTOM_DLL 1001 -#define IDC_DLL_NAME 1002 -#define IDC_ENTRY_POINT 1003 -#define IDC_LOG_FILE 1004 -#define IDC_BROWSE_DLL 1005 -#define IDC_BROWSE_LOG 1006 -#define ID_FILE_EXIT 32771 -#define ID_COMMANDS_LAUNCHDLL 32772 -#define ID_COMMANDS_SPAWNTARGET 32773 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32774 -#define _APS_NEXT_CONTROL_VALUE 1007 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/sandbox/win/sandbox_poc/sandbox.ico b/sandbox/win/sandbox_poc/sandbox.ico Binary files differdeleted file mode 100644 index 916fa12fc2..0000000000 --- a/sandbox/win/sandbox_poc/sandbox.ico +++ /dev/null diff --git a/sandbox/win/sandbox_poc/sandbox.rc b/sandbox/win/sandbox_poc/sandbox.rc deleted file mode 100644 index 978c96f6f2..0000000000 --- a/sandbox/win/sandbox_poc/sandbox.rc +++ /dev/null @@ -1,136 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU_MAIN_UI MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "E&xit", ID_FILE_EXIT - END - POPUP "&Commands" - BEGIN - MENUITEM "&Spawn target", ID_COMMANDS_SPAWNTARGET - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_LAUNCH_DLL DIALOGEX 0, 0, 269, 118 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "BrokerUI: Load an Attack DLL" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "Call now",IDOK,212,70,50,14 - PUSHBUTTON "Cancel",IDCANCEL,212,95,50,14 - EDITTEXT IDC_DLL_NAME,7,43,200,13,ES_AUTOHSCROLL - LTEXT "DLL to load in target:",IDC_STATIC,7,33,168,8 - LTEXT "Function to call:",IDC_STATIC,7,61,139,8 - EDITTEXT IDC_ENTRY_POINT,7,71,200,13,ES_AUTOHSCROLL - EDITTEXT IDC_LOG_FILE,7,17,200,13,ES_AUTOHSCROLL - LTEXT "File for Target logging (optional):",IDC_STATIC,7,7,139,8 - PUSHBUTTON "Browse...",IDC_BROWSE_DLL,212,42,50,14 - PUSHBUTTON "Browse...",IDC_BROWSE_LOG,212,16,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_LAUNCH_DLL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 262 - TOPMARGIN, 7 - BOTTOMMARGIN, 111 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_SANDBOX ICON "sandbox.ico" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/sandbox/win/sandbox_poc/sandbox_poc.vcproj b/sandbox/win/sandbox_poc/sandbox_poc.vcproj deleted file mode 100644 index 5fde1cd407..0000000000 --- a/sandbox/win/sandbox_poc/sandbox_poc.vcproj +++ /dev/null @@ -1,202 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="sandbox_poc" - ProjectGUID="{CF757839-F2A1-417C-8F25-DCAE480020F1}" - RootNamespace="sandbox_poc" - 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" - AdditionalDependencies="comctl32.lib" - /> - <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" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="comctl32.lib" - /> - <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=".\main_ui_window.cc" - > - </File> - <File - RelativePath=".\main_ui_window.h" - > - </File> - <File - RelativePath=".\resource.h" - > - </File> - <File - RelativePath=".\sandbox.cc" - > - </File> - <File - RelativePath=".\sandbox.h" - > - </File> - <File - RelativePath=".\sandbox.ico" - > - </File> - <File - RelativePath=".\sandbox.rc" - > - </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/sandbox/win/sandbox_standalone.sln b/sandbox/win/sandbox_standalone.sln deleted file mode 100644 index 529d20e09e..0000000000 --- a/sandbox/win/sandbox_standalone.sln +++ /dev/null @@ -1,127 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox", "src\sandbox.vcproj", "{881F6A97-D539-4C48-B401-DF04385B2343}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sbox_unittests", "tests\unit_tests\sbox_unittests.vcproj", "{883553BE-2A9D-418C-A121-61FE1DFBC562}" - ProjectSection(ProjectDependencies) = postProject - {1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165} - {881F6A97-D539-4C48-B401-DF04385B2343} = {881F6A97-D539-4C48-B401-DF04385B2343} - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F7A3B82E-B8B4-4FDF-BC8E-FEC9398F57ED}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sbox_validation_tests", "tests\validation_tests\sbox_validation_tests.vcproj", "{B9CC7B0D-145A-49C2-B887-84E43CFA0F27}" - ProjectSection(ProjectDependencies) = postProject - {1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165} - {881F6A97-D539-4C48-B401-DF04385B2343} = {881F6A97-D539-4C48-B401-DF04385B2343} - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{BCE54389-D18D-48B9-977E-9D1998200F63}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_message", "..\base\debug_message.vcproj", "{F0F92189-193A-6607-C2BB-0F98BBD19ADF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{7F36EE20-5016-4051-B0D7-42824CDA0291}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "proof_of_concept", "proof_of_concept", "{B607BE7B-3555-422C-A40B-28E73C0B5E24}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox_poc", "sandbox_poc\sandbox_poc.vcproj", "{CF757839-F2A1-417C-8F25-DCAE480020F1}" - ProjectSection(ProjectDependencies) = postProject - {1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165} - {881F6A97-D539-4C48-B401-DF04385B2343} = {881F6A97-D539-4C48-B401-DF04385B2343} - {AE5BFB87-850E-4454-B01D-58E7D8BAC224} = {AE5BFB87-850E-4454-B01D-58E7D8BAC224} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pocdll", "sandbox_poc\pocdll\pocdll.vcproj", "{AE5BFB87-850E-4454-B01D-58E7D8BAC224}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "finder", "tools\finder\finder.vcproj", "{ACDC2E06-0366-41A4-A646-C37E130A605D}" - ProjectSection(ProjectDependencies) = postProject - {1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165} - {881F6A97-D539-4C48-B401-DF04385B2343} = {881F6A97-D539-4C48-B401-DF04385B2343} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launcher", "tools\launcher\launcher.vcproj", "{386FA217-FBC2-4461-882D-CDAD221ED800}" - ProjectSection(ProjectDependencies) = postProject - {1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165} - {881F6A97-D539-4C48-B401-DF04385B2343} = {881F6A97-D539-4C48-B401-DF04385B2343} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sbox_integration_tests", "tests\integration_tests\sbox_integration_tests.vcproj", "{542D4B3B-98D4-4233-B68D-0103891508C6}" - ProjectSection(ProjectDependencies) = postProject - {1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165} - {881F6A97-D539-4C48-B401-DF04385B2343} = {881F6A97-D539-4C48-B401-DF04385B2343} - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "..\base\base.vcproj", "{1832A374-8A74-4F9E-B536-69A699B3E165}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\testing\gtest.vcproj", "{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {881F6A97-D539-4C48-B401-DF04385B2343}.Debug|Win32.ActiveCfg = Debug|Win32 - {881F6A97-D539-4C48-B401-DF04385B2343}.Debug|Win32.Build.0 = Debug|Win32 - {881F6A97-D539-4C48-B401-DF04385B2343}.Release|Win32.ActiveCfg = Release|Win32 - {881F6A97-D539-4C48-B401-DF04385B2343}.Release|Win32.Build.0 = Release|Win32 - {883553BE-2A9D-418C-A121-61FE1DFBC562}.Debug|Win32.ActiveCfg = Debug|Win32 - {883553BE-2A9D-418C-A121-61FE1DFBC562}.Debug|Win32.Build.0 = Debug|Win32 - {883553BE-2A9D-418C-A121-61FE1DFBC562}.Release|Win32.ActiveCfg = Release|Win32 - {883553BE-2A9D-418C-A121-61FE1DFBC562}.Release|Win32.Build.0 = Release|Win32 - {B9CC7B0D-145A-49C2-B887-84E43CFA0F27}.Debug|Win32.ActiveCfg = Debug|Win32 - {B9CC7B0D-145A-49C2-B887-84E43CFA0F27}.Debug|Win32.Build.0 = Debug|Win32 - {B9CC7B0D-145A-49C2-B887-84E43CFA0F27}.Release|Win32.ActiveCfg = Release|Win32 - {B9CC7B0D-145A-49C2-B887-84E43CFA0F27}.Release|Win32.Build.0 = Release|Win32 - {F0F92189-193A-6607-C2BB-0F98BBD19ADF}.Debug|Win32.ActiveCfg = Debug|Win32 - {F0F92189-193A-6607-C2BB-0F98BBD19ADF}.Debug|Win32.Build.0 = Debug|Win32 - {F0F92189-193A-6607-C2BB-0F98BBD19ADF}.Release|Win32.ActiveCfg = Release|Win32 - {F0F92189-193A-6607-C2BB-0F98BBD19ADF}.Release|Win32.Build.0 = Release|Win32 - {CF757839-F2A1-417C-8F25-DCAE480020F1}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF757839-F2A1-417C-8F25-DCAE480020F1}.Debug|Win32.Build.0 = Debug|Win32 - {CF757839-F2A1-417C-8F25-DCAE480020F1}.Release|Win32.ActiveCfg = Release|Win32 - {CF757839-F2A1-417C-8F25-DCAE480020F1}.Release|Win32.Build.0 = Release|Win32 - {AE5BFB87-850E-4454-B01D-58E7D8BAC224}.Debug|Win32.ActiveCfg = Debug|Win32 - {AE5BFB87-850E-4454-B01D-58E7D8BAC224}.Debug|Win32.Build.0 = Debug|Win32 - {AE5BFB87-850E-4454-B01D-58E7D8BAC224}.Release|Win32.ActiveCfg = Release|Win32 - {AE5BFB87-850E-4454-B01D-58E7D8BAC224}.Release|Win32.Build.0 = Release|Win32 - {ACDC2E06-0366-41A4-A646-C37E130A605D}.Debug|Win32.ActiveCfg = Debug|Win32 - {ACDC2E06-0366-41A4-A646-C37E130A605D}.Debug|Win32.Build.0 = Debug|Win32 - {ACDC2E06-0366-41A4-A646-C37E130A605D}.Release|Win32.ActiveCfg = Release|Win32 - {ACDC2E06-0366-41A4-A646-C37E130A605D}.Release|Win32.Build.0 = Release|Win32 - {386FA217-FBC2-4461-882D-CDAD221ED800}.Debug|Win32.ActiveCfg = Debug|Win32 - {386FA217-FBC2-4461-882D-CDAD221ED800}.Debug|Win32.Build.0 = Debug|Win32 - {386FA217-FBC2-4461-882D-CDAD221ED800}.Release|Win32.ActiveCfg = Release|Win32 - {386FA217-FBC2-4461-882D-CDAD221ED800}.Release|Win32.Build.0 = Release|Win32 - {542D4B3B-98D4-4233-B68D-0103891508C6}.Debug|Win32.ActiveCfg = Debug|Win32 - {542D4B3B-98D4-4233-B68D-0103891508C6}.Debug|Win32.Build.0 = Debug|Win32 - {542D4B3B-98D4-4233-B68D-0103891508C6}.Release|Win32.ActiveCfg = Release|Win32 - {542D4B3B-98D4-4233-B68D-0103891508C6}.Release|Win32.Build.0 = Release|Win32 - {1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Win32.ActiveCfg = Debug|Win32 - {1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Win32.Build.0 = Debug|Win32 - {1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Win32.ActiveCfg = Release|Win32 - {1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Win32.Build.0 = Release|Win32 - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Debug|Win32.ActiveCfg = Debug|Win32 - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Debug|Win32.Build.0 = Debug|Win32 - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Release|Win32.ActiveCfg = Release|Win32 - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {883553BE-2A9D-418C-A121-61FE1DFBC562} = {F7A3B82E-B8B4-4FDF-BC8E-FEC9398F57ED} - {B9CC7B0D-145A-49C2-B887-84E43CFA0F27} = {F7A3B82E-B8B4-4FDF-BC8E-FEC9398F57ED} - {542D4B3B-98D4-4233-B68D-0103891508C6} = {F7A3B82E-B8B4-4FDF-BC8E-FEC9398F57ED} - {F0F92189-193A-6607-C2BB-0F98BBD19ADF} = {BCE54389-D18D-48B9-977E-9D1998200F63} - {1832A374-8A74-4F9E-B536-69A699B3E165} = {BCE54389-D18D-48B9-977E-9D1998200F63} - {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BCE54389-D18D-48B9-977E-9D1998200F63} - {ACDC2E06-0366-41A4-A646-C37E130A605D} = {7F36EE20-5016-4051-B0D7-42824CDA0291} - {386FA217-FBC2-4461-882D-CDAD221ED800} = {7F36EE20-5016-4051-B0D7-42824CDA0291} - {CF757839-F2A1-417C-8F25-DCAE480020F1} = {B607BE7B-3555-422C-A40B-28E73C0B5E24} - {AE5BFB87-850E-4454-B01D-58E7D8BAC224} = {B607BE7B-3555-422C-A40B-28E73C0B5E24} - EndGlobalSection -EndGlobal diff --git a/sandbox/win/src/crosscall_client.h b/sandbox/win/src/crosscall_client.h deleted file mode 100644 index 60ff2437a0..0000000000 --- a/sandbox/win/src/crosscall_client.h +++ /dev/null @@ -1,526 +0,0 @@ -// Copyright (c) 2012 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_SRC_CROSSCALL_CLIENT_H_ -#define SANDBOX_SRC_CROSSCALL_CLIENT_H_ - -#include <stddef.h> -#include <stdint.h> - -#include "sandbox/win/src/crosscall_params.h" -#include "sandbox/win/src/sandbox.h" - -// This header defines the CrossCall(..) family of templated functions -// Their purpose is to simulate the syntax of regular call but to generate -// and IPC from the client-side. -// -// The basic pattern is to -// 1) use template argument deduction to compute the size of each -// parameter and the appropriate copy method -// 2) pack the parameters in the appropriate ActualCallParams< > object -// 3) call the IPC interface IPCProvider::DoCall( ) -// -// The general interface of CrossCall is: -// ResultCode CrossCall(IPCProvider& ipc_provider, -// uint32_t tag, -// const Par1& p1, const Par2& p2,...pn -// CrossCallReturn* answer) -// -// where: -// ipc_provider: is a specific implementation of the ipc transport see -// sharedmem_ipc_server.h for an example. -// tag : is the unique id for this IPC call. Is used to route the call to -// the appropriate service. -// p1, p2,.. pn : The input parameters of the IPC. Use only simple types -// and wide strings (can add support for others). -// answer : If the IPC was successful. The server-side answer is here. The -// interpretation of the answer is private to client and server. -// -// The return value is ALL_OK if the IPC was delivered to the server, other -// return codes indicate that the IPC transport failed to deliver it. -namespace sandbox { - -// this is the assumed channel size. This can be overridden in a given -// IPC implementation. -const uint32_t kIPCChannelSize = 1024; - -// The copy helper uses templates to deduce the appropriate copy function to -// copy the input parameters in the buffer that is going to be send across the -// IPC. These template facility can be made more sophisticated as need arises. - -// The default copy helper. It catches the general case where no other -// specialized template matches better. We set the type to UINT32_TYPE, so this -// only works with objects whose size is 32 bits. -template<typename T> -class CopyHelper { - public: - CopyHelper(const T& t) : t_(t) {} - - // Returns the pointer to the start of the input. - const void* GetStart() const { - return &t_; - } - - // Update the stored value with the value in the buffer. This is not - // supported for this type. - bool Update(void* buffer) { - // Not supported; - return true; - } - - // Returns the size of the input in bytes. - uint32_t GetSize() const { return sizeof(T); } - - // Returns true if the current type is used as an In or InOut parameter. - bool IsInOut() { - return false; - } - - // Returns this object's type. - ArgType GetType() { - static_assert(sizeof(T) == sizeof(uint32_t), "specialization needed"); - return UINT32_TYPE; - } - - private: - const T& t_; -}; - -// This copy helper template specialization if for the void pointer -// case both 32 and 64 bit. -template<> -class CopyHelper<void*> { - public: - CopyHelper(void* t) : t_(t) {} - - // Returns the pointer to the start of the input. - const void* GetStart() const { - return &t_; - } - - // Update the stored value with the value in the buffer. This is not - // supported for this type. - bool Update(void* buffer) { - // Not supported; - return true; - } - - // Returns the size of the input in bytes. - uint32_t GetSize() const { return sizeof(t_); } - - // Returns true if the current type is used as an In or InOut parameter. - bool IsInOut() { - return false; - } - - // Returns this object's type. - ArgType GetType() { - return VOIDPTR_TYPE; - } - - private: - const void* t_; -}; - -// This copy helper template specialization catches the cases where the -// parameter is a pointer to a string. -template<> -class CopyHelper<const wchar_t*> { - public: - CopyHelper(const wchar_t* t) - : t_(t) { - } - - // Returns the pointer to the start of the string. - const void* GetStart() const { - return t_; - } - - // Update the stored value with the value in the buffer. This is not - // supported for this type. - bool Update(void* buffer) { - // Not supported; - return true; - } - - // Returns the size of the string in bytes. We define a NULL string to - // be of zero length. - uint32_t GetSize() const { - __try { - return (!t_) ? 0 - : static_cast<uint32_t>(StringLength(t_) * sizeof(t_[0])); - } - __except(EXCEPTION_EXECUTE_HANDLER) { - return UINT32_MAX; - } - } - - // Returns true if the current type is used as an In or InOut parameter. - bool IsInOut() { - return false; - } - - ArgType GetType() { - return WCHAR_TYPE; - } - - private: - // We provide our not very optimized version of wcslen(), since we don't - // want to risk having the linker use the version in the CRT since the CRT - // might not be present when we do an early IPC call. - static size_t __cdecl StringLength(const wchar_t* wcs) { - const wchar_t *eos = wcs; - while (*eos++); - return static_cast<size_t>(eos - wcs - 1); - } - - const wchar_t* t_; -}; - -// Specialization for non-const strings. We just reuse the implementation of the -// const string specialization. -template<> -class CopyHelper<wchar_t*> : public CopyHelper<const wchar_t*> { - public: - typedef CopyHelper<const wchar_t*> Base; - CopyHelper(wchar_t* t) : Base(t) {} - - const void* GetStart() const { - return Base::GetStart(); - } - - bool Update(void* buffer) { - return Base::Update(buffer); - } - - uint32_t GetSize() const { return Base::GetSize(); } - - bool IsInOut() { - return Base::IsInOut(); - } - - ArgType GetType() { - return Base::GetType(); - } -}; - -// Specialization for wchar_t arrays strings. We just reuse the implementation -// of the const string specialization. -template<size_t n> -class CopyHelper<const wchar_t[n]> : public CopyHelper<const wchar_t*> { - public: - typedef const wchar_t array[n]; - typedef CopyHelper<const wchar_t*> Base; - CopyHelper(array t) : Base(t) {} - - const void* GetStart() const { - return Base::GetStart(); - } - - bool Update(void* buffer) { - return Base::Update(buffer); - } - - uint32_t GetSize() const { return Base::GetSize(); } - - bool IsInOut() { - return Base::IsInOut(); - } - - ArgType GetType() { - return Base::GetType(); - } -}; - -// Generic encapsulation class containing a pointer to a buffer and the -// size of the buffer. It is used by the IPC to be able to pass in/out -// parameters. -class InOutCountedBuffer : public CountedBuffer { - public: - InOutCountedBuffer(void* buffer, uint32_t size) - : CountedBuffer(buffer, size) {} -}; - -// This copy helper template specialization catches the cases where the -// parameter is a an input/output buffer. -template<> -class CopyHelper<InOutCountedBuffer> { - public: - CopyHelper(const InOutCountedBuffer t) : t_(t) {} - - // Returns the pointer to the start of the string. - const void* GetStart() const { - return t_.Buffer(); - } - - // Updates the buffer with the value from the new buffer in parameter. - bool Update(void* buffer) { - // We are touching user memory, this has to be done from inside a try - // except. - __try { - memcpy(t_.Buffer(), buffer, t_.Size()); - } - __except(EXCEPTION_EXECUTE_HANDLER) { - return false; - } - return true; - } - - // Returns the size of the string in bytes. We define a NULL string to - // be of zero length. - uint32_t GetSize() const { return t_.Size(); } - - // Returns true if the current type is used as an In or InOut parameter. - bool IsInOut() { - return true; - } - - ArgType GetType() { - return INOUTPTR_TYPE; - } - - private: - const InOutCountedBuffer t_; -}; - -// The following two macros make it less error prone the generation -// of CrossCall functions with ever more input parameters. - -#define XCALL_GEN_PARAMS_OBJ(num, params) \ - typedef ActualCallParams<num, kIPCChannelSize> ActualParams; \ - void* raw_mem = ipc_provider.GetBuffer(); \ - if (NULL == raw_mem) \ - return SBOX_ERROR_NO_SPACE; \ - ActualParams* params = new(raw_mem) ActualParams(tag); - -#define XCALL_GEN_COPY_PARAM(num, params) \ - static_assert(kMaxIpcParams >= num, "too many parameters"); \ - CopyHelper<Par##num> ch##num(p##num); \ - if (!params->CopyParamIn(num - 1, ch##num.GetStart(), ch##num.GetSize(), \ - ch##num.IsInOut(), ch##num.GetType())) \ - return SBOX_ERROR_NO_SPACE; - -#define XCALL_GEN_UPDATE_PARAM(num, params) \ - if (!ch##num.Update(params->GetParamPtr(num-1))) {\ - ipc_provider.FreeBuffer(raw_mem); \ - return SBOX_ERROR_BAD_PARAMS; \ - } - -#define XCALL_GEN_FREE_CHANNEL() \ - ipc_provider.FreeBuffer(raw_mem); - -// CrossCall template with one input parameter -template <typename IPCProvider, typename Par1> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(1, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - - return result; -} - -// CrossCall template with two input parameters. -template <typename IPCProvider, typename Par1, typename Par2> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - const Par2& p2, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(2, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - XCALL_GEN_COPY_PARAM(2, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_UPDATE_PARAM(2, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - return result; -} - -// CrossCall template with three input parameters. -template <typename IPCProvider, typename Par1, typename Par2, typename Par3> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - const Par2& p2, - const Par3& p3, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(3, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - XCALL_GEN_COPY_PARAM(2, call_params); - XCALL_GEN_COPY_PARAM(3, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_UPDATE_PARAM(2, call_params); - XCALL_GEN_UPDATE_PARAM(3, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - return result; -} - -// CrossCall template with four input parameters. -template <typename IPCProvider, - typename Par1, - typename Par2, - typename Par3, - typename Par4> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - const Par2& p2, - const Par3& p3, - const Par4& p4, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(4, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - XCALL_GEN_COPY_PARAM(2, call_params); - XCALL_GEN_COPY_PARAM(3, call_params); - XCALL_GEN_COPY_PARAM(4, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_UPDATE_PARAM(2, call_params); - XCALL_GEN_UPDATE_PARAM(3, call_params); - XCALL_GEN_UPDATE_PARAM(4, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - return result; -} - -// CrossCall template with five input parameters. -template <typename IPCProvider, - typename Par1, - typename Par2, - typename Par3, - typename Par4, - typename Par5> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - const Par2& p2, - const Par3& p3, - const Par4& p4, - const Par5& p5, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(5, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - XCALL_GEN_COPY_PARAM(2, call_params); - XCALL_GEN_COPY_PARAM(3, call_params); - XCALL_GEN_COPY_PARAM(4, call_params); - XCALL_GEN_COPY_PARAM(5, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_UPDATE_PARAM(2, call_params); - XCALL_GEN_UPDATE_PARAM(3, call_params); - XCALL_GEN_UPDATE_PARAM(4, call_params); - XCALL_GEN_UPDATE_PARAM(5, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - return result; -} - -// CrossCall template with six input parameters. -template <typename IPCProvider, - typename Par1, - typename Par2, - typename Par3, - typename Par4, - typename Par5, - typename Par6> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - const Par2& p2, - const Par3& p3, - const Par4& p4, - const Par5& p5, - const Par6& p6, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(6, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - XCALL_GEN_COPY_PARAM(2, call_params); - XCALL_GEN_COPY_PARAM(3, call_params); - XCALL_GEN_COPY_PARAM(4, call_params); - XCALL_GEN_COPY_PARAM(5, call_params); - XCALL_GEN_COPY_PARAM(6, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_UPDATE_PARAM(2, call_params); - XCALL_GEN_UPDATE_PARAM(3, call_params); - XCALL_GEN_UPDATE_PARAM(4, call_params); - XCALL_GEN_UPDATE_PARAM(5, call_params); - XCALL_GEN_UPDATE_PARAM(6, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - return result; -} - -// CrossCall template with seven input parameters. -template <typename IPCProvider, - typename Par1, - typename Par2, - typename Par3, - typename Par4, - typename Par5, - typename Par6, - typename Par7> -ResultCode CrossCall(IPCProvider& ipc_provider, - uint32_t tag, - const Par1& p1, - const Par2& p2, - const Par3& p3, - const Par4& p4, - const Par5& p5, - const Par6& p6, - const Par7& p7, - CrossCallReturn* answer) { - XCALL_GEN_PARAMS_OBJ(7, call_params); - XCALL_GEN_COPY_PARAM(1, call_params); - XCALL_GEN_COPY_PARAM(2, call_params); - XCALL_GEN_COPY_PARAM(3, call_params); - XCALL_GEN_COPY_PARAM(4, call_params); - XCALL_GEN_COPY_PARAM(5, call_params); - XCALL_GEN_COPY_PARAM(6, call_params); - XCALL_GEN_COPY_PARAM(7, call_params); - - ResultCode result = ipc_provider.DoCall(call_params, answer); - - if (SBOX_ERROR_CHANNEL_ERROR != result) { - XCALL_GEN_UPDATE_PARAM(1, call_params); - XCALL_GEN_UPDATE_PARAM(2, call_params); - XCALL_GEN_UPDATE_PARAM(3, call_params); - XCALL_GEN_UPDATE_PARAM(4, call_params); - XCALL_GEN_UPDATE_PARAM(5, call_params); - XCALL_GEN_UPDATE_PARAM(6, call_params); - XCALL_GEN_UPDATE_PARAM(7, call_params); - XCALL_GEN_FREE_CHANNEL(); - } - return result; -} -} // namespace sandbox - -#endif // SANDBOX_SRC_CROSSCALL_CLIENT_H__ diff --git a/sandbox/win/src/crosscall_params.h b/sandbox/win/src/crosscall_params.h deleted file mode 100644 index eb59c44239..0000000000 --- a/sandbox/win/src/crosscall_params.h +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) 2012 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_SRC_CROSSCALL_PARAMS_H__ -#define SANDBOX_SRC_CROSSCALL_PARAMS_H__ - -#include <windows.h> -#include <lmaccess.h> -#include <stddef.h> -#include <stdint.h> - -#include <memory> - -#include "base/macros.h" -#include "sandbox/win/src/internal_types.h" -#include "sandbox/win/src/sandbox_types.h" - -// Increases |value| until there is no need for padding given an int64_t -// alignment. Returns the increased value. -inline uint32_t Align(uint32_t value) { - uint32_t alignment = sizeof(int64_t); - return ((value + alignment - 1) / alignment) * alignment; -} - -// This header is part of CrossCall: the sandbox inter-process communication. -// This header defines the basic types used both in the client IPC and in the -// server IPC code. CrossCallParams and ActualCallParams model the input -// parameters of an IPC call and CrossCallReturn models the output params and -// the return value. -// -// An IPC call is defined by its 'tag' which is a (uint32_t) unique identifier -// that is used to route the IPC call to the proper server. Every tag implies -// a complete call signature including the order and type of each parameter. -// -// Like most IPC systems. CrossCall is designed to take as inputs 'simple' -// types such as integers and strings. Classes, generic arrays or pointers to -// them are not supported. -// -// Another limitation of CrossCall is that the return value and output -// parameters can only be uint32_t integers. Returning complex structures or -// strings is not supported. - -namespace sandbox { - -// max number of extended return parameters. See CrossCallReturn -const size_t kExtendedReturnCount = 8; - -// Union of multiple types to be used as extended results -// in the CrossCallReturn. -union MultiType { - uint32_t unsigned_int; - void* pointer; - HANDLE handle; - ULONG_PTR ulong_ptr; -}; - -// Maximum number of IPC parameters currently supported. -// To increase this value, we have to: -// - Add another Callback typedef to Dispatcher. -// - Add another case to the switch on SharedMemIPCServer::InvokeCallback. -// - Add another case to the switch in GetActualAndMaxBufferSize -const int kMaxIpcParams = 9; - -// Contains the information about a parameter in the ipc buffer. -struct ParamInfo { - ArgType type_; - uint32_t offset_; - uint32_t size_; -}; - -// Models the return value and the return parameters of an IPC call -// currently limited to one status code and eight generic return values -// which cannot be pointers to other data. For x64 ports this structure -// might have to use other integer types. -struct CrossCallReturn { - // the IPC tag. It should match the original IPC tag. - uint32_t tag; - // The result of the IPC operation itself. - ResultCode call_outcome; - // the result of the IPC call as executed in the server. The interpretation - // of this value depends on the specific service. - union { - NTSTATUS nt_status; - DWORD win32_result; - }; - // Number of extended return values. - uint32_t extended_count; - // for calls that should return a windows handle. It is found here. - HANDLE handle; - // The array of extended values. - MultiType extended[kExtendedReturnCount]; -}; - -// CrossCallParams base class that models the input params all packed in a -// single compact memory blob. The representation can vary but in general a -// given child of this class is meant to represent all input parameters -// necessary to make a IPC call. -// -// This class cannot have virtual members because its assumed the IPC -// parameters start from the 'this' pointer to the end, which is defined by -// one of the subclasses -// -// Objects of this class cannot be constructed directly. Only derived -// classes have the proper knowledge to construct it. -class CrossCallParams { - public: - // Returns the tag (ipc unique id) associated with this IPC. - uint32_t GetTag() const { return tag_; } - - // Returns the beggining of the buffer where the IPC params can be stored. - // prior to an IPC call - const void* GetBuffer() const { - return this; - } - - // Returns how many parameter this IPC call should have. - uint32_t GetParamsCount() const { return params_count_; } - - // Returns a pointer to the CrossCallReturn structure. - CrossCallReturn* GetCallReturn() { - return &call_return; - } - - // Returns TRUE if this call contains InOut parameters. - bool IsInOut() const { return (1 == is_in_out_); } - - // Tells the CrossCall object if it contains InOut parameters. - void SetIsInOut(bool value) { - if (value) - is_in_out_ = 1; - else - is_in_out_ = 0; - } - - protected: - // constructs the IPC call params. Called only from the derived classes - CrossCallParams(uint32_t tag, uint32_t params_count) - : tag_(tag), is_in_out_(0), params_count_(params_count) {} - - private: - uint32_t tag_; - uint32_t is_in_out_; - CrossCallReturn call_return; - const uint32_t params_count_; - DISALLOW_COPY_AND_ASSIGN(CrossCallParams); -}; - -// ActualCallParams models an specific IPC call parameters with respect to the -// storage allocation that the packed parameters should need. -// NUMBER_PARAMS: the number of parameters, valid from 1 to N -// BLOCK_SIZE: the total storage that the NUMBER_PARAMS parameters can take, -// typically the block size is defined by the channel size of the underlying -// ipc mechanism. -// In practice this class is used to levergage C++ capacity to properly -// calculate sizes and displacements given the possibility of the packed params -// blob to be complex. -// -// As is, this class assumes that the layout of the blob is as follows. Assume -// that NUMBER_PARAMS = 2 and a 32-bit build: -// -// [ tag 4 bytes] -// [ IsOnOut 4 bytes] -// [ call return 52 bytes] -// [ params count 4 bytes] -// [ parameter 0 type 4 bytes] -// [ parameter 0 offset 4 bytes] ---delta to ---\ -// [ parameter 0 size 4 bytes] | -// [ parameter 1 type 4 bytes] | -// [ parameter 1 offset 4 bytes] ---------------|--\ -// [ parameter 1 size 4 bytes] | | -// [ parameter 2 type 4 bytes] | | -// [ parameter 2 offset 4 bytes] ----------------------\ -// [ parameter 2 size 4 bytes] | | | -// |---------------------------| | | | -// | value 0 (x bytes) | <--------------/ | | -// | value 1 (y bytes) | <-----------------/ | -// | | | -// | end of buffer | <---------------------/ -// |---------------------------| -// -// Note that the actual number of params is NUMBER_PARAMS + 1 -// so that the size of each actual param can be computed from the difference -// between one parameter and the next down. The offset of the last param -// points to the end of the buffer and the type and size are undefined. -// -template <size_t NUMBER_PARAMS, size_t BLOCK_SIZE> -class ActualCallParams : public CrossCallParams { - public: - // constructor. Pass the ipc unique tag as input - explicit ActualCallParams(uint32_t tag) - : CrossCallParams(tag, NUMBER_PARAMS) { - param_info_[0].offset_ = - static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); - } - - // Testing-only constructor. Allows setting the |number_params| to a - // wrong value. - ActualCallParams(uint32_t tag, uint32_t number_params) - : CrossCallParams(tag, number_params) { - param_info_[0].offset_ = - static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); - } - - // Testing-only method. Allows setting the apparent size to a wrong value. - // returns the previous size. - uint32_t OverrideSize(uint32_t new_size) { - uint32_t previous_size = param_info_[NUMBER_PARAMS].offset_; - param_info_[NUMBER_PARAMS].offset_ = new_size; - return previous_size; - } - - // Copies each paramter into the internal buffer. For each you must supply: - // index: 0 for the first param, 1 for the next an so on - bool CopyParamIn(uint32_t index, - const void* parameter_address, - uint32_t size, - bool is_in_out, - ArgType type) { - if (index >= NUMBER_PARAMS) { - return false; - } - - if (UINT32_MAX == size) { - // Memory error while getting the size. - return false; - } - - if (size && !parameter_address) { - return false; - } - - if ((size > sizeof(*this)) || - (param_info_[index].offset_ > (sizeof(*this) - size))) { - // It does not fit, abort copy. - return false; - } - - char* dest = reinterpret_cast<char*>(this) + param_info_[index].offset_; - - // We might be touching user memory, this has to be done from inside a try - // except. - __try { - memcpy(dest, parameter_address, size); - } - __except(EXCEPTION_EXECUTE_HANDLER) { - return false; - } - - // Set the flag to tell the broker to update the buffer once the call is - // made. - if (is_in_out) - SetIsInOut(true); - - param_info_[index + 1].offset_ = Align(param_info_[index].offset_ + - size); - param_info_[index].size_ = size; - param_info_[index].type_ = type; - return true; - } - - // Returns a pointer to a parameter in the memory section. - void* GetParamPtr(size_t index) { - return reinterpret_cast<char*>(this) + param_info_[index].offset_; - } - - // Returns the total size of the buffer. Only valid once all the paramters - // have been copied in with CopyParamIn. - uint32_t GetSize() const { return param_info_[NUMBER_PARAMS].offset_; } - - protected: - ActualCallParams() : CrossCallParams(0, NUMBER_PARAMS) { } - - private: - ParamInfo param_info_[NUMBER_PARAMS + 1]; - char parameters_[BLOCK_SIZE - sizeof(CrossCallParams) - - sizeof(ParamInfo) * (NUMBER_PARAMS + 1)]; - DISALLOW_COPY_AND_ASSIGN(ActualCallParams); -}; - -static_assert(sizeof(ActualCallParams<1, 1024>) == 1024, "bad size buffer"); -static_assert(sizeof(ActualCallParams<2, 1024>) == 1024, "bad size buffer"); -static_assert(sizeof(ActualCallParams<3, 1024>) == 1024, "bad size buffer"); - -} // namespace sandbox - -#endif // SANDBOX_SRC_CROSSCALL_PARAMS_H__ diff --git a/sandbox/win/src/interception_internal.h b/sandbox/win/src/interception_internal.h deleted file mode 100644 index 45a0557e5e..0000000000 --- a/sandbox/win/src/interception_internal.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2006-2010 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. - -// Defines InterceptionManager, the class in charge of setting up interceptions -// for the sandboxed process. For more details see: -// http://dev.chromium.org/developers/design-documents/sandbox . - -#ifndef SANDBOX_SRC_INTERCEPTION_INTERNAL_H_ -#define SANDBOX_SRC_INTERCEPTION_INTERNAL_H_ - -#include <stddef.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, -// hence this pragma. -#pragma pack(push, 4) - -// Structures for the shared memory that contains patching information -// for the InterceptionAgent. -// A single interception: -struct FunctionInfo { - size_t record_bytes; // rounded to sizeof(size_t) bytes - InterceptionType type; - InterceptorId id; - const void* interceptor_address; - char function[1]; // placeholder for null terminated name - // char interceptor[] // followed by the interceptor function -}; - -// A single dll: -struct DllPatchInfo { - size_t record_bytes; // rounded to sizeof(size_t) bytes - size_t offset_to_functions; - int num_functions; - bool unload_module; - wchar_t dll_name[1]; // placeholder for null terminated name - // FunctionInfo function_info[] // followed by the functions to intercept -}; - -// All interceptions: -struct SharedMemory { - int num_intercepted_dlls; - void* interceptor_base; - DllPatchInfo dll_list[1]; // placeholder for the list of dlls -}; - -// Dummy single thunk: -struct ThunkData { - char data[kMaxThunkDataBytes]; -}; - -// In-memory representation of the interceptions for a given dll: -struct DllInterceptionData { - size_t data_bytes; - size_t used_bytes; - void* base; - int num_thunks; -#if defined(_WIN64) - int dummy; // Improve alignment. -#endif - ThunkData thunks[1]; -}; - -#pragma pack(pop) - -} // namespace sandbox - -#endif // SANDBOX_SRC_INTERCEPTION_INTERNAL_H_ diff --git a/sandbox/win/src/interceptors.h b/sandbox/win/src/interceptors.h deleted file mode 100644 index 44b34e37f2..0000000000 --- a/sandbox/win/src/interceptors.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2011 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_SRC_INTERCEPTORS_H_ -#define SANDBOX_SRC_INTERCEPTORS_H_ - -#if defined(_WIN64) -#include "sandbox/win/src/interceptors_64.h" -#endif - -namespace sandbox { - -enum InterceptorId { - // Internal use: - MAP_VIEW_OF_SECTION_ID = 0, - UNMAP_VIEW_OF_SECTION_ID, - // Policy broker: - SET_INFORMATION_THREAD_ID, - OPEN_THREAD_TOKEN_ID, - OPEN_THREAD_TOKEN_EX_ID, - OPEN_THREAD_ID, - OPEN_PROCESS_ID, - OPEN_PROCESS_TOKEN_ID, - OPEN_PROCESS_TOKEN_EX_ID, - // Filesystem dispatcher: - CREATE_FILE_ID, - OPEN_FILE_ID, - QUERY_ATTRIB_FILE_ID, - QUERY_FULL_ATTRIB_FILE_ID, - SET_INFO_FILE_ID, - // Named pipe dispatcher: - CREATE_NAMED_PIPE_ID, - // Process-thread dispatcher: - CREATE_PROCESSW_ID, - CREATE_PROCESSA_ID, - CREATE_THREAD_ID, - // Registry dispatcher: - CREATE_KEY_ID, - OPEN_KEY_ID, - OPEN_KEY_EX_ID, - // Sync dispatcher: - CREATE_EVENT_ID, - OPEN_EVENT_ID, - // Process mitigations Win32k dispatcher: - GDIINITIALIZE_ID, - GETSTOCKOBJECT_ID, - REGISTERCLASSW_ID, - ENUMDISPLAYMONITORS_ID, - ENUMDISPLAYDEVICESA_ID, - GETMONITORINFOA_ID, - GETMONITORINFOW_ID, - CREATEOPMPROTECTEDOUTPUTS_ID, - GETCERTIFICATE_ID, - GETCERTIFICATESIZE_ID, - GETCERTIFICATEBYHANDLE_ID, - GETCERTIFICATESIZEBYHANDLE_ID, - DESTROYOPMPROTECTEDOUTPUT_ID, - CONFIGUREOPMPROTECTEDOUTPUT_ID, - GETOPMINFORMATION_ID, - GETOPMRANDOMNUMBER_ID, - GETSUGGESTEDOPMPROTECTEDOUTPUTARRAYSIZE_ID, - SETOPMSIGNINGKEYANDSEQUENCENUMBERS_ID, - INTERCEPTOR_MAX_ID -}; - -typedef void* OriginalFunctions[INTERCEPTOR_MAX_ID]; - -} // namespace sandbox - -#endif // SANDBOX_SRC_INTERCEPTORS_H_ diff --git a/sandbox/win/src/internal_types.h b/sandbox/win/src/internal_types.h deleted file mode 100644 index 7ea4b7d62e..0000000000 --- a/sandbox/win/src/internal_types.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2012 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_WIN_SRC_INTERNAL_TYPES_H_ -#define SANDBOX_WIN_SRC_INTERNAL_TYPES_H_ - -#include <stdint.h> - -namespace sandbox { - -const wchar_t kNtdllName[] = L"ntdll.dll"; -const wchar_t kKerneldllName[] = L"kernel32.dll"; -const wchar_t kKernelBasedllName[] = L"kernelbase.dll"; - -// Defines the supported C++ types encoding to numeric id. Like a simplified -// RTTI. Note that true C++ RTTI will not work because the types are not -// polymorphic anyway. -enum ArgType { - INVALID_TYPE = 0, - WCHAR_TYPE, - UINT32_TYPE, - UNISTR_TYPE, - VOIDPTR_TYPE, - INPTR_TYPE, - INOUTPTR_TYPE, - LAST_TYPE -}; - -// Encapsulates a pointer to a buffer and the size of the buffer. -class CountedBuffer { - public: - CountedBuffer(void* buffer, uint32_t size) : size_(size), buffer_(buffer) {} - - uint32_t Size() const { return size_; } - - void* Buffer() const { - return buffer_; - } - - private: - uint32_t size_; - void* buffer_; -}; - -// Helper class to convert void-pointer packed ints for both -// 32 and 64 bit builds. This construct is non-portable. -class IPCInt { - public: - explicit IPCInt(void* buffer) { - buffer_.vp = buffer; - } - - explicit IPCInt(unsigned __int32 i32) { - buffer_.vp = NULL; - buffer_.i32 = i32; - } - - unsigned __int32 As32Bit() const { - return buffer_.i32; - } - - void* AsVoidPtr() const { - return buffer_.vp; - } - - private: - union U { - void* vp; - unsigned __int32 i32; - } buffer_; -}; - -} // namespace sandbox - -#endif // SANDBOX_WIN_SRC_INTERNAL_TYPES_H_ diff --git a/sandbox/win/src/ipc_tags.h b/sandbox/win/src/ipc_tags.h deleted file mode 100644 index 1c754cdd1f..0000000000 --- a/sandbox/win/src/ipc_tags.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 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_SRC_IPC_TAGS_H__ -#define SANDBOX_SRC_IPC_TAGS_H__ - -namespace sandbox { - -enum { - IPC_UNUSED_TAG = 0, - IPC_PING1_TAG, // Takes a cookie in parameters and returns the cookie - // multiplied by 2 and the tick_count. Used for testing only. - IPC_PING2_TAG, // Takes an in/out cookie in parameters and modify the cookie - // to be multiplied by 3. Used for testing only. - IPC_NTCREATEFILE_TAG, - IPC_NTOPENFILE_TAG, - IPC_NTQUERYATTRIBUTESFILE_TAG, - IPC_NTQUERYFULLATTRIBUTESFILE_TAG, - IPC_NTSETINFO_RENAME_TAG, - IPC_CREATENAMEDPIPEW_TAG, - IPC_NTOPENTHREAD_TAG, - IPC_NTOPENPROCESS_TAG, - IPC_NTOPENPROCESSTOKEN_TAG, - IPC_NTOPENPROCESSTOKENEX_TAG, - IPC_CREATEPROCESSW_TAG, - IPC_CREATEEVENT_TAG, - IPC_OPENEVENT_TAG, - IPC_NTCREATEKEY_TAG, - IPC_NTOPENKEY_TAG, - IPC_GDI_GDIDLLINITIALIZE_TAG, - IPC_GDI_GETSTOCKOBJECT_TAG, - IPC_USER_REGISTERCLASSW_TAG, - IPC_CREATETHREAD_TAG, - IPC_USER_ENUMDISPLAYMONITORS_TAG, - IPC_USER_ENUMDISPLAYDEVICES_TAG, - IPC_USER_GETMONITORINFO_TAG, - IPC_GDI_CREATEOPMPROTECTEDOUTPUTS_TAG, - IPC_GDI_GETCERTIFICATE_TAG, - IPC_GDI_GETCERTIFICATESIZE_TAG, - IPC_GDI_DESTROYOPMPROTECTEDOUTPUT_TAG, - IPC_GDI_CONFIGUREOPMPROTECTEDOUTPUT_TAG, - IPC_GDI_GETOPMINFORMATION_TAG, - IPC_GDI_GETOPMRANDOMNUMBER_TAG, - IPC_GDI_GETSUGGESTEDOPMPROTECTEDOUTPUTARRAYSIZE_TAG, - IPC_GDI_SETOPMSIGNINGKEYANDSEQUENCENUMBERS_TAG, - IPC_LAST_TAG -}; - -} // namespace sandbox - -#endif // SANDBOX_SRC_IPC_TAGS_H__ diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h deleted file mode 100644 index 6469c2bf34..0000000000 --- a/sandbox/win/src/nt_internals.h +++ /dev/null @@ -1,912 +0,0 @@ -// Copyright 2013 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. - -// This file holds definitions related to the ntdll API. - -#ifndef SANDBOX_WIN_SRC_NT_INTERNALS_H__ -#define SANDBOX_WIN_SRC_NT_INTERNALS_H__ - -#include <windows.h> -#include <stddef.h> - -typedef LONG NTSTATUS; -#define NT_SUCCESS(st) (st >= 0) - -#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) -#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) -#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) -#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) -#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) -#ifndef STATUS_INVALID_PARAMETER -// It is now defined in Windows 2008 SDK. -#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) -#endif -#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L) -#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) -#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) -#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) -#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xC0000035L) -#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007AL) -#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL) -#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL) -#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL) - -#define CURRENT_PROCESS ((HANDLE) -1) -#define CURRENT_THREAD ((HANDLE) -2) -#define NtCurrentProcess CURRENT_PROCESS - -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING; -typedef UNICODE_STRING *PUNICODE_STRING; -typedef const UNICODE_STRING *PCUNICODE_STRING; - -typedef struct _STRING { - USHORT Length; - USHORT MaximumLength; - PCHAR Buffer; -} STRING; -typedef STRING *PSTRING; - -typedef STRING ANSI_STRING; -typedef PSTRING PANSI_STRING; -typedef CONST PSTRING PCANSI_STRING; - -typedef STRING OEM_STRING; -typedef PSTRING POEM_STRING; -typedef CONST STRING* PCOEM_STRING; - -#define OBJ_CASE_INSENSITIVE 0x00000040L -#define OBJ_OPENIF 0x00000080L - -typedef struct _OBJECT_ATTRIBUTES { - ULONG Length; - HANDLE RootDirectory; - PUNICODE_STRING ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES; -typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; - -#define InitializeObjectAttributes(p, n, a, r, s) { \ - (p)->Length = sizeof(OBJECT_ATTRIBUTES);\ - (p)->RootDirectory = r;\ - (p)->Attributes = a;\ - (p)->ObjectName = n;\ - (p)->SecurityDescriptor = s;\ - (p)->SecurityQualityOfService = NULL;\ -} - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - }; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -// ----------------------------------------------------------------------- -// File IO - -// Create disposition values. - -#define FILE_SUPERSEDE 0x00000000 -#define FILE_OPEN 0x00000001 -#define FILE_CREATE 0x00000002 -#define FILE_OPEN_IF 0x00000003 -#define FILE_OVERWRITE 0x00000004 -#define FILE_OVERWRITE_IF 0x00000005 -#define FILE_MAXIMUM_DISPOSITION 0x00000005 - -// Create/open option flags. - -#define FILE_DIRECTORY_FILE 0x00000001 -#define FILE_WRITE_THROUGH 0x00000002 -#define FILE_SEQUENTIAL_ONLY 0x00000004 -#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 - -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 -#define FILE_NON_DIRECTORY_FILE 0x00000040 -#define FILE_CREATE_TREE_CONNECTION 0x00000080 - -#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 -#define FILE_NO_EA_KNOWLEDGE 0x00000200 -#define FILE_OPEN_REMOTE_INSTANCE 0x00000400 -#define FILE_RANDOM_ACCESS 0x00000800 - -#define FILE_DELETE_ON_CLOSE 0x00001000 -#define FILE_OPEN_BY_FILE_ID 0x00002000 -#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 -#define FILE_NO_COMPRESSION 0x00008000 - -#define FILE_RESERVE_OPFILTER 0x00100000 -#define FILE_OPEN_REPARSE_POINT 0x00200000 -#define FILE_OPEN_NO_RECALL 0x00400000 -#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 - -// Create/open result values. These are the disposition values returned on the -// io status information. -#define FILE_SUPERSEDED 0x00000000 -#define FILE_OPENED 0x00000001 -#define FILE_CREATED 0x00000002 -#define FILE_OVERWRITTEN 0x00000003 -#define FILE_EXISTS 0x00000004 -#define FILE_DOES_NOT_EXIST 0x00000005 - -typedef NTSTATUS (WINAPI *NtCreateFileFunction)( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PLARGE_INTEGER AllocationSize OPTIONAL, - IN ULONG FileAttributes, - IN ULONG ShareAccess, - IN ULONG CreateDisposition, - IN ULONG CreateOptions, - IN PVOID EaBuffer OPTIONAL, - IN ULONG EaLength); - -typedef NTSTATUS (WINAPI *NtOpenFileFunction)( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG ShareAccess, - IN ULONG OpenOptions); - -typedef NTSTATUS (WINAPI *NtCloseFunction)( - IN HANDLE Handle); - -typedef enum _FILE_INFORMATION_CLASS { - FileRenameInformation = 10 -} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; - -typedef struct _FILE_RENAME_INFORMATION { - BOOLEAN ReplaceIfExists; - HANDLE RootDirectory; - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; - -typedef NTSTATUS (WINAPI *NtSetInformationFileFunction)( - IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID FileInformation, - IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInformationClass); - -typedef struct FILE_BASIC_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - ULONG FileAttributes; -} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; - -typedef NTSTATUS (WINAPI *NtQueryAttributesFileFunction)( - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PFILE_BASIC_INFORMATION FileAttributes); - -typedef struct _FILE_NETWORK_OPEN_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG FileAttributes; -} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; - -typedef NTSTATUS (WINAPI *NtQueryFullAttributesFileFunction)( - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PFILE_NETWORK_OPEN_INFORMATION FileAttributes); - -// ----------------------------------------------------------------------- -// Sections - -typedef NTSTATUS (WINAPI *NtCreateSectionFunction)( - OUT PHANDLE SectionHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN PLARGE_INTEGER MaximumSize OPTIONAL, - IN ULONG SectionPageProtection, - IN ULONG AllocationAttributes, - IN HANDLE FileHandle OPTIONAL); - -typedef ULONG SECTION_INHERIT; -#define ViewShare 1 -#define ViewUnmap 2 - -typedef NTSTATUS (WINAPI *NtMapViewOfSectionFunction)( - IN HANDLE SectionHandle, - IN HANDLE ProcessHandle, - IN OUT PVOID *BaseAddress, - IN ULONG_PTR ZeroBits, - IN SIZE_T CommitSize, - IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, - IN OUT PSIZE_T ViewSize, - IN SECTION_INHERIT InheritDisposition, - IN ULONG AllocationType, - IN ULONG Win32Protect); - -typedef NTSTATUS (WINAPI *NtUnmapViewOfSectionFunction)( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress); - -typedef enum _SECTION_INFORMATION_CLASS { - SectionBasicInformation = 0, - SectionImageInformation -} SECTION_INFORMATION_CLASS; - -typedef struct _SECTION_BASIC_INFORMATION { - PVOID BaseAddress; - ULONG Attributes; - LARGE_INTEGER Size; -} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; - -typedef NTSTATUS (WINAPI *NtQuerySectionFunction)( - IN HANDLE SectionHandle, - IN SECTION_INFORMATION_CLASS SectionInformationClass, - OUT PVOID SectionInformation, - IN SIZE_T SectionInformationLength, - OUT PSIZE_T ReturnLength OPTIONAL); - -// ----------------------------------------------------------------------- -// Process and Thread - -typedef struct _CLIENT_ID { - PVOID UniqueProcess; - PVOID UniqueThread; -} CLIENT_ID, *PCLIENT_ID; - -typedef NTSTATUS (WINAPI *NtOpenThreadFunction) ( - OUT PHANDLE ThreadHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PCLIENT_ID ClientId); - -typedef NTSTATUS (WINAPI *NtOpenProcessFunction) ( - OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PCLIENT_ID ClientId); - -typedef enum _NT_THREAD_INFORMATION_CLASS { - ThreadBasicInformation, - ThreadTimes, - ThreadPriority, - ThreadBasePriority, - ThreadAffinityMask, - ThreadImpersonationToken, - ThreadDescriptorTableEntry, - ThreadEnableAlignmentFaultFixup, - ThreadEventPair, - ThreadQuerySetWin32StartAddress, - ThreadZeroTlsCell, - ThreadPerformanceCount, - ThreadAmILastThread, - ThreadIdealProcessor, - ThreadPriorityBoost, - ThreadSetTlsArrayAddress, - ThreadIsIoPending, - ThreadHideFromDebugger -} NT_THREAD_INFORMATION_CLASS, *PNT_THREAD_INFORMATION_CLASS; - -typedef NTSTATUS (WINAPI *NtSetInformationThreadFunction) ( - IN HANDLE ThreadHandle, - IN NT_THREAD_INFORMATION_CLASS ThreadInformationClass, - IN PVOID ThreadInformation, - IN ULONG ThreadInformationLength); - -// Partial definition only: -typedef enum _PROCESSINFOCLASS { - ProcessBasicInformation = 0, - ProcessExecuteFlags = 0x22 -} PROCESSINFOCLASS; - -typedef PVOID PPEB; -typedef LONG KPRIORITY; - -typedef struct _PROCESS_BASIC_INFORMATION { - union { - NTSTATUS ExitStatus; - PVOID padding_for_x64_0; - }; - PPEB PebBaseAddress; - KAFFINITY AffinityMask; - union { - KPRIORITY BasePriority; - PVOID padding_for_x64_1; - }; - union { - DWORD UniqueProcessId; - PVOID padding_for_x64_2; - }; - union { - DWORD InheritedFromUniqueProcessId; - PVOID padding_for_x64_3; - }; -} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; - -typedef NTSTATUS(WINAPI* NtQueryInformationProcessFunction)( - IN HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - OUT PVOID ProcessInformation, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength OPTIONAL); - -typedef NTSTATUS(WINAPI* NtSetInformationProcessFunction)( - HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - IN PVOID ProcessInformation, - IN ULONG ProcessInformationLength); - -typedef NTSTATUS (WINAPI *NtOpenThreadTokenFunction) ( - IN HANDLE ThreadHandle, - IN ACCESS_MASK DesiredAccess, - IN BOOLEAN OpenAsSelf, - OUT PHANDLE TokenHandle); - -typedef NTSTATUS (WINAPI *NtOpenThreadTokenExFunction) ( - IN HANDLE ThreadHandle, - IN ACCESS_MASK DesiredAccess, - IN BOOLEAN OpenAsSelf, - IN ULONG HandleAttributes, - OUT PHANDLE TokenHandle); - -typedef NTSTATUS (WINAPI *NtOpenProcessTokenFunction) ( - IN HANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - OUT PHANDLE TokenHandle); - -typedef NTSTATUS (WINAPI *NtOpenProcessTokenExFunction) ( - IN HANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN ULONG HandleAttributes, - OUT PHANDLE TokenHandle); - -typedef NTSTATUS(WINAPI* NtQueryInformationTokenFunction)( - IN HANDLE TokenHandle, - IN TOKEN_INFORMATION_CLASS TokenInformationClass, - OUT PVOID TokenInformation, - IN ULONG TokenInformationLength, - OUT PULONG ReturnLength); - -typedef NTSTATUS(WINAPI* RtlCreateUserThreadFunction)( - IN HANDLE Process, - IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, - IN BOOLEAN CreateSuspended, - IN ULONG ZeroBits, - IN SIZE_T MaximumStackSize, - IN SIZE_T CommittedStackSize, - IN LPTHREAD_START_ROUTINE StartAddress, - IN PVOID Parameter, - OUT PHANDLE Thread, - OUT PCLIENT_ID ClientId); - -typedef NTSTATUS(WINAPI* RtlConvertSidToUnicodeStringFunction)( - OUT PUNICODE_STRING UnicodeString, - IN PSID Sid, - IN BOOLEAN AllocateDestinationString); - -typedef VOID(WINAPI* RtlFreeUnicodeStringFunction)( - IN OUT PUNICODE_STRING UnicodeString); - -// ----------------------------------------------------------------------- -// Registry - -typedef enum _KEY_VALUE_INFORMATION_CLASS { - KeyValueFullInformation = 1 -} KEY_VALUE_INFORMATION_CLASS, - *PKEY_VALUE_INFORMATION_CLASS; - -typedef struct _KEY_VALUE_FULL_INFORMATION { - ULONG TitleIndex; - ULONG Type; - ULONG DataOffset; - ULONG DataLength; - ULONG NameLength; - WCHAR Name[1]; -} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION; - -typedef NTSTATUS (WINAPI *NtCreateKeyFunction)( - OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG TitleIndex, - IN PUNICODE_STRING Class OPTIONAL, - IN ULONG CreateOptions, - OUT PULONG Disposition OPTIONAL); - -typedef NTSTATUS (WINAPI *NtOpenKeyFunction)( - OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI *NtOpenKeyExFunction)( - OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN DWORD open_options); - -typedef NTSTATUS (WINAPI *NtDeleteKeyFunction)( - IN HANDLE KeyHandle); - -typedef NTSTATUS(WINAPI* RtlFormatCurrentUserKeyPathFunction)( - OUT PUNICODE_STRING RegistryPath); - -typedef NTSTATUS(WINAPI* NtQueryValueKeyFunction)(IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName, - IN KEY_VALUE_INFORMATION_CLASS - KeyValueInformationClass, - OUT PVOID KeyValueInformation, - IN ULONG Length, - OUT PULONG ResultLength); - -typedef NTSTATUS(WINAPI* NtSetValueKeyFunction)(IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName, - IN ULONG TitleIndex OPTIONAL, - IN ULONG Type, - IN PVOID Data, - IN ULONG DataSize); - -// ----------------------------------------------------------------------- -// Memory - -// Don't really need this structure right now. -typedef PVOID PRTL_HEAP_PARAMETERS; - -typedef PVOID (WINAPI *RtlCreateHeapFunction)( - IN ULONG Flags, - IN PVOID HeapBase OPTIONAL, - IN SIZE_T ReserveSize OPTIONAL, - IN SIZE_T CommitSize OPTIONAL, - IN PVOID Lock OPTIONAL, - IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL); - -typedef PVOID (WINAPI *RtlDestroyHeapFunction)( - IN PVOID HeapHandle); - -typedef PVOID (WINAPI *RtlAllocateHeapFunction)( - IN PVOID HeapHandle, - IN ULONG Flags, - IN SIZE_T Size); - -typedef BOOLEAN (WINAPI *RtlFreeHeapFunction)( - IN PVOID HeapHandle, - IN ULONG Flags, - IN PVOID HeapBase); - -typedef NTSTATUS (WINAPI *NtAllocateVirtualMemoryFunction) ( - IN HANDLE ProcessHandle, - IN OUT PVOID *BaseAddress, - IN ULONG_PTR ZeroBits, - IN OUT PSIZE_T RegionSize, - IN ULONG AllocationType, - IN ULONG Protect); - -typedef NTSTATUS (WINAPI *NtFreeVirtualMemoryFunction) ( - IN HANDLE ProcessHandle, - IN OUT PVOID *BaseAddress, - IN OUT PSIZE_T RegionSize, - IN ULONG FreeType); - -typedef enum _MEMORY_INFORMATION_CLASS { - MemoryBasicInformation = 0, - MemoryWorkingSetList, - MemorySectionName, - MemoryBasicVlmInformation -} MEMORY_INFORMATION_CLASS; - -typedef struct _MEMORY_SECTION_NAME { // Information Class 2 - UNICODE_STRING SectionFileName; -} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME; - -typedef NTSTATUS (WINAPI *NtQueryVirtualMemoryFunction)( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN MEMORY_INFORMATION_CLASS MemoryInformationClass, - OUT PVOID MemoryInformation, - IN SIZE_T MemoryInformationLength, - OUT PSIZE_T ReturnLength OPTIONAL); - -typedef NTSTATUS (WINAPI *NtProtectVirtualMemoryFunction)( - IN HANDLE ProcessHandle, - IN OUT PVOID* BaseAddress, - IN OUT PSIZE_T ProtectSize, - IN ULONG NewProtect, - OUT PULONG OldProtect); - -// ----------------------------------------------------------------------- -// Objects - -typedef enum _OBJECT_INFORMATION_CLASS { - ObjectBasicInformation, - ObjectNameInformation, - ObjectTypeInformation, - ObjectAllInformation, - ObjectDataInformation -} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS; - -typedef struct _OBJDIR_INFORMATION { - UNICODE_STRING ObjectName; - UNICODE_STRING ObjectTypeName; - BYTE Data[1]; -} OBJDIR_INFORMATION; - -typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION { - ULONG Attributes; - ACCESS_MASK GrantedAccess; - ULONG HandleCount; - ULONG PointerCount; - ULONG Reserved[10]; // reserved for internal use -} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION; - -typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION { - UNICODE_STRING TypeName; - ULONG Reserved[22]; // reserved for internal use -} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION; - -typedef enum _POOL_TYPE { - NonPagedPool, - PagedPool, - NonPagedPoolMustSucceed, - ReservedType, - NonPagedPoolCacheAligned, - PagedPoolCacheAligned, - NonPagedPoolCacheAlignedMustS -} POOL_TYPE; - -typedef struct _OBJECT_BASIC_INFORMATION { - ULONG Attributes; - ACCESS_MASK GrantedAccess; - ULONG HandleCount; - ULONG PointerCount; - ULONG PagedPoolUsage; - ULONG NonPagedPoolUsage; - ULONG Reserved[3]; - ULONG NameInformationLength; - ULONG TypeInformationLength; - ULONG SecurityDescriptorLength; - LARGE_INTEGER CreateTime; -} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION; - -typedef struct _OBJECT_TYPE_INFORMATION { - UNICODE_STRING Name; - ULONG TotalNumberOfObjects; - ULONG TotalNumberOfHandles; - ULONG TotalPagedPoolUsage; - ULONG TotalNonPagedPoolUsage; - ULONG TotalNamePoolUsage; - ULONG TotalHandleTableUsage; - ULONG HighWaterNumberOfObjects; - ULONG HighWaterNumberOfHandles; - ULONG HighWaterPagedPoolUsage; - ULONG HighWaterNonPagedPoolUsage; - ULONG HighWaterNamePoolUsage; - ULONG HighWaterHandleTableUsage; - ULONG InvalidAttributes; - GENERIC_MAPPING GenericMapping; - ULONG ValidAccess; - BOOLEAN SecurityRequired; - BOOLEAN MaintainHandleCount; - USHORT MaintainTypeList; - POOL_TYPE PoolType; - ULONG PagedPoolUsage; - ULONG NonPagedPoolUsage; -} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; - -typedef enum _SYSTEM_INFORMATION_CLASS { - SystemHandleInformation = 16 -} SYSTEM_INFORMATION_CLASS; - -typedef struct _SYSTEM_HANDLE_INFORMATION { - USHORT ProcessId; - USHORT CreatorBackTraceIndex; - UCHAR ObjectTypeNumber; - UCHAR Flags; - USHORT Handle; - PVOID Object; - ACCESS_MASK GrantedAccess; -} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; - -typedef struct _SYSTEM_HANDLE_INFORMATION_EX { - ULONG NumberOfHandles; - SYSTEM_HANDLE_INFORMATION Information[1]; -} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; - -typedef struct _OBJECT_NAME_INFORMATION { - UNICODE_STRING ObjectName; -} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; - -typedef NTSTATUS (WINAPI *NtQueryObjectFunction)( - IN HANDLE Handle, - IN OBJECT_INFORMATION_CLASS ObjectInformationClass, - OUT PVOID ObjectInformation OPTIONAL, - IN ULONG ObjectInformationLength, - OUT PULONG ReturnLength OPTIONAL); - -typedef NTSTATUS (WINAPI *NtDuplicateObjectFunction)( - IN HANDLE SourceProcess, - IN HANDLE SourceHandle, - IN HANDLE TargetProcess, - OUT PHANDLE TargetHandle, - IN ACCESS_MASK DesiredAccess, - IN ULONG Attributes, - IN ULONG Options); - -typedef NTSTATUS (WINAPI *NtSignalAndWaitForSingleObjectFunction)( - IN HANDLE HandleToSignal, - IN HANDLE HandleToWait, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout OPTIONAL); - -typedef NTSTATUS (WINAPI *NtQuerySystemInformation)( - IN SYSTEM_INFORMATION_CLASS SystemInformationClass, - OUT PVOID SystemInformation, - IN ULONG SystemInformationLength, - OUT PULONG ReturnLength); - -typedef NTSTATUS (WINAPI *NtQueryObject)( - IN HANDLE Handle, - IN OBJECT_INFORMATION_CLASS ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG ObjectInformationLength, - OUT PULONG ReturnLength); - -// ----------------------------------------------------------------------- -// Strings - -typedef int (__cdecl *_strnicmpFunction)( - IN const char* _Str1, - IN const char* _Str2, - IN size_t _MaxCount); - -typedef size_t (__cdecl *strlenFunction)( - IN const char * _Str); - -typedef size_t (__cdecl *wcslenFunction)( - IN const wchar_t* _Str); - -typedef void* (__cdecl *memcpyFunction)( - IN void* dest, - IN const void* src, - IN size_t count); - -typedef NTSTATUS (WINAPI *RtlAnsiStringToUnicodeStringFunction)( - IN OUT PUNICODE_STRING DestinationString, - IN PANSI_STRING SourceString, - IN BOOLEAN AllocateDestinationString); - -typedef LONG (WINAPI *RtlCompareUnicodeStringFunction)( - IN PCUNICODE_STRING String1, - IN PCUNICODE_STRING String2, - IN BOOLEAN CaseInSensitive); - -typedef VOID (WINAPI *RtlInitUnicodeStringFunction) ( - IN OUT PUNICODE_STRING DestinationString, - IN PCWSTR SourceString); - -typedef ULONG (WINAPI* RtlNtStatusToDosErrorFunction)(NTSTATUS status); - -typedef enum _EVENT_TYPE { - NotificationEvent, - SynchronizationEvent -} EVENT_TYPE, *PEVENT_TYPE; - -typedef NTSTATUS (WINAPI* NtCreateDirectoryObjectFunction) ( - PHANDLE DirectoryHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NtOpenDirectoryObjectFunction) ( - PHANDLE DirectoryHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NtQuerySymbolicLinkObjectFunction) ( - HANDLE LinkHandle, - PUNICODE_STRING LinkTarget, - PULONG ReturnedLength); - -typedef NTSTATUS (WINAPI* NtOpenSymbolicLinkObjectFunction) ( - PHANDLE LinkHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes); - -#define DIRECTORY_QUERY 0x0001 -#define DIRECTORY_TRAVERSE 0x0002 -#define DIRECTORY_CREATE_OBJECT 0x0004 -#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 -#define DIRECTORY_ALL_ACCESS 0x000F - -typedef NTSTATUS (WINAPI* NtCreateLowBoxToken)( - OUT PHANDLE token, - IN HANDLE original_handle, - IN ACCESS_MASK access, - IN POBJECT_ATTRIBUTES object_attribute, - IN PSID appcontainer_sid, - IN DWORD capabilityCount, - IN PSID_AND_ATTRIBUTES capabilities, - IN DWORD handle_count, - IN PHANDLE handles); - -typedef NTSTATUS(WINAPI *NtSetInformationProcess)( - IN HANDLE process_handle, - IN ULONG info_class, - IN PVOID process_information, - IN ULONG information_length); - -struct PROCESS_ACCESS_TOKEN { - HANDLE token; - HANDLE thread; -}; - -const unsigned int NtProcessInformationAccessToken = 9; - -// ----------------------------------------------------------------------- -// GDI OPM API and Supported Calls - -#define DXGKMDT_OPM_OMAC_SIZE 16 -#define DXGKMDT_OPM_128_BIT_RANDOM_NUMBER_SIZE 16 -#define DXGKMDT_OPM_ENCRYPTED_PARAMETERS_SIZE 256 -#define DXGKMDT_OPM_CONFIGURE_SETTING_DATA_SIZE 4056 -#define DXGKMDT_OPM_GET_INFORMATION_PARAMETERS_SIZE 4056 -#define DXGKMDT_OPM_REQUESTED_INFORMATION_SIZE 4076 -#define DXGKMDT_OPM_HDCP_KEY_SELECTION_VECTOR_SIZE 5 -#define DXGKMDT_OPM_PROTECTION_TYPE_SIZE 4 - -enum DXGKMDT_CERTIFICATE_TYPE { - DXGKMDT_OPM_CERTIFICATE = 0, - DXGKMDT_COPP_CERTIFICATE = 1, - DXGKMDT_UAB_CERTIFICATE = 2, - DXGKMDT_FORCE_ULONG = 0xFFFFFFFF -}; - -enum DXGKMDT_OPM_VIDEO_OUTPUT_SEMANTICS { - DXGKMDT_OPM_VOS_COPP_SEMANTICS = 0, - DXGKMDT_OPM_VOS_OPM_SEMANTICS = 1 -}; - -enum DXGKMDT_DPCP_PROTECTION_LEVEL { - DXGKMDT_OPM_DPCP_OFF = 0, - DXGKMDT_OPM_DPCP_ON = 1, - DXGKMDT_OPM_DPCP_FORCE_ULONG = 0x7fffffff -}; - -enum DXGKMDT_OPM_HDCP_PROTECTION_LEVEL { - DXGKMDT_OPM_HDCP_OFF = 0, - DXGKMDT_OPM_HDCP_ON = 1, - DXGKMDT_OPM_HDCP_FORCE_ULONG = 0x7fffffff -}; - -enum DXGKMDT_OPM_HDCP_FLAG { - DXGKMDT_OPM_HDCP_FLAG_NONE = 0x00, - DXGKMDT_OPM_HDCP_FLAG_REPEATER = 0x01 -}; - -enum DXGKMDT_OPM_PROTECTION_TYPE { - DXGKMDT_OPM_PROTECTION_TYPE_OTHER = 0x80000000, - DXGKMDT_OPM_PROTECTION_TYPE_NONE = 0x00000000, - DXGKMDT_OPM_PROTECTION_TYPE_COPP_COMPATIBLE_HDCP = 0x00000001, - DXGKMDT_OPM_PROTECTION_TYPE_ACP = 0x00000002, - DXGKMDT_OPM_PROTECTION_TYPE_CGMSA = 0x00000004, - DXGKMDT_OPM_PROTECTION_TYPE_HDCP = 0x00000008, - DXGKMDT_OPM_PROTECTION_TYPE_DPCP = 0x00000010, - DXGKMDT_OPM_PROTECTION_TYPE_MASK = 0x8000001F -}; - -typedef void* OPM_PROTECTED_OUTPUT_HANDLE; - -struct DXGKMDT_OPM_ENCRYPTED_PARAMETERS { - BYTE abEncryptedParameters[DXGKMDT_OPM_ENCRYPTED_PARAMETERS_SIZE]; -}; - -struct DXGKMDT_OPM_OMAC { - BYTE abOMAC[DXGKMDT_OPM_OMAC_SIZE]; -}; - -struct DXGKMDT_OPM_CONFIGURE_PARAMETERS { - DXGKMDT_OPM_OMAC omac; - GUID guidSetting; - ULONG ulSequenceNumber; - ULONG cbParametersSize; - BYTE abParameters[DXGKMDT_OPM_CONFIGURE_SETTING_DATA_SIZE]; -}; - -struct DXGKMDT_OPM_RANDOM_NUMBER { - BYTE abRandomNumber[DXGKMDT_OPM_128_BIT_RANDOM_NUMBER_SIZE]; -}; - -struct DXGKMDT_OPM_GET_INFO_PARAMETERS { - DXGKMDT_OPM_OMAC omac; - DXGKMDT_OPM_RANDOM_NUMBER rnRandomNumber; - GUID guidInformation; - ULONG ulSequenceNumber; - ULONG cbParametersSize; - BYTE abParameters[DXGKMDT_OPM_GET_INFORMATION_PARAMETERS_SIZE]; -}; - -struct DXGKMDT_OPM_REQUESTED_INFORMATION { - DXGKMDT_OPM_OMAC omac; - ULONG cbRequestedInformationSize; - BYTE abRequestedInformation[DXGKMDT_OPM_REQUESTED_INFORMATION_SIZE]; -}; - -struct DXGKMDT_OPM_SET_PROTECTION_LEVEL_PARAMETERS { - ULONG ulProtectionType; - ULONG ulProtectionLevel; - ULONG Reserved; - ULONG Reserved2; -}; - -struct DXGKMDT_OPM_STANDARD_INFORMATION { - DXGKMDT_OPM_RANDOM_NUMBER rnRandomNumber; - ULONG ulStatusFlags; - ULONG ulInformation; - ULONG ulReserved; - ULONG ulReserved2; -}; - -typedef NTSTATUS(WINAPI* GetSuggestedOPMProtectedOutputArraySizeFunction)( - PUNICODE_STRING device_name, - DWORD* suggested_output_array_size); - -typedef NTSTATUS(WINAPI* CreateOPMProtectedOutputsFunction)( - PUNICODE_STRING device_name, - DXGKMDT_OPM_VIDEO_OUTPUT_SEMANTICS vos, - DWORD output_array_size, - DWORD* num_in_output_array, - OPM_PROTECTED_OUTPUT_HANDLE* output_array); - -typedef NTSTATUS(WINAPI* GetCertificateFunction)( - PUNICODE_STRING device_name, - DXGKMDT_CERTIFICATE_TYPE certificate_type, - BYTE* certificate, - ULONG certificate_length); - -typedef NTSTATUS(WINAPI* GetCertificateSizeFunction)( - PUNICODE_STRING device_name, - DXGKMDT_CERTIFICATE_TYPE certificate_type, - ULONG* certificate_length); - -typedef NTSTATUS(WINAPI* GetCertificateByHandleFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output, - DXGKMDT_CERTIFICATE_TYPE certificate_type, - BYTE* certificate, - ULONG certificate_length); - -typedef NTSTATUS(WINAPI* GetCertificateSizeByHandleFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output, - DXGKMDT_CERTIFICATE_TYPE certificate_type, - ULONG* certificate_length); - -typedef NTSTATUS(WINAPI* DestroyOPMProtectedOutputFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output); - -typedef NTSTATUS(WINAPI* ConfigureOPMProtectedOutputFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output, - const DXGKMDT_OPM_CONFIGURE_PARAMETERS* parameters, - ULONG additional_parameters_size, - const BYTE* additional_parameters); - -typedef NTSTATUS(WINAPI* GetOPMInformationFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output, - const DXGKMDT_OPM_GET_INFO_PARAMETERS* parameters, - DXGKMDT_OPM_REQUESTED_INFORMATION* requested_information); - -typedef NTSTATUS(WINAPI* GetOPMRandomNumberFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output, - DXGKMDT_OPM_RANDOM_NUMBER* random_number); - -typedef NTSTATUS(WINAPI* SetOPMSigningKeyAndSequenceNumbersFunction)( - OPM_PROTECTED_OUTPUT_HANDLE protected_output, - const DXGKMDT_OPM_ENCRYPTED_PARAMETERS* parameters); - -#endif // SANDBOX_WIN_SRC_NT_INTERNALS_H__ - diff --git a/sandbox/win/src/policy_engine_params.h b/sandbox/win/src/policy_engine_params.h deleted file mode 100644 index fb4c00e3da..0000000000 --- a/sandbox/win/src/policy_engine_params.h +++ /dev/null @@ -1,202 +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_SRC_POLICY_ENGINE_PARAMS_H__ -#define SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__ - -#include <stdint.h> - -#include "sandbox/win/src/internal_types.h" -#include "sandbox/win/src/nt_internals.h" -#include "sandbox/win/src/sandbox_nt_util.h" - -// This header defines the classes that allow the low level policy to select -// the input parameters. In order to better make sense of this header is -// recommended that you check policy_engine_opcodes.h first. - -namespace sandbox { - -// Models the set of interesting parameters of an intercepted system call -// normally you don't create objects of this class directly, instead you -// use the POLPARAMS_XXX macros. -// For example, if an intercepted function has the following signature: -// -// NTSTATUS NtOpenFileFunction (PHANDLE FileHandle, -// ACCESS_MASK DesiredAccess, -// POBJECT_ATTRIBUTES ObjectAttributes, -// PIO_STATUS_BLOCK IoStatusBlock, -// ULONG ShareAccess, -// ULONG OpenOptions); -// -// You could say that the following parameters are of interest to policy: -// -// POLPARAMS_BEGIN(open_params) -// POLPARAM(DESIRED_ACCESS) -// POLPARAM(OBJECT_NAME) -// POLPARAM(SECURITY_DESCRIPTOR) -// POLPARAM(IO_STATUS) -// POLPARAM(OPEN_OPTIONS) -// POLPARAMS_END; -// -// and the actual code will use this for defining the parameters: -// -// CountedParameterSet<open_params> p; -// p[open_params::DESIRED_ACCESS] = ParamPickerMake(DesiredAccess); -// p[open_params::OBJECT_NAME] = -// ParamPickerMake(ObjectAttributes->ObjectName); -// p[open_params::SECURITY_DESCRIPTOR] = -// ParamPickerMake(ObjectAttributes->SecurityDescriptor); -// p[open_params::IO_STATUS] = ParamPickerMake(IoStatusBlock); -// p[open_params::OPEN_OPTIONS] = ParamPickerMake(OpenOptions); -// -// These will create an stack-allocated array of ParameterSet objects which -// have each 1) the address of the parameter 2) a numeric id that encodes the -// original C++ type. This allows the policy to treat any set of supported -// argument types uniformily and with some type safety. -// -// TODO(cpu): support not fully implemented yet for unicode string and will -// probably add other types as well. -class ParameterSet { - public: - ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {} - - // Retrieve the stored parameter. If the type does not match ulong fail. - bool Get(uint32_t* destination) const { - if (real_type_ != UINT32_TYPE) { - return false; - } - *destination = Void2TypePointerCopy<uint32_t>(); - return true; - } - - // Retrieve the stored parameter. If the type does not match void* fail. - bool Get(const void** destination) const { - if (real_type_ != VOIDPTR_TYPE) { - return false; - } - *destination = Void2TypePointerCopy<void*>(); - return true; - } - - // Retrieve the stored parameter. If the type does not match wchar_t* fail. - bool Get(const wchar_t** destination) const { - if (real_type_ != WCHAR_TYPE) { - return false; - } - *destination = Void2TypePointerCopy<const wchar_t*>(); - return true; - } - - // False if the parameter is not properly initialized. - bool IsValid() const { - return real_type_ != INVALID_TYPE; - } - - protected: - // The constructor can only be called by derived types, which should - // safely provide the real_type and the address of the argument. - ParameterSet(ArgType real_type, const void* address) - : real_type_(real_type), address_(address) { - } - - private: - // This template provides the same functionality as bits_cast but - // it works with pointer while the former works only with references. - template <typename T> - T Void2TypePointerCopy() const { - return *(reinterpret_cast<const T*>(address_)); - } - - ArgType real_type_; - const void* address_; -}; - -// To safely infer the type, we use a set of template specializations -// in ParameterSetEx with a template function ParamPickerMake to do the -// parameter type deduction. - -// Base template class. Not implemented so using unsupported types should -// fail to compile. -template <typename T> -class ParameterSetEx : public ParameterSet { - public: - ParameterSetEx(const void* address); -}; - -template<> -class ParameterSetEx<void const*> : public ParameterSet { - public: - ParameterSetEx(const void* address) - : ParameterSet(VOIDPTR_TYPE, address) {} -}; - -template<> -class ParameterSetEx<void*> : public ParameterSet { - public: - ParameterSetEx(const void* address) - : ParameterSet(VOIDPTR_TYPE, address) {} -}; - - -template<> -class ParameterSetEx<wchar_t*> : public ParameterSet { - public: - ParameterSetEx(const void* address) - : ParameterSet(WCHAR_TYPE, address) {} -}; - -template<> -class ParameterSetEx<wchar_t const*> : public ParameterSet { - public: - ParameterSetEx(const void* address) - : ParameterSet(WCHAR_TYPE, address) {} -}; - -template <> -class ParameterSetEx<uint32_t> : public ParameterSet { - public: - ParameterSetEx(const void* address) - : ParameterSet(UINT32_TYPE, address) {} -}; - -template<> -class ParameterSetEx<UNICODE_STRING> : public ParameterSet { - public: - ParameterSetEx(const void* address) - : ParameterSet(UNISTR_TYPE, address) {} -}; - -template <typename T> -ParameterSet ParamPickerMake(T& parameter) { - return ParameterSetEx<T>(¶meter); -}; - -struct CountedParameterSetBase { - int count; - ParameterSet parameters[1]; -}; - -// This template defines the actual list of policy parameters for a given -// interception. -// Warning: This template stores the address to the actual variables, in -// other words, the values are not copied. -template <typename T> -struct CountedParameterSet { - CountedParameterSet() : count(T::PolParamLast) {} - - ParameterSet& operator[](typename T::Args n) { - return parameters[n]; - } - - CountedParameterSetBase* GetBase() { - return reinterpret_cast<CountedParameterSetBase*>(this); - } - - int count; - ParameterSet parameters[T::PolParamLast]; -}; - -} // namespace sandbox - -#endif // SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__ diff --git a/sandbox/win/src/policy_params.h b/sandbox/win/src/policy_params.h deleted file mode 100644 index e051d2b59d..0000000000 --- a/sandbox/win/src/policy_params.h +++ /dev/null @@ -1,67 +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_SRC_POLICY_PARAMS_H__ -#define SANDBOX_SRC_POLICY_PARAMS_H__ - -#include "sandbox/win/src/policy_engine_params.h" - -namespace sandbox { - -class ParameterSet; - -// Warning: The following macros store the address to the actual variables, in -// other words, the values are not copied. -#define POLPARAMS_BEGIN(type) class type { public: enum Args { -#define POLPARAM(arg) arg, -#define POLPARAMS_END(type) PolParamLast }; }; \ - typedef sandbox::ParameterSet type##Array [type::PolParamLast]; - -// Policy parameters for file open / create. -POLPARAMS_BEGIN(OpenFile) - POLPARAM(NAME) - POLPARAM(BROKER) // TRUE if called from the broker. - POLPARAM(ACCESS) - POLPARAM(DISPOSITION) - POLPARAM(OPTIONS) -POLPARAMS_END(OpenFile) - -// Policy parameter for name-based policies. -POLPARAMS_BEGIN(FileName) - POLPARAM(NAME) - POLPARAM(BROKER) // TRUE if called from the broker. -POLPARAMS_END(FileName) - -static_assert(OpenFile::NAME == static_cast<int>(FileName::NAME), - "to simplify fs policies"); -static_assert(OpenFile::BROKER == static_cast<int>(FileName::BROKER), - "to simplify fs policies"); - -// Policy parameter for name-based policies. -POLPARAMS_BEGIN(NameBased) - POLPARAM(NAME) -POLPARAMS_END(NameBased) - -// Policy parameters for open event. -POLPARAMS_BEGIN(OpenEventParams) - POLPARAM(NAME) - POLPARAM(ACCESS) -POLPARAMS_END(OpenEventParams) - -// Policy Parameters for reg open / create. -POLPARAMS_BEGIN(OpenKey) - POLPARAM(NAME) - POLPARAM(ACCESS) -POLPARAMS_END(OpenKey) - -// Policy parameter for name-based policies. -POLPARAMS_BEGIN(HandleTarget) - POLPARAM(NAME) - POLPARAM(TARGET) -POLPARAMS_END(HandleTarget) - - -} // namespace sandbox - -#endif // SANDBOX_SRC_POLICY_PARAMS_H__ diff --git a/sandbox/win/src/sandbox.vcproj b/sandbox/win/src/sandbox.vcproj deleted file mode 100644 index 229441cbd5..0000000000 --- a/sandbox/win/src/sandbox.vcproj +++ /dev/null @@ -1,648 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="sandbox" - ProjectGUID="{881F6A97-D539-4C48-B401-DF04385B2343}" - RootNamespace="sandbox" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - ConfigurationType="4" - InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\testing\using_gtest.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="VCLibrarianTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - ConfigurationType="4" - InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLibrarianTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="security" - > - <File - RelativePath=".\acl.cc" - > - </File> - <File - RelativePath=".\acl.h" - > - </File> - <File - RelativePath=".\dep.cc" - > - </File> - <File - RelativePath=".\dep.h" - > - </File> - <File - RelativePath=".\job.cc" - > - </File> - <File - RelativePath=".\job.h" - > - </File> - <File - RelativePath=".\restricted_token.cc" - > - </File> - <File - RelativePath=".\restricted_token.h" - > - </File> - <File - RelativePath=".\restricted_token_utils.cc" - > - </File> - <File - RelativePath=".\restricted_token_utils.h" - > - </File> - <File - RelativePath=".\security_level.h" - > - </File> - <File - RelativePath=".\sid.cc" - > - </File> - <File - RelativePath=".\sid.h" - > - </File> - <File - RelativePath=".\window.cc" - > - </File> - <File - RelativePath=".\window.h" - > - </File> - </Filter> - <Filter - Name="Interception" - > - <File - RelativePath=".\eat_resolver.cc" - > - </File> - <File - RelativePath=".\eat_resolver.h" - > - </File> - <File - RelativePath=".\interception.cc" - > - </File> - <File - RelativePath=".\interception.h" - > - </File> - <File - RelativePath=".\interception_agent.cc" - > - </File> - <File - RelativePath=".\interception_agent.h" - > - </File> - <File - RelativePath=".\interception_internal.h" - > - </File> - <File - RelativePath=".\pe_image.cc" - > - </File> - <File - RelativePath=".\pe_image.h" - > - </File> - <File - RelativePath=".\resolver.cc" - > - </File> - <File - RelativePath=".\resolver.h" - > - </File> - <File - RelativePath=".\service_resolver.cc" - > - </File> - <File - RelativePath=".\service_resolver.h" - > - </File> - <File - RelativePath=".\sidestep_resolver.cc" - > - </File> - <File - RelativePath=".\sidestep_resolver.h" - > - </File> - <File - RelativePath=".\target_interceptions.cc" - > - </File> - <File - RelativePath=".\target_interceptions.h" - > - </File> - <File - RelativePath=".\Wow64.cc" - > - </File> - <File - RelativePath=".\Wow64.h" - > - </File> - <Filter - Name="sidestep" - > - <File - RelativePath=".\sidestep\ia32_modrm_map.cpp" - > - </File> - <File - RelativePath=".\sidestep\ia32_opcode_map.cpp" - > - </File> - <File - RelativePath=".\sidestep\mini_disassembler.cpp" - > - </File> - <File - RelativePath=".\sidestep\mini_disassembler.h" - > - </File> - <File - RelativePath=".\sidestep\mini_disassembler_types.h" - > - </File> - <File - RelativePath=".\sidestep\preamble_patcher.h" - > - </File> - <File - RelativePath=".\sidestep\preamble_patcher_with_stub.cpp" - > - </File> - </Filter> - </Filter> - <Filter - Name="nt_level" - > - <File - RelativePath=".\nt_internals.h" - > - </File> - <File - RelativePath=".\policy_target.cc" - > - </File> - <File - RelativePath=".\policy_target.h" - > - </File> - <File - RelativePath=".\sandbox_nt_types.h" - > - </File> - <File - RelativePath=".\sandbox_nt_util.cc" - > - </File> - <File - RelativePath=".\sandbox_nt_util.h" - > - </File> - </Filter> - <Filter - Name="Policy_handlers" - > - <File - RelativePath=".\filesystem_dispatcher.cc" - > - </File> - <File - RelativePath=".\filesystem_dispatcher.h" - > - </File> - <File - RelativePath=".\filesystem_interception.cc" - > - </File> - <File - RelativePath=".\filesystem_interception.h" - > - </File> - <File - RelativePath=".\filesystem_policy.cc" - > - </File> - <File - RelativePath=".\filesystem_policy.h" - > - </File> - <File - RelativePath=".\named_pipe_dispatcher.cc" - > - </File> - <File - RelativePath=".\named_pipe_dispatcher.h" - > - </File> - <File - RelativePath=".\named_pipe_interception.cc" - > - </File> - <File - RelativePath=".\named_pipe_interception.h" - > - </File> - <File - RelativePath=".\named_pipe_policy.cc" - > - </File> - <File - RelativePath=".\named_pipe_policy.h" - > - </File> - <File - RelativePath=".\policy_params.h" - > - </File> - <File - RelativePath=".\process_thread_dispatcher.cc" - > - </File> - <File - RelativePath=".\process_thread_dispatcher.h" - > - </File> - <File - RelativePath=".\process_thread_interception.cc" - > - </File> - <File - RelativePath=".\process_thread_interception.h" - > - </File> - <File - RelativePath=".\process_thread_policy.cc" - > - </File> - <File - RelativePath=".\process_thread_policy.h" - > - </File> - <File - RelativePath=".\registry_dispatcher.cc" - > - </File> - <File - RelativePath=".\registry_dispatcher.h" - > - </File> - <File - RelativePath=".\registry_interception.cc" - > - </File> - <File - RelativePath=".\registry_interception.h" - > - </File> - <File - RelativePath=".\registry_policy.cc" - > - </File> - <File - RelativePath=".\registry_policy.h" - > - </File> - <File - RelativePath=".\sync_dispatcher.cc" - > - </File> - <File - RelativePath=".\sync_dispatcher.h" - > - </File> - <File - RelativePath=".\sync_interception.cc" - > - </File> - <File - RelativePath=".\sync_interception.h" - > - </File> - <File - RelativePath=".\sync_policy.cc" - > - </File> - <File - RelativePath=".\sync_policy.h" - > - </File> - </Filter> - <Filter - Name="IPC" - > - <File - RelativePath=".\crosscall_client.h" - > - </File> - <File - RelativePath=".\crosscall_params.h" - > - </File> - <File - RelativePath=".\crosscall_server.cc" - > - </File> - <File - RelativePath=".\crosscall_server.h" - > - </File> - <File - RelativePath=".\ipc_tags.h" - > - </File> - <File - RelativePath=".\sharedmem_ipc_client.cc" - > - </File> - <File - RelativePath=".\sharedmem_ipc_client.h" - > - </File> - <File - RelativePath=".\sharedmem_ipc_server.cc" - > - </File> - <File - RelativePath=".\sharedmem_ipc_server.h" - > - </File> - </Filter> - <Filter - Name="Policy_base" - > - <File - RelativePath=".\policy_engine_opcodes.cc" - > - </File> - <File - RelativePath=".\policy_engine_opcodes.h" - > - </File> - <File - RelativePath=".\policy_engine_params.h" - > - </File> - <File - RelativePath=".\policy_engine_processor.cc" - > - </File> - <File - RelativePath=".\policy_engine_processor.h" - > - </File> - <File - RelativePath=".\policy_low_level.cc" - > - </File> - <File - RelativePath=".\policy_low_level.h" - > - </File> - <File - RelativePath=".\sandbox_policy_base.cc" - > - </File> - <File - RelativePath=".\sandbox_policy_base.h" - > - </File> - </Filter> - <File - RelativePath=".\broker_services.cc" - > - </File> - <File - RelativePath=".\broker_services.h" - > - </File> - <File - RelativePath=".\internal_types.h" - > - </File> - <File - RelativePath=".\policy_broker.cc" - > - </File> - <File - RelativePath=".\policy_broker.h" - > - </File> - <File - RelativePath=".\sandbox.cc" - > - </File> - <File - RelativePath=".\sandbox.h" - > - </File> - <File - RelativePath=".\sandbox_factory.h" - > - </File> - <File - RelativePath=".\sandbox_policy.h" - > - </File> - <File - RelativePath=".\sandbox_types.h" - > - </File> - <File - RelativePath=".\sandbox_utils.cc" - > - </File> - <File - RelativePath=".\sandbox_utils.h" - > - </File> - <File - RelativePath=".\shared_handles.cc" - > - </File> - <File - RelativePath=".\shared_handles.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> - <File - RelativePath=".\target_process.cc" - > - </File> - <File - RelativePath=".\target_process.h" - > - </File> - <File - RelativePath=".\target_services.cc" - > - </File> - <File - RelativePath=".\target_services.h" - > - </File> - <File - RelativePath=".\win2k_threadpool.cc" - > - </File> - <File - RelativePath=".\win2k_threadpool.h" - > - </File> - <File - RelativePath=".\win_utils.cc" - > - </File> - <File - RelativePath=".\win_utils.h" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/sandbox/win/src/sandbox_factory.h b/sandbox/win/src/sandbox_factory.h deleted file mode 100644 index f5888ffcda..0000000000 --- a/sandbox/win/src/sandbox_factory.h +++ /dev/null @@ -1,51 +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_SRC_SANDBOX_FACTORY_H__ -#define SANDBOX_SRC_SANDBOX_FACTORY_H__ - -#include "base/macros.h" -#include "sandbox/win/src/sandbox.h" - -// SandboxFactory is a set of static methods to get access to the broker -// or target services object. Only one of the two methods (GetBrokerServices, -// GetTargetServices) will return a non-null pointer and that should be used -// as the indication that the process is the broker or the target: -// -// BrokerServices* broker_services = SandboxFactory::GetBrokerServices(); -// if (NULL != broker_services) { -// //we are the broker, call broker api here -// broker_services->Init(); -// } else { -// TargetServices* target_services = SandboxFactory::GetTargetServices(); -// if (NULL != target_services) { -// //we are the target, call target api here -// target_services->Init(); -// } -// -// The methods in this class are expected to be called from a single thread -// -// The Sandbox library needs to be linked against the main executable, but -// sometimes the API calls are issued from a DLL that loads into the exe -// process. These factory methods then need to be called from the main -// exe and the interface pointers then can be safely passed to the DLL where -// the Sandbox API calls are made. -namespace sandbox { - -class SandboxFactory { - public: - // Returns the Broker API interface, returns NULL if this process is the - // target. - static BrokerServices* GetBrokerServices(); - - // Returns the Target API interface, returns NULL if this process is the - // broker. - static TargetServices* GetTargetServices(); - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxFactory); -}; - -} // namespace sandbox - -#endif // SANDBOX_SRC_SANDBOX_FACTORY_H__ diff --git a/sandbox/win/src/sandbox_nt_types.h b/sandbox/win/src/sandbox_nt_types.h deleted file mode 100644 index a4a88bba7c..0000000000 --- a/sandbox/win/src/sandbox_nt_types.h +++ /dev/null @@ -1,46 +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_SRC_SANDBOX_NT_TYPES_H__ -#define SANDBOX_SRC_SANDBOX_NT_TYPES_H__ - -#include "sandbox/win/src/nt_internals.h" - -namespace sandbox { - -struct NtExports { - NtAllocateVirtualMemoryFunction AllocateVirtualMemory; - NtCloseFunction Close; - NtDuplicateObjectFunction DuplicateObject; - NtFreeVirtualMemoryFunction FreeVirtualMemory; - NtMapViewOfSectionFunction MapViewOfSection; - NtProtectVirtualMemoryFunction ProtectVirtualMemory; - NtQueryInformationProcessFunction QueryInformationProcess; - NtQueryObjectFunction QueryObject; - NtQuerySectionFunction QuerySection; - NtQueryVirtualMemoryFunction QueryVirtualMemory; - NtUnmapViewOfSectionFunction UnmapViewOfSection; - RtlAllocateHeapFunction RtlAllocateHeap; - RtlAnsiStringToUnicodeStringFunction RtlAnsiStringToUnicodeString; - RtlCompareUnicodeStringFunction RtlCompareUnicodeString; - RtlCreateHeapFunction RtlCreateHeap; - RtlCreateUserThreadFunction RtlCreateUserThread; - RtlDestroyHeapFunction RtlDestroyHeap; - RtlFreeHeapFunction RtlFreeHeap; - _strnicmpFunction _strnicmp; - strlenFunction strlen; - wcslenFunction wcslen; - memcpyFunction memcpy; -}; - -// This is the value used for the ntdll level allocator. -enum AllocationType { - NT_ALLOC, - NT_PAGE -}; - -} // namespace sandbox - - -#endif // SANDBOX_SRC_SANDBOX_NT_TYPES_H__ diff --git a/sandbox/win/src/sandbox_policy.h b/sandbox/win/src/sandbox_policy.h deleted file mode 100644 index c0916ea6de..0000000000 --- a/sandbox/win/src/sandbox_policy.h +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (c) 2012 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_WIN_SRC_SANDBOX_POLICY_H_ -#define SANDBOX_WIN_SRC_SANDBOX_POLICY_H_ - -#include <stddef.h> -#include <stdint.h> - -#include "base/strings/string16.h" -#include "sandbox/win/src/sandbox_types.h" -#include "sandbox/win/src/security_level.h" - -namespace sandbox { - -class TargetPolicy { - public: - // Windows subsystems that can have specific rules. - // Note: The process subsystem(SUBSY_PROCESS) does not evaluate the request - // exactly like the CreateProcess API does. See the comment at the top of - // process_thread_dispatcher.cc for more details. - enum SubSystem { - SUBSYS_FILES, // Creation and opening of files and pipes. - SUBSYS_NAMED_PIPES, // Creation of named pipes. - SUBSYS_PROCESS, // Creation of child processes. - SUBSYS_REGISTRY, // Creation and opening of registry keys. - SUBSYS_SYNC, // Creation of named sync objects. - SUBSYS_WIN32K_LOCKDOWN // Win32K Lockdown related policy. - }; - - // Allowable semantics when a rule is matched. - enum Semantics { - FILES_ALLOW_ANY, // Allows open or create for any kind of access that - // the file system supports. - FILES_ALLOW_READONLY, // Allows open or create with read access only. - FILES_ALLOW_QUERY, // Allows access to query the attributes of a file. - FILES_ALLOW_DIR_ANY, // Allows open or create with directory semantics - // only. - NAMEDPIPES_ALLOW_ANY, // Allows creation of a named pipe. - PROCESS_MIN_EXEC, // Allows to create a process with minimal rights - // over the resulting process and thread handles. - // No other parameters besides the command line are - // passed to the child process. - PROCESS_ALL_EXEC, // Allows the creation of a process and return full - // access on the returned handles. - // This flag can be used only when the main token of - // the sandboxed application is at least INTERACTIVE. - EVENTS_ALLOW_ANY, // Allows the creation of an event with full access. - EVENTS_ALLOW_READONLY, // Allows opening an even with synchronize access. - REG_ALLOW_READONLY, // Allows readonly access to a registry key. - REG_ALLOW_ANY, // Allows read and write access to a registry key. - FAKE_USER_GDI_INIT, // Fakes user32 and gdi32 initialization. This can - // be used to allow the DLLs to load and initialize - // even if the process cannot access that subsystem. - IMPLEMENT_OPM_APIS // Implements FAKE_USER_GDI_INIT and also exposes - // IPC calls to handle Output Protection Manager - // APIs. - }; - - // Increments the reference count of this object. The reference count must - // be incremented if this interface is given to another component. - virtual void AddRef() = 0; - - // Decrements the reference count of this object. When the reference count - // is zero the object is automatically destroyed. - // Indicates that the caller is done with this interface. After calling - // release no other method should be called. - virtual void Release() = 0; - - // Sets the security level for the target process' two tokens. - // This setting is permanent and cannot be changed once the target process is - // spawned. - // initial: the security level for the initial token. This is the token that - // is used by the process from the creation of the process until the moment - // the process calls TargetServices::LowerToken() or the process calls - // win32's RevertToSelf(). Once this happens the initial token is no longer - // available and the lockdown token is in effect. Using an initial token is - // not compatible with AppContainer, see SetAppContainer. - // lockdown: the security level for the token that comes into force after the - // process calls TargetServices::LowerToken() or the process calls - // RevertToSelf(). See the explanation of each level in the TokenLevel - // definition. - // Return value: SBOX_ALL_OK if the setting succeeds and false otherwise. - // Returns false if the lockdown value is more permissive than the initial - // value. - // - // Important: most of the sandbox-provided security relies on this single - // setting. The caller should strive to set the lockdown level as restricted - // as possible. - virtual ResultCode SetTokenLevel(TokenLevel initial, TokenLevel lockdown) = 0; - - // Returns the initial token level. - virtual TokenLevel GetInitialTokenLevel() const = 0; - - // Returns the lockdown token level. - virtual TokenLevel GetLockdownTokenLevel() const = 0; - - // Sets the security level of the Job Object to which the target process will - // belong. This setting is permanent and cannot be changed once the target - // process is spawned. The job controls the global security settings which - // can not be specified in the token security profile. - // job_level: the security level for the job. See the explanation of each - // level in the JobLevel definition. - // ui_exceptions: specify what specific rights that are disabled in the - // chosen job_level that need to be granted. Use this parameter to avoid - // selecting the next permissive job level unless you need all the rights - // that are granted in such level. - // The exceptions can be specified as a combination of the following - // constants: - // JOB_OBJECT_UILIMIT_HANDLES : grant access to all user-mode handles. These - // include windows, icons, menus and various GDI objects. In addition the - // target process can set hooks, and broadcast messages to other processes - // that belong to the same desktop. - // JOB_OBJECT_UILIMIT_READCLIPBOARD : grant read-only access to the clipboard. - // JOB_OBJECT_UILIMIT_WRITECLIPBOARD : grant write access to the clipboard. - // JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS : allow changes to the system-wide - // parameters as defined by the Win32 call SystemParametersInfo(). - // JOB_OBJECT_UILIMIT_DISPLAYSETTINGS : allow programmatic changes to the - // display settings. - // JOB_OBJECT_UILIMIT_GLOBALATOMS : allow access to the global atoms table. - // JOB_OBJECT_UILIMIT_DESKTOP : allow the creation of new desktops. - // JOB_OBJECT_UILIMIT_EXITWINDOWS : allow the call to ExitWindows(). - // - // Return value: SBOX_ALL_OK if the setting succeeds and false otherwise. - // - // Note: JOB_OBJECT_XXXX constants are defined in winnt.h and documented at - // length in: - // http://msdn2.microsoft.com/en-us/library/ms684152.aspx - // - // Note: the recommended level is JOB_RESTRICTED or JOB_LOCKDOWN. - virtual ResultCode SetJobLevel(JobLevel job_level, - uint32_t ui_exceptions) = 0; - - // Returns the job level. - virtual JobLevel GetJobLevel() const = 0; - - // Sets a hard limit on the size of the commit set for the sandboxed process. - // If the limit is reached, the process will be terminated with - // SBOX_FATAL_MEMORY_EXCEEDED (7012). - virtual ResultCode SetJobMemoryLimit(size_t memory_limit) = 0; - - // Specifies the desktop on which the application is going to run. If the - // desktop does not exist, it will be created. If alternate_winstation is - // set to true, the desktop will be created on an alternate window station. - virtual ResultCode SetAlternateDesktop(bool alternate_winstation) = 0; - - // Returns the name of the alternate desktop used. If an alternate window - // station is specified, the name is prepended by the window station name, - // followed by a backslash. - virtual base::string16 GetAlternateDesktop() const = 0; - - // Precreates the desktop and window station, if any. - virtual ResultCode CreateAlternateDesktop(bool alternate_winstation) = 0; - - // Destroys the desktop and windows station. - virtual void DestroyAlternateDesktop() = 0; - - // Sets the integrity level of the process in the sandbox. Both the initial - // token and the main token will be affected by this. If the integrity level - // is set to a level higher than the current level, the sandbox will fail - // to start. - virtual ResultCode SetIntegrityLevel(IntegrityLevel level) = 0; - - // Returns the initial integrity level used. - virtual IntegrityLevel GetIntegrityLevel() const = 0; - - // Sets the integrity level of the process in the sandbox. The integrity level - // will not take effect before you call LowerToken. User Interface Privilege - // Isolation is not affected by this setting and will remain off for the - // process in the sandbox. If the integrity level is set to a level higher - // than the current level, the sandbox will fail to start. - virtual ResultCode SetDelayedIntegrityLevel(IntegrityLevel level) = 0; - - // Sets a capability to be enabled for the sandboxed process' AppContainer. - virtual ResultCode SetCapability(const wchar_t* sid) = 0; - - // Sets the LowBox token for sandboxed process. This is mutually exclusive - // with SetAppContainer method. - virtual ResultCode SetLowBox(const wchar_t* sid) = 0; - - // Sets the mitigations enabled when the process is created. Most of these - // are implemented as attributes passed via STARTUPINFOEX. So they take - // effect before any thread in the target executes. The declaration of - // MitigationFlags is followed by a detailed description of each flag. - virtual ResultCode SetProcessMitigations(MitigationFlags flags) = 0; - - // Returns the currently set mitigation flags. - virtual MitigationFlags GetProcessMitigations() = 0; - - // Sets process mitigation flags that don't take effect before the call to - // LowerToken(). - virtual ResultCode SetDelayedProcessMitigations(MitigationFlags flags) = 0; - - // Returns the currently set delayed mitigation flags. - virtual MitigationFlags GetDelayedProcessMitigations() const = 0; - - // Disconnect the target from CSRSS when TargetServices::LowerToken() is - // called inside the target. - virtual void SetDisconnectCsrss() = 0; - - // Sets the interceptions to operate in strict mode. By default, interceptions - // are performed in "relaxed" mode, where if something inside NTDLL.DLL is - // already patched we attempt to intercept it anyway. Setting interceptions - // to strict mode means that when we detect that the function is patched we'll - // refuse to perform the interception. - virtual void SetStrictInterceptions() = 0; - - // Set the handles the target process should inherit for stdout and - // stderr. The handles the caller passes must remain valid for the - // lifetime of the policy object. This only has an effect on - // Windows Vista and later versions. These methods accept pipe and - // file handles, but not console handles. - virtual ResultCode SetStdoutHandle(HANDLE handle) = 0; - virtual ResultCode SetStderrHandle(HANDLE handle) = 0; - - // Adds a policy rule effective for processes spawned using this policy. - // subsystem: One of the above enumerated windows subsystems. - // semantics: One of the above enumerated FileSemantics. - // pattern: A specific full path or a full path with wildcard patterns. - // The valid wildcards are: - // '*' : Matches zero or more character. Only one in series allowed. - // '?' : Matches a single character. One or more in series are allowed. - // Examples: - // "c:\\documents and settings\\vince\\*.dmp" - // "c:\\documents and settings\\*\\crashdumps\\*.dmp" - // "c:\\temp\\app_log_?????_chrome.txt" - virtual ResultCode AddRule(SubSystem subsystem, Semantics semantics, - const wchar_t* pattern) = 0; - - // Adds a dll that will be unloaded in the target process before it gets - // a chance to initialize itself. Typically, dlls that cause the target - // to crash go here. - virtual ResultCode AddDllToUnload(const wchar_t* dll_name) = 0; - - // Adds a handle that will be closed in the target process after lockdown. - // A NULL value for handle_name indicates all handles of the specified type. - // An empty string for handle_name indicates the handle is unnamed. - virtual ResultCode AddKernelObjectToClose(const wchar_t* handle_type, - const wchar_t* handle_name) = 0; - - // Adds a handle that will be shared with the target process. Does not take - // ownership of the handle. - virtual void AddHandleToShare(HANDLE handle) = 0; - - // Locks down the default DACL of the created lockdown and initial tokens - // to restrict what other processes are allowed to access a process' kernel - // resources. - virtual void SetLockdownDefaultDacl() = 0; - - // Enable OPM API redirection when in Win32k lockdown. - virtual void SetEnableOPMRedirection() = 0; - // Enable OPM API emulation when in Win32k lockdown. - virtual bool GetEnableOPMRedirection() = 0; -}; - -} // namespace sandbox - - -#endif // SANDBOX_WIN_SRC_SANDBOX_POLICY_H_ diff --git a/sandbox/win/src/sandbox_types.h b/sandbox/win/src/sandbox_types.h deleted file mode 100644 index ae36ef5c95..0000000000 --- a/sandbox/win/src/sandbox_types.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2012 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_WIN_SRC_SANDBOX_TYPES_H_ -#define SANDBOX_WIN_SRC_SANDBOX_TYPES_H_ - -#include "base/process/kill.h" -#include "base/process/launch.h" - -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. -// -enum ResultCode : int { - SBOX_ALL_OK = 0, - // Error is originating on the win32 layer. Call GetlastError() for more - // information. - SBOX_ERROR_GENERIC = 1, - // An invalid combination of parameters was given to the API. - SBOX_ERROR_BAD_PARAMS = 2, - // The desired operation is not supported at this time. - SBOX_ERROR_UNSUPPORTED = 3, - // The request requires more memory that allocated or available. - SBOX_ERROR_NO_SPACE = 4, - // The ipc service requested does not exist. - SBOX_ERROR_INVALID_IPC = 5, - // The ipc service did not complete. - SBOX_ERROR_FAILED_IPC = 6, - // The requested handle was not found. - SBOX_ERROR_NO_HANDLE = 7, - // This function was not expected to be called at this time. - SBOX_ERROR_UNEXPECTED_CALL = 8, - // WaitForAllTargets is already called. - SBOX_ERROR_WAIT_ALREADY_CALLED = 9, - // A channel error prevented DoCall from executing. - SBOX_ERROR_CHANNEL_ERROR = 10, - // Failed to create the alternate desktop. - SBOX_ERROR_CANNOT_CREATE_DESKTOP = 11, - // Failed to create the alternate window station. - SBOX_ERROR_CANNOT_CREATE_WINSTATION = 12, - // Failed to switch back to the interactive window station. - SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION = 13, - // The supplied AppContainer is not valid. - SBOX_ERROR_INVALID_APP_CONTAINER = 14, - // The supplied capability is not valid. - SBOX_ERROR_INVALID_CAPABILITY = 15, - // There is a failure initializing the AppContainer. - SBOX_ERROR_CANNOT_INIT_APPCONTAINER = 16, - // Initializing or updating ProcThreadAttributes failed. - SBOX_ERROR_PROC_THREAD_ATTRIBUTES = 17, - // Error in creating process. - SBOX_ERROR_CREATE_PROCESS = 18, - // Failure calling delegate PreSpawnTarget. - SBOX_ERROR_DELEGATE_PRE_SPAWN = 19, - // Could not assign process to job object. - SBOX_ERROR_ASSIGN_PROCESS_TO_JOB_OBJECT = 20, - // Could not assign process to job object. - SBOX_ERROR_SET_THREAD_TOKEN = 21, - // Could not get thread context of new process. - SBOX_ERROR_GET_THREAD_CONTEXT = 22, - // Could not duplicate target info of new process. - SBOX_ERROR_DUPLICATE_TARGET_INFO = 23, - // Could not set low box token. - SBOX_ERROR_SET_LOW_BOX_TOKEN = 24, - // Could not create file mapping for IPC dispatcher. - SBOX_ERROR_CREATE_FILE_MAPPING = 25, - // Could not duplicate shared section into target process for IPC dispatcher. - SBOX_ERROR_DUPLICATE_SHARED_SECTION = 26, - // Could not map view of shared memory in broker. - SBOX_ERROR_MAP_VIEW_OF_SHARED_SECTION = 27, - // Could not apply ASLR mitigations to target process. - SBOX_ERROR_APPLY_ASLR_MITIGATIONS = 28, - // Could not setup one of the required interception services. - SBOX_ERROR_SETUP_BASIC_INTERCEPTIONS = 29, - // Could not setup basic interceptions. - SBOX_ERROR_SETUP_INTERCEPTION_SERVICE = 30, - // Could not initialize interceptions. This usually means 3rd party software - // is stomping on our hooks, or can sometimes mean the syscall format has - // changed. - SBOX_ERROR_INITIALIZE_INTERCEPTIONS = 31, - // Could not setup the imports for ntdll in target process. - SBOX_ERROR_SETUP_NTDLL_IMPORTS = 32, - // Could not setup the handle closer in target process. - SBOX_ERROR_SETUP_HANDLE_CLOSER = 33, - // Cannot get the current Window Station. - SBOX_ERROR_CANNOT_GET_WINSTATION = 34, - // Cannot query the security attributes of the current Window Station. - SBOX_ERROR_CANNOT_QUERY_WINSTATION_SECURITY = 35, - // Cannot get the current Desktop. - SBOX_ERROR_CANNOT_GET_DESKTOP = 36, - // Cannot query the security attributes of the current Desktop. - SBOX_ERROR_CANNOT_QUERY_DESKTOP_SECURITY = 37, - // Cannot setup the interception manager config buffer. - SBOX_ERROR_CANNOT_SETUP_INTERCEPTION_CONFIG_BUFFER = 38, - // Cannot copy data to the child process. - SBOX_ERROR_CANNOT_COPY_DATA_TO_CHILD = 39, - // Cannot setup the interception thunk. - SBOX_ERROR_CANNOT_SETUP_INTERCEPTION_THUNK = 40, - // Cannot resolve the interception thunk. - SBOX_ERROR_CANNOT_RESOLVE_INTERCEPTION_THUNK = 41, - // Cannot write interception thunk to child process. - SBOX_ERROR_CANNOT_WRITE_INTERCEPTION_THUNK = 42, - // Cannot find the base address of the new process. - SBOX_ERROR_CANNOT_FIND_BASE_ADDRESS = 43, - // Placeholder for last item of the enum. - SBOX_ERROR_LAST -}; - -// If the sandbox cannot create a secure environment for the target, the -// target will be forcibly terminated. These are the process exit codes. -enum TerminationCodes { - SBOX_FATAL_INTEGRITY = 7006, // Could not set the integrity level. - SBOX_FATAL_DROPTOKEN = 7007, // Could not lower the token. - SBOX_FATAL_FLUSHANDLES = 7008, // Failed to flush registry handles. - SBOX_FATAL_CACHEDISABLE = 7009, // Failed to forbid HCKU caching. - SBOX_FATAL_CLOSEHANDLES = 7010, // Failed to close pending handles. - SBOX_FATAL_MITIGATION = 7011, // Could not set the mitigation policy. - SBOX_FATAL_MEMORY_EXCEEDED = 7012, // Exceeded the job memory limit. - SBOX_FATAL_WARMUP = 7013, // Failed to warmup. - SBOX_FATAL_LAST -}; - -static_assert(SBOX_FATAL_MEMORY_EXCEEDED == - base::win::kSandboxFatalMemoryExceeded, - "Value for SBOX_FATAL_MEMORY_EXCEEDED must match base."); - -class BrokerServices; -class TargetServices; - -// Contains the pointer to a target or broker service. -struct SandboxInterfaceInfo { - BrokerServices* broker_services; - TargetServices* target_services; -}; - -#if SANDBOX_EXPORTS -#define SANDBOX_INTERCEPT extern "C" __declspec(dllexport) -#else -#define SANDBOX_INTERCEPT extern "C" -#endif - -enum InterceptionType { - INTERCEPTION_INVALID = 0, - INTERCEPTION_SERVICE_CALL, // Trampoline of an NT native call - INTERCEPTION_EAT, - INTERCEPTION_SIDESTEP, // Preamble patch - INTERCEPTION_SMART_SIDESTEP, // Preamble patch but bypass internal calls - INTERCEPTION_UNLOAD_MODULE, // Unload the module (don't patch) - INTERCEPTION_LAST // Placeholder for last item in the enumeration -}; - -} // namespace sandbox - -#endif // SANDBOX_WIN_SRC_SANDBOX_TYPES_H_ diff --git a/sandbox/win/src/security_level.h b/sandbox/win/src/security_level.h deleted file mode 100644 index ecca64d8fc..0000000000 --- a/sandbox/win/src/security_level.h +++ /dev/null @@ -1,232 +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_SRC_SECURITY_LEVEL_H_ -#define SANDBOX_SRC_SECURITY_LEVEL_H_ - -#include <stdint.h> - -namespace sandbox { - -// List of all the integrity levels supported in the sandbox. This is used -// only on Windows Vista. You can't set the integrity level of the process -// in the sandbox to a level higher than yours. -enum IntegrityLevel { - INTEGRITY_LEVEL_SYSTEM, - INTEGRITY_LEVEL_HIGH, - INTEGRITY_LEVEL_MEDIUM, - INTEGRITY_LEVEL_MEDIUM_LOW, - INTEGRITY_LEVEL_LOW, - INTEGRITY_LEVEL_BELOW_LOW, - INTEGRITY_LEVEL_UNTRUSTED, - INTEGRITY_LEVEL_LAST -}; - -// The Token level specifies a set of security profiles designed to -// provide the bulk of the security of sandbox. -// -// TokenLevel |Restricting |Deny Only |Privileges| -// |Sids |Sids | | -// ----------------------------|--------------|----------------|----------| -// USER_LOCKDOWN | Null Sid | All | None | -// ----------------------------|--------------|----------------|----------| -// USER_RESTRICTED | RESTRICTED | All | Traverse | -// ----------------------------|--------------|----------------|----------| -// USER_LIMITED | Users | All except: | Traverse | -// | Everyone | Users | | -// | RESTRICTED | Everyone | | -// | | Interactive | | -// ----------------------------|--------------|----------------|----------| -// USER_INTERACTIVE | Users | All except: | Traverse | -// | Everyone | Users | | -// | RESTRICTED | Everyone | | -// | Owner | Interactive | | -// | | Local | | -// | | Authent-users | | -// | | User | | -// ----------------------------|--------------|----------------|----------| -// USER_NON_ADMIN | None | All except: | Traverse | -// | | Users | | -// | | Everyone | | -// | | Interactive | | -// | | Local | | -// | | Authent-users | | -// | | User | | -// ----------------------------|--------------|----------------|----------| -// USER_RESTRICTED_SAME_ACCESS | All | None | All | -// ----------------------------|--------------|----------------|----------| -// USER_UNPROTECTED | None | None | All | -// ----------------------------|--------------|----------------|----------| -// -// The above restrictions are actually a transformation that is applied to -// the existing broker process token. The resulting token that will be -// applied to the target process depends both on the token level selected -// and on the broker token itself. -// -// The LOCKDOWN and RESTRICTED are designed to allow access to almost -// nothing that has security associated with and they are the recommended -// levels to run sandboxed code specially if there is a chance that the -// broker is process might be started by a user that belongs to the Admins -// or power users groups. -enum TokenLevel { - USER_LOCKDOWN = 0, - USER_RESTRICTED, - USER_LIMITED, - USER_INTERACTIVE, - USER_NON_ADMIN, - USER_RESTRICTED_SAME_ACCESS, - USER_UNPROTECTED, - USER_LAST -}; - -// The Job level specifies a set of decreasing security profiles for the -// Job object that the target process will be placed into. -// This table summarizes the security associated with each level: -// -// JobLevel |General |Quota | -// |restrictions |restrictions | -// -----------------|---------------------------------- |--------------------| -// JOB_NONE | No job is assigned to the | None | -// | sandboxed process. | | -// -----------------|---------------------------------- |--------------------| -// JOB_UNPROTECTED | None | *Kill on Job close.| -// -----------------|---------------------------------- |--------------------| -// JOB_INTERACTIVE | *Forbid system-wide changes using | | -// | SystemParametersInfo(). | *Kill on Job close.| -// | *Forbid the creation/switch of | | -// | Desktops. | | -// | *Forbids calls to ExitWindows(). | | -// -----------------|---------------------------------- |--------------------| -// JOB_LIMITED_USER | Same as INTERACTIVE_USER plus: | *One active process| -// | *Forbid changes to the display | limit. | -// | settings. | *Kill on Job close.| -// -----------------|---------------------------------- |--------------------| -// JOB_RESTRICTED | Same as LIMITED_USER plus: | *One active process| -// | * No read/write to the clipboard. | limit. | -// | * No access to User Handles that | *Kill on Job close.| -// | belong to other processes. | | -// | * Forbid message broadcasts. | | -// | * Forbid setting global hooks. | | -// | * No access to the global atoms | | -// | table. | | -// -----------------|-----------------------------------|--------------------| -// JOB_LOCKDOWN | Same as RESTRICTED | *One active process| -// | | limit. | -// | | *Kill on Job close.| -// | | *Kill on unhandled | -// | | exception. | -// | | | -// In the context of the above table, 'user handles' refers to the handles of -// windows, bitmaps, menus, etc. Files, treads and registry handles are kernel -// handles and are not affected by the job level settings. -enum JobLevel { - JOB_LOCKDOWN = 0, - JOB_RESTRICTED, - JOB_LIMITED_USER, - JOB_INTERACTIVE, - JOB_UNPROTECTED, - JOB_NONE -}; - -// These flags correspond to various process-level mitigations (eg. ASLR and -// DEP). Most are implemented via UpdateProcThreadAttribute() plus flags for -// the PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY attribute argument; documented -// here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686880 -// Some mitigations are implemented directly by the sandbox or emulated to -// the greatest extent possible when not directly supported by the OS. -// Flags that are unsupported for the target OS will be silently ignored. -// Flags that are invalid for their application (pre or post startup) will -// return SBOX_ERROR_BAD_PARAMS. -typedef uint64_t MitigationFlags; - -// Permanently enables DEP for the target process. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE. -const MitigationFlags MITIGATION_DEP = 0x00000001; - -// Permanently Disables ATL thunk emulation when DEP is enabled. Valid -// only when MITIGATION_DEP is passed. Corresponds to not passing -// PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE. -const MitigationFlags MITIGATION_DEP_NO_ATL_THUNK = 0x00000002; - -// Enables Structured exception handling override prevention. Must be -// enabled prior to process start. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE. -const MitigationFlags MITIGATION_SEHOP = 0x00000004; - -// Forces ASLR on all images in the child process. In debug builds, must be -// enabled after startup. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON . -const MitigationFlags MITIGATION_RELOCATE_IMAGE = 0x00000008; - -// Refuses to load DLLs that cannot support ASLR. In debug builds, must be -// enabled after startup. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS. -const MitigationFlags MITIGATION_RELOCATE_IMAGE_REQUIRED = 0x00000010; - -// Terminates the process on Windows heap corruption. Coresponds to -// PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON. -const MitigationFlags MITIGATION_HEAP_TERMINATE = 0x00000020; - -// Sets a random lower bound as the minimum user address. Must be -// enabled prior to process start. On 32-bit processes this is -// emulated to a much smaller degree. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON. -const MitigationFlags MITIGATION_BOTTOM_UP_ASLR = 0x00000040; - -// Increases the randomness range of bottom-up ASLR to up to 1TB. Must be -// enabled prior to process start and with MITIGATION_BOTTOM_UP_ASLR. -// Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON -const MitigationFlags MITIGATION_HIGH_ENTROPY_ASLR = 0x00000080; - -// Immediately raises an exception on a bad handle reference. Must be -// enabled after startup. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON. -const MitigationFlags MITIGATION_STRICT_HANDLE_CHECKS = 0x00000100; - -// Prevents the process from making Win32k calls. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON. -// -// Applications linked to user32.dll or gdi32.dll make Win32k calls during -// setup, even if Win32k is not otherwise used. So they also need to add a rule -// with SUBSYS_WIN32K_LOCKDOWN and semantics FAKE_USER_GDI_INIT to allow the -// initialization to succeed. -const MitigationFlags MITIGATION_WIN32K_DISABLE = 0x00000200; - -// Prevents certain built-in third party extension points from being used. -// - App_Init DLLs -// - Winsock Layered Service Providers (LSPs) -// - Global Windows Hooks (NOT thread-targeted hooks) -// - Legacy Input Method Editors (IMEs). -// I.e.: Disable legacy hooking mechanisms. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON. -const MitigationFlags MITIGATION_EXTENSION_POINT_DISABLE = 0x00000400; - -// Prevents the process from loading non-system fonts into GDI. -// Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_FONT_DISABLE_ALWAYS_ON -const MitigationFlags MITIGATION_NONSYSTEM_FONT_DISABLE = 0x00000800; - -// Sets the DLL search order to LOAD_LIBRARY_SEARCH_DEFAULT_DIRS. Additional -// directories can be added via the Windows AddDllDirectory() function. -// http://msdn.microsoft.com/en-us/library/windows/desktop/hh310515 -// Must be enabled after startup. -const MitigationFlags MITIGATION_DLL_SEARCH_ORDER = 0x00000001ULL << 32; - -// Changes the mandatory integrity level policy on the current process' token -// to enable no-read and no-execute up. This prevents a lower IL process from -// opening the process token for impersonate/duplicate/assignment. -const MitigationFlags MITIGATION_HARDEN_TOKEN_IL_POLICY = 0x00000001ULL << 33; - -// Blocks mapping of images from remote devices. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_REMOTE_ALWAYS_ON. -const MitigationFlags MITIGATION_IMAGE_LOAD_NO_REMOTE = 0x00000001ULL << 52; - -// Blocks mapping of images that have the low manditory label. Corresponds to -// PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_ON. -const MitigationFlags MITIGATION_IMAGE_LOAD_NO_LOW_LABEL = 0x00000001ULL << 56; - -} // namespace sandbox - -#endif // SANDBOX_SRC_SECURITY_LEVEL_H_ diff --git a/sandbox/win/src/sidestep/ia32_modrm_map.cpp b/sandbox/win/src/sidestep/ia32_modrm_map.cpp deleted file mode 100644 index 89bc1895eb..0000000000 --- a/sandbox/win/src/sidestep/ia32_modrm_map.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2012 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. - -// Table of relevant information about how to decode the ModR/M byte. -// Based on information in the IA-32 Intel Architecture -// Software Developer's Manual Volume 2: Instruction Set Reference. - -#include "sandbox/win/src/sidestep/mini_disassembler.h" -#include "sandbox/win/src/sidestep/mini_disassembler_types.h" - -namespace sidestep { - -const ModrmEntry MiniDisassembler::s_ia16_modrm_map_[] = { -// mod == 00 - /* r/m == 000 */ { false, false, OS_ZERO }, - /* r/m == 001 */ { false, false, OS_ZERO }, - /* r/m == 010 */ { false, false, OS_ZERO }, - /* r/m == 011 */ { false, false, OS_ZERO }, - /* r/m == 100 */ { false, false, OS_ZERO }, - /* r/m == 101 */ { false, false, OS_ZERO }, - /* r/m == 110 */ { true, false, OS_WORD }, - /* r/m == 111 */ { false, false, OS_ZERO }, -// mod == 01 - /* r/m == 000 */ { true, false, OS_BYTE }, - /* r/m == 001 */ { true, false, OS_BYTE }, - /* r/m == 010 */ { true, false, OS_BYTE }, - /* r/m == 011 */ { true, false, OS_BYTE }, - /* r/m == 100 */ { true, false, OS_BYTE }, - /* r/m == 101 */ { true, false, OS_BYTE }, - /* r/m == 110 */ { true, false, OS_BYTE }, - /* r/m == 111 */ { true, false, OS_BYTE }, -// mod == 10 - /* r/m == 000 */ { true, false, OS_WORD }, - /* r/m == 001 */ { true, false, OS_WORD }, - /* r/m == 010 */ { true, false, OS_WORD }, - /* r/m == 011 */ { true, false, OS_WORD }, - /* r/m == 100 */ { true, false, OS_WORD }, - /* r/m == 101 */ { true, false, OS_WORD }, - /* r/m == 110 */ { true, false, OS_WORD }, - /* r/m == 111 */ { true, false, OS_WORD }, -// mod == 11 - /* r/m == 000 */ { false, false, OS_ZERO }, - /* r/m == 001 */ { false, false, OS_ZERO }, - /* r/m == 010 */ { false, false, OS_ZERO }, - /* r/m == 011 */ { false, false, OS_ZERO }, - /* r/m == 100 */ { false, false, OS_ZERO }, - /* r/m == 101 */ { false, false, OS_ZERO }, - /* r/m == 110 */ { false, false, OS_ZERO }, - /* r/m == 111 */ { false, false, OS_ZERO } -}; - -const ModrmEntry MiniDisassembler::s_ia32_modrm_map_[] = { -// mod == 00 - /* r/m == 000 */ { false, false, OS_ZERO }, - /* r/m == 001 */ { false, false, OS_ZERO }, - /* r/m == 010 */ { false, false, OS_ZERO }, - /* r/m == 011 */ { false, false, OS_ZERO }, - /* r/m == 100 */ { false, true, OS_ZERO }, - /* r/m == 101 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 110 */ { false, false, OS_ZERO }, - /* r/m == 111 */ { false, false, OS_ZERO }, -// mod == 01 - /* r/m == 000 */ { true, false, OS_BYTE }, - /* r/m == 001 */ { true, false, OS_BYTE }, - /* r/m == 010 */ { true, false, OS_BYTE }, - /* r/m == 011 */ { true, false, OS_BYTE }, - /* r/m == 100 */ { true, true, OS_BYTE }, - /* r/m == 101 */ { true, false, OS_BYTE }, - /* r/m == 110 */ { true, false, OS_BYTE }, - /* r/m == 111 */ { true, false, OS_BYTE }, -// mod == 10 - /* r/m == 000 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 001 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 010 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 011 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 100 */ { true, true, OS_DOUBLE_WORD }, - /* r/m == 101 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 110 */ { true, false, OS_DOUBLE_WORD }, - /* r/m == 111 */ { true, false, OS_DOUBLE_WORD }, -// mod == 11 - /* r/m == 000 */ { false, false, OS_ZERO }, - /* r/m == 001 */ { false, false, OS_ZERO }, - /* r/m == 010 */ { false, false, OS_ZERO }, - /* r/m == 011 */ { false, false, OS_ZERO }, - /* r/m == 100 */ { false, false, OS_ZERO }, - /* r/m == 101 */ { false, false, OS_ZERO }, - /* r/m == 110 */ { false, false, OS_ZERO }, - /* r/m == 111 */ { false, false, OS_ZERO }, -}; - -}; // namespace sidestep diff --git a/sandbox/win/src/sidestep/ia32_opcode_map.cpp b/sandbox/win/src/sidestep/ia32_opcode_map.cpp deleted file mode 100644 index b7d8a60bc1..0000000000 --- a/sandbox/win/src/sidestep/ia32_opcode_map.cpp +++ /dev/null @@ -1,1159 +0,0 @@ -// Copyright (c) 2012 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. - -// Opcode decoding maps. Based on the IA-32 Intel Architecture -// Software Developer's Manual Volume 2: Instruction Set Reference. Idea -// for how to lay out the tables in memory taken from the implementation -// in the Bastard disassembly environment. - -#include "sandbox/win/src/sidestep/mini_disassembler.h" - -namespace sidestep { - -/* -* This is the first table to be searched; the first field of each -* Opcode in the table is either 0 to indicate you're in the -* right table, or an index to the correct table, in the global -* map g_pentiumOpcodeMap -*/ -const Opcode s_first_opcode_byte[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF */ { 1, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x10 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x11 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x12 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x13 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x14 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x15 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x16 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x17 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x18 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x19 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1E */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1F */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x20 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x21 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x22 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x23 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x24 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x25 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x26 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x27 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "daa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x28 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x29 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "das", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x30 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x31 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x32 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x33 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x34 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x35 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x36 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x37 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aaa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x38 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x39 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aas", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x40 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x41 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x42 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x43 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x44 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x45 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x46 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x47 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x48 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x49 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x50 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x51 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x52 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x53 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x54 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x55 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x56 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x57 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x58 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x59 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x60 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x61 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x62 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_A, AM_NOT_USED, "bound", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x63 */ { 0, IT_GENERIC, AM_E | OT_W, AM_G | OT_W, AM_NOT_USED, "arpl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x64 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x65 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x66 */ { 0, IT_PREFIX_OPERAND, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x67 */ { 0, IT_PREFIX_ADDRESS, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x68 */ { 0, IT_GENERIC, AM_I | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x69 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_V, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6A */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_B, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6C */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "insb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6D */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "insd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6E */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X | OT_B, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X | OT_V, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x70 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x71 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x72 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x73 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x74 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x75 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x76 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x77 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x78 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x79 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7A */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7B */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7C */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7D */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7E */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7F */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x80 */ { 2, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x81 */ { 3, IT_REFERENCE, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x82 */ { 4, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x83 */ { 5, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x84 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x85 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x86 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x87 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x88 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x89 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8C */ { 0, IT_GENERIC, AM_E | OT_W, AM_S | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8D */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, "lea", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8E */ { 0, IT_GENERIC, AM_S | OT_W, AM_E | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8F */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x90 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "nop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x91 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x92 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x93 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x94 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x95 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x96 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x97 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x98 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cwde", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x99 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cdq", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9A */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "callf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9B */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wait", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9E */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_O | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_O | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA2 */ { 0, IT_GENERIC, AM_O | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA3 */ { 0, IT_GENERIC, AM_O | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA4 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "movsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA5 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "movsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA6 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "cmpsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA7 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "cmpsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAA */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "stosb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAB */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "stosd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X| OT_B, AM_NOT_USED, "lodsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X| OT_V, AM_NOT_USED, "lodsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAE */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_Y | OT_B, AM_NOT_USED, "scasb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_Y | OT_V, AM_NOT_USED, "scasd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB1 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB2 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB3 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC0 */ { 6, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC1 */ { 7, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC2 */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC3 */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC4 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "les", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "lds", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC8 */ { 0, IT_GENERIC, AM_I | OT_W, AM_I | OT_B, AM_NOT_USED, "enter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "leave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCA */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCB */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "int3", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCD */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "int", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCE */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "into", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCF */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "iret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD0 */ { 8, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD1 */ { 9, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD2 */ { 10, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD3 */ { 11, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD4 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aam", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD5 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "xlat", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - - // The following 8 lines would be references to the FPU tables, but we currently - // do not support the FPU instructions in this disassembler. - - /* 0xD8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xDA */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xDB */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xDC */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xDD */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xDE */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xDF */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - - - /* 0xE0 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE1 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE2 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE3 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jcxz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE6 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE7 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE8 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE9 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xEA */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xEB */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xEC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xED */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xEE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xEF */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_V, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF0 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lock:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF2 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "repne:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF3 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rep:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF4 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "hlt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF6 */ { 12, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF7 */ { 13, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xFA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cli", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xFB */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xFC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xFD */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "std", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xFE */ { 14, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xFF */ { 15, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f[] = { - /* 0x0 */ { 16, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 17, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lsl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "invd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wbinvd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud2", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xE */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x10 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movups", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "movsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "movss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movupd" } }, - /* 0x11 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movups", true, - /* F2h */ { 0, IT_GENERIC, AM_W | OT_SD, AM_V | OT_SD, AM_NOT_USED, "movsd" }, - /* F3h */ { 0, IT_GENERIC, AM_W | OT_SS, AM_V | OT_SS, AM_NOT_USED, "movss" }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movupd" } }, - /* 0x12 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" }, // only one of ... - /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" }, // ...these two is correct, Intel doesn't specify which - /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_S, AM_NOT_USED, "movlpd" } }, - /* 0x13 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlpd" } }, - /* 0x14 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpcklps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpcklpd" } }, - /* 0x15 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpckhps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpckhpd" } }, - /* 0x16 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" }, // only one of... - /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" }, // ...these two is correct, Intel doesn't specify which - /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhpd" } }, - /* 0x17 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhpd" } }, - /* 0x18 */ { 18, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x19 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1C */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x20 */ { 0, IT_GENERIC, AM_R | OT_D, AM_C | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x21 */ { 0, IT_GENERIC, AM_R | OT_D, AM_D | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x22 */ { 0, IT_GENERIC, AM_C | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x23 */ { 0, IT_GENERIC, AM_D | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x24 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x25 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x26 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x27 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x28 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movaps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movapd" } }, - /* 0x29 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movaps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movapd" } }, - /* 0x2A */ { 0, IT_GENERIC, AM_V | OT_PS, AM_Q | OT_Q, AM_NOT_USED, "cvtpi2ps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_E | OT_D, AM_NOT_USED, "cvtsi2sd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_E | OT_D, AM_NOT_USED, "cvtsi2ss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_Q | OT_DQ, AM_NOT_USED, "cvtpi2pd" } }, - /* 0x2B */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movntps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movntpd" } }, - /* 0x2C */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvttps2pi", true, - /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvttsd2si" }, - /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvttss2si" }, - /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2pi" } }, - /* 0x2D */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvtps2pi", true, - /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvtsd2si" }, - /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvtss2si" }, - /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2pi" } }, - /* 0x2E */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "ucomiss", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "ucomisd" } }, - /* 0x2F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_SS, AM_NOT_USED, "comiss", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "comisd" } }, - /* 0x30 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wrmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x31 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdtsc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x32 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x33 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdpmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x34 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysenter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x35 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysexit", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x36 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x37 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x38 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x39 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x40 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x41 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x42 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x43 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x44 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x45 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x46 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x47 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmova", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x48 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x49 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4A */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4D */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4E */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4F */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x50 */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PS, AM_NOT_USED, "movmskps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PD, AM_NOT_USED, "movmskpd" } }, - /* 0x51 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "sqrtps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "sqrtsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "sqrtss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "sqrtpd" } }, - /* 0x52 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rsqrtps", true, - /* F2h */ { 0 }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rsqrtss" }, - /* 66h */ { 0 } }, - /* 0x53 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rcpps", true, - /* F2h */ { 0 }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rcpss" }, - /* 66h */ { 0 } }, - /* 0x54 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andpd" } }, - /* 0x55 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andnps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andnpd" } }, - /* 0x56 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "orps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "orpd" } }, - /* 0x57 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "xorps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "xorpd" } }, - /* 0x58 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "addps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "addsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "addss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "addpd" } }, - /* 0x59 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "mulps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "mulsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "mulss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "mulpd" } }, - /* 0x5A */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PS, AM_NOT_USED, "cvtps2pd", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "cvtsd2ss" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "cvtss2sd" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PD, AM_NOT_USED, "cvtpd2ps" } }, - /* 0x5B */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2ps", true, - /* F2h */ { 0 }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvttps2dq" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvtps2dq" } }, - /* 0x5C */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "subps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "subsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "subss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "subpd" } }, - /* 0x5D */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "minps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "minsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "minss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "minpd" } }, - /* 0x5E */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "divps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "divsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "divss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "divpd" } }, - /* 0x5F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "maxps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "maxsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "maxss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "maxpd" } }, - /* 0x60 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklbw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklbw" } }, - /* 0x61 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklwd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklwd" } }, - /* 0x62 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckldq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpckldq" } }, - /* 0x63 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packsswb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packsswb" } }, - /* 0x64 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtb" } }, - /* 0x65 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtw" } }, - /* 0x66 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtd" } }, - /* 0x67 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packuswb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packuswb" } }, - /* 0x68 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhbw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhbw" } }, - /* 0x69 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhwd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhwd" } }, - /* 0x6A */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhdq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhdq" } }, - /* 0x6B */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packssdw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "packssdw" } }, - /* 0x6C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } }, - /* 0x6D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } }, - /* 0x6E */ { 0, IT_GENERIC, AM_P | OT_D, AM_E | OT_D, AM_NOT_USED, "movd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_NOT_USED, "movd" } }, - /* 0x6F */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "movq", true, - /* F2h */ { 0 }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqu" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqa" } }, - /* 0x70 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_I | OT_B, "pshuf", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshuflw" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufhw" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufd" } }, - /* 0x71 */ { 19, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x72 */ { 20, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x73 */ { 21, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x74 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqb" } }, - /* 0x75 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqw" } }, - /* 0x76 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqd" } }, - /* 0x77 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "emms", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - - // The following six opcodes are escapes into the MMX stuff, which this disassembler does not support. - /* 0x78 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x79 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7A */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7B */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7C */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7D */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - - /* 0x7E */ { 0, IT_GENERIC, AM_E | OT_D, AM_P | OT_D, AM_NOT_USED, "movd", true, - /* F2h */ { 0 }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movq" }, - /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_DQ, AM_NOT_USED, "movd" } }, - /* 0x7F */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_P | OT_Q, AM_NOT_USED, "movq", true, - /* F2h */ { 0 }, - /* F3h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqu" }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqa" } }, - /* 0x80 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x81 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x82 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x83 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x84 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x85 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x86 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x87 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x88 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x89 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8A */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8B */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8C */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8D */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8E */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x8F */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x90 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seto", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x91 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x92 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x93 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x94 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x95 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x96 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x97 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seta", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x98 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "sets", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x99 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9A */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9B */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9C */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9D */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9E */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x9F */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cpuid", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA6 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA7 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rsm", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAC */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAD */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAE */ { 22, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xAF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB2 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lss", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB4 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lfs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB5 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lgs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB6 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB7 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xB9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud1", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBA */ { 23, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBC */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBD */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBE */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xBF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC2 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "cmpps", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_I | OT_B, "cmpsd" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_I | OT_B, "cmpss" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "cmppd" } }, - /* 0xC3 */ { 0, IT_GENERIC, AM_E | OT_D, AM_G | OT_D, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_E | OT_D, AM_I | OT_B, "pinsrw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_I | OT_B, "pinsrw" } }, - /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_I | OT_B, "pextrw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_I | OT_B, "pextrw" } }, - /* 0xC6 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "shufps", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "shufpd" } }, - /* 0xC7 */ { 24, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC8 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xC9 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCA */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCB */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCC */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCD */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCE */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xCF */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xD1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlw" } }, - /* 0xD2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrld", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrld" } }, - /* 0xD3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlq" } }, - /* 0xD4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddq" } }, - /* 0xD5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmullw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmullw" } }, - /* 0xD6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "unused without prefix", true, - /* F2h */ { 0, IT_GENERIC, AM_P | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movdq2q" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_Q | OT_Q, AM_NOT_USED, "movq2dq" }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movq" } }, - /* 0xD7 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_NOT_USED, "pmovmskb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_NOT_USED, "pmovmskb" } }, - /* 0xD8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusb" } }, - /* 0xD9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusw" } }, - /* 0xDA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminub", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminub" } }, - /* 0xDB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pand", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pand" } }, - /* 0xDC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusb" } }, - /* 0xDD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusw" } }, - /* 0xDE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxub", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxub" } }, - /* 0xDF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pandn", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pandn" } }, - /* 0xE0 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgb" } }, - /* 0xE1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psraw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrqw" } }, - /* 0xE2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrad", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrad" } }, - /* 0xE3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgw" } }, - /* 0xE4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhuw" } }, - /* 0xE5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhw" } }, - /* 0xE6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true, - /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2dq" }, - /* F3h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2pd" }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2dq" } }, - /* 0xE7 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movntq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movntdq" } }, - /* 0xE8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsb" } }, - /* 0xE9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsw" } }, - /* 0xEA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminsw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminsw" } }, - /* 0xEB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "por", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "por" } }, - /* 0xEC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsb" } }, - /* 0xED */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsw" } }, - /* 0xEE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxsw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxsw" } }, - /* 0xEF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pxor", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pxor" } }, - /* 0xF0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0xF1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllw" } }, - /* 0xF2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pslld", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pslld" } }, - /* 0xF3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllq" } }, - /* 0xF4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmuludq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmuludq" } }, - /* 0xF5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaddwd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaddwd" } }, - /* 0xF6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psadbw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psadbw" } }, - /* 0xF7 */ { 0, IT_GENERIC, AM_P | OT_PI, AM_Q | OT_PI, AM_NOT_USED, "maskmovq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "maskmovdqu" } }, - /* 0xF8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubb" } }, - /* 0xF9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubw" } }, - /* 0xFA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubd" } }, - /* 0xFB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubq" } }, - /* 0xFC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddb", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddb" } }, - /* 0xFD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddw" } }, - /* 0xFE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddd", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddd" } }, - /* 0xFF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f00[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "sldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "str", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "ltr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f01[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "smsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lmsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_M | OT_B, AM_NOT_USED, AM_NOT_USED, "invlpg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f18[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f71[] = { - /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlw" } }, - /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psraw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psraw" } }, - /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllw", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllw" } }, - /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f72[] = { - /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrld", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrld" } }, - /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrad", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrad" } }, - /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "pslld", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslld" } }, - /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0f73[] = { - /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlq" } }, - /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllq" } }, - /* 0x7 */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq", true, - /* F2h */ { 0 }, - /* F3h */ { 0 }, - /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq" } }, -}; - -const Opcode s_opcode_byte_after_0fae[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxsave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxrstor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ldmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "mfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clflush/sfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, -}; - -const Opcode s_opcode_byte_after_0fba[] = { - /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_0fc7[] = { - /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_Q, AM_NOT_USED, AM_NOT_USED, "cmpxch8b", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_80[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_81[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_82[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_83[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_c0[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_c1[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_d0[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_d1[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_d2[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_d3[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_f6[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_f7[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_fe[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -const Opcode s_opcode_byte_after_ff[] = { - /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x2 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x3 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x4 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x5 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }, - /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } } -}; - -/* -* A table of all the other tables, containing some extra information, e.g. -* how to mask out the byte we're looking at. -*/ -const OpcodeTable MiniDisassembler::s_ia32_opcode_map_[]={ - // One-byte opcodes and jumps to larger - /* 0 */ {s_first_opcode_byte, 0, 0xff, 0, 0xff}, - // Two-byte opcodes (second byte) - /* 1 */ {s_opcode_byte_after_0f, 0, 0xff, 0, 0xff}, - // Start of tables for opcodes using ModR/M bits as extension - /* 2 */ {s_opcode_byte_after_80, 3, 0x07, 0, 0x07}, - /* 3 */ {s_opcode_byte_after_81, 3, 0x07, 0, 0x07}, - /* 4 */ {s_opcode_byte_after_82, 3, 0x07, 0, 0x07}, - /* 5 */ {s_opcode_byte_after_83, 3, 0x07, 0, 0x07}, - /* 6 */ {s_opcode_byte_after_c0, 3, 0x07, 0, 0x07}, - /* 7 */ {s_opcode_byte_after_c1, 3, 0x07, 0, 0x07}, - /* 8 */ {s_opcode_byte_after_d0, 3, 0x07, 0, 0x07}, - /* 9 */ {s_opcode_byte_after_d1, 3, 0x07, 0, 0x07}, - /* 10 */ {s_opcode_byte_after_d2, 3, 0x07, 0, 0x07}, - /* 11 */ {s_opcode_byte_after_d3, 3, 0x07, 0, 0x07}, - /* 12 */ {s_opcode_byte_after_f6, 3, 0x07, 0, 0x07}, - /* 13 */ {s_opcode_byte_after_f7, 3, 0x07, 0, 0x07}, - /* 14 */ {s_opcode_byte_after_fe, 3, 0x07, 0, 0x01}, - /* 15 */ {s_opcode_byte_after_ff, 3, 0x07, 0, 0x07}, - /* 16 */ {s_opcode_byte_after_0f00, 3, 0x07, 0, 0x07}, - /* 17 */ {s_opcode_byte_after_0f01, 3, 0x07, 0, 0x07}, - /* 18 */ {s_opcode_byte_after_0f18, 3, 0x07, 0, 0x07}, - /* 19 */ {s_opcode_byte_after_0f71, 3, 0x07, 0, 0x07}, - /* 20 */ {s_opcode_byte_after_0f72, 3, 0x07, 0, 0x07}, - /* 21 */ {s_opcode_byte_after_0f73, 3, 0x07, 0, 0x07}, - /* 22 */ {s_opcode_byte_after_0fae, 3, 0x07, 0, 0x07}, - /* 23 */ {s_opcode_byte_after_0fba, 3, 0x07, 0, 0x07}, - /* 24 */ {s_opcode_byte_after_0fc7, 3, 0x07, 0, 0x01} -}; - -}; // namespace sidestep diff --git a/sandbox/win/src/sidestep/mini_disassembler.cpp b/sandbox/win/src/sidestep/mini_disassembler.cpp deleted file mode 100644 index 1e8e0bd972..0000000000 --- a/sandbox/win/src/sidestep/mini_disassembler.cpp +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright (c) 2012 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. - -// Implementation of MiniDisassembler. - -#ifdef _WIN64 -#error The code in this file should not be used on 64-bit Windows. -#endif - -#include "sandbox/win/src/sidestep/mini_disassembler.h" - -namespace sidestep { - -MiniDisassembler::MiniDisassembler(bool operand_default_is_32_bits, - bool address_default_is_32_bits) - : operand_default_is_32_bits_(operand_default_is_32_bits), - address_default_is_32_bits_(address_default_is_32_bits) { - Initialize(); -} - -MiniDisassembler::MiniDisassembler() - : operand_default_is_32_bits_(true), - address_default_is_32_bits_(true) { - Initialize(); -} - -InstructionType MiniDisassembler::Disassemble( - unsigned char* start_byte, - unsigned int* instruction_bytes) { - // Clean up any state from previous invocations. - Initialize(); - - // Start by processing any prefixes. - unsigned char* current_byte = start_byte; - unsigned int size = 0; - InstructionType instruction_type = ProcessPrefixes(current_byte, &size); - - if (IT_UNKNOWN == instruction_type) - return instruction_type; - - current_byte += size; - size = 0; - - // Invariant: We have stripped all prefixes, and the operand_is_32_bits_ - // and address_is_32_bits_ flags are correctly set. - - instruction_type = ProcessOpcode(current_byte, 0, &size); - - // Check for error processing instruction - if ((IT_UNKNOWN == instruction_type_) || (IT_UNUSED == instruction_type_)) { - return IT_UNKNOWN; - } - - current_byte += size; - - // Invariant: operand_bytes_ indicates the total size of operands - // specified by the opcode and/or ModR/M byte and/or SIB byte. - // pCurrentByte points to the first byte after the ModR/M byte, or after - // the SIB byte if it is present (i.e. the first byte of any operands - // encoded in the instruction). - - // We get the total length of any prefixes, the opcode, and the ModR/M and - // SIB bytes if present, by taking the difference of the original starting - // address and the current byte (which points to the first byte of the - // operands if present, or to the first byte of the next instruction if - // they are not). Adding the count of bytes in the operands encoded in - // the instruction gives us the full length of the instruction in bytes. - *instruction_bytes += operand_bytes_ + (current_byte - start_byte); - - // Return the instruction type, which was set by ProcessOpcode(). - return instruction_type_; -} - -void MiniDisassembler::Initialize() { - operand_is_32_bits_ = operand_default_is_32_bits_; - address_is_32_bits_ = address_default_is_32_bits_; - operand_bytes_ = 0; - have_modrm_ = false; - should_decode_modrm_ = false; - instruction_type_ = IT_UNKNOWN; - got_f2_prefix_ = false; - got_f3_prefix_ = false; - got_66_prefix_ = false; -} - -InstructionType MiniDisassembler::ProcessPrefixes(unsigned char* start_byte, - unsigned int* size) { - InstructionType instruction_type = IT_GENERIC; - const Opcode& opcode = s_ia32_opcode_map_[0].table_[*start_byte]; - - switch (opcode.type_) { - case IT_PREFIX_ADDRESS: - address_is_32_bits_ = !address_default_is_32_bits_; - goto nochangeoperand; - case IT_PREFIX_OPERAND: - operand_is_32_bits_ = !operand_default_is_32_bits_; - nochangeoperand: - case IT_PREFIX: - - if (0xF2 == (*start_byte)) - got_f2_prefix_ = true; - else if (0xF3 == (*start_byte)) - got_f3_prefix_ = true; - else if (0x66 == (*start_byte)) - got_66_prefix_ = true; - - instruction_type = opcode.type_; - (*size)++; - // we got a prefix, so add one and check next byte - ProcessPrefixes(start_byte + 1, size); - default: - break; // not a prefix byte - } - - return instruction_type; -} - -InstructionType MiniDisassembler::ProcessOpcode(unsigned char* start_byte, - unsigned int table_index, - unsigned int* size) { - const OpcodeTable& table = s_ia32_opcode_map_[table_index]; // Get our table - unsigned char current_byte = (*start_byte) >> table.shift_; - current_byte = current_byte & table.mask_; // Mask out the bits we will use - - // Check whether the byte we have is inside the table we have. - if (current_byte < table.min_lim_ || current_byte > table.max_lim_) { - instruction_type_ = IT_UNKNOWN; - return instruction_type_; - } - - const Opcode& opcode = table.table_[current_byte]; - if (IT_UNUSED == opcode.type_) { - // This instruction is not used by the IA-32 ISA, so we indicate - // this to the user. Probably means that we were pointed to - // a byte in memory that was not the start of an instruction. - instruction_type_ = IT_UNUSED; - return instruction_type_; - } else if (IT_REFERENCE == opcode.type_) { - // We are looking at an opcode that has more bytes (or is continued - // in the ModR/M byte). Recursively find the opcode definition in - // the table for the opcode's next byte. - (*size)++; - ProcessOpcode(start_byte + 1, opcode.table_index_, size); - return instruction_type_; - } - - const SpecificOpcode* specific_opcode = reinterpret_cast< - const SpecificOpcode*>(&opcode); - if (opcode.is_prefix_dependent_) { - if (got_f2_prefix_ && opcode.opcode_if_f2_prefix_.mnemonic_ != 0) { - specific_opcode = &opcode.opcode_if_f2_prefix_; - } else if (got_f3_prefix_ && opcode.opcode_if_f3_prefix_.mnemonic_ != 0) { - specific_opcode = &opcode.opcode_if_f3_prefix_; - } else if (got_66_prefix_ && opcode.opcode_if_66_prefix_.mnemonic_ != 0) { - specific_opcode = &opcode.opcode_if_66_prefix_; - } - } - - // Inv: The opcode type is known. - instruction_type_ = specific_opcode->type_; - - // Let's process the operand types to see if we have any immediate - // operands, and/or a ModR/M byte. - - ProcessOperand(specific_opcode->flag_dest_); - ProcessOperand(specific_opcode->flag_source_); - ProcessOperand(specific_opcode->flag_aux_); - - // Inv: We have processed the opcode and incremented operand_bytes_ - // by the number of bytes of any operands specified by the opcode - // that are stored in the instruction (not registers etc.). Now - // we need to return the total number of bytes for the opcode and - // for the ModR/M or SIB bytes if they are present. - - if (table.mask_ != 0xff) { - if (have_modrm_) { - // we're looking at a ModR/M byte so we're not going to - // count that into the opcode size - ProcessModrm(start_byte, size); - return IT_GENERIC; - } else { - // need to count the ModR/M byte even if it's just being - // used for opcode extension - (*size)++; - return IT_GENERIC; - } - } else { - if (have_modrm_) { - // The ModR/M byte is the next byte. - (*size)++; - ProcessModrm(start_byte + 1, size); - return IT_GENERIC; - } else { - (*size)++; - return IT_GENERIC; - } - } -} - -bool MiniDisassembler::ProcessOperand(int flag_operand) { - bool succeeded = true; - if (AM_NOT_USED == flag_operand) - return succeeded; - - // Decide what to do based on the addressing mode. - switch (flag_operand & AM_MASK) { - // No ModR/M byte indicated by these addressing modes, and no - // additional (e.g. immediate) parameters. - case AM_A: // Direct address - case AM_F: // EFLAGS register - case AM_X: // Memory addressed by the DS:SI register pair - case AM_Y: // Memory addressed by the ES:DI register pair - case AM_IMPLICIT: // Parameter is implicit, occupies no space in - // instruction - break; - - // There is a ModR/M byte but it does not necessarily need - // to be decoded. - case AM_C: // reg field of ModR/M selects a control register - case AM_D: // reg field of ModR/M selects a debug register - case AM_G: // reg field of ModR/M selects a general register - case AM_P: // reg field of ModR/M selects an MMX register - case AM_R: // mod field of ModR/M may refer only to a general register - case AM_S: // reg field of ModR/M selects a segment register - case AM_T: // reg field of ModR/M selects a test register - case AM_V: // reg field of ModR/M selects a 128-bit XMM register - have_modrm_ = true; - break; - - // In these addressing modes, there is a ModR/M byte and it needs to be - // decoded. No other (e.g. immediate) params than indicated in ModR/M. - case AM_E: // Operand is either a general-purpose register or memory, - // specified by ModR/M byte - case AM_M: // ModR/M byte will refer only to memory - case AM_Q: // Operand is either an MMX register or memory (complex - // evaluation), specified by ModR/M byte - case AM_W: // Operand is either a 128-bit XMM register or memory (complex - // eval), specified by ModR/M byte - have_modrm_ = true; - should_decode_modrm_ = true; - break; - - // These addressing modes specify an immediate or an offset value - // directly, so we need to look at the operand type to see how many - // bytes. - case AM_I: // Immediate data. - case AM_J: // Jump to offset. - case AM_O: // Operand is at offset. - switch (flag_operand & OT_MASK) { - case OT_B: // Byte regardless of operand-size attribute. - operand_bytes_ += OS_BYTE; - break; - case OT_C: // Byte or word, depending on operand-size attribute. - if (operand_is_32_bits_) - operand_bytes_ += OS_WORD; - else - operand_bytes_ += OS_BYTE; - break; - case OT_D: // Doubleword, regardless of operand-size attribute. - operand_bytes_ += OS_DOUBLE_WORD; - break; - case OT_DQ: // Double-quadword, regardless of operand-size attribute. - operand_bytes_ += OS_DOUBLE_QUAD_WORD; - break; - case OT_P: // 32-bit or 48-bit pointer, depending on operand-size - // attribute. - if (operand_is_32_bits_) - operand_bytes_ += OS_48_BIT_POINTER; - else - operand_bytes_ += OS_32_BIT_POINTER; - break; - case OT_PS: // 128-bit packed single-precision floating-point data. - operand_bytes_ += OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING; - break; - case OT_Q: // Quadword, regardless of operand-size attribute. - operand_bytes_ += OS_QUAD_WORD; - break; - case OT_S: // 6-byte pseudo-descriptor. - operand_bytes_ += OS_PSEUDO_DESCRIPTOR; - break; - case OT_SD: // Scalar Double-Precision Floating-Point Value - case OT_PD: // Unaligned packed double-precision floating point value - operand_bytes_ += OS_DOUBLE_PRECISION_FLOATING; - break; - case OT_SS: - // Scalar element of a 128-bit packed single-precision - // floating data. - // We simply return enItUnknown since we don't have to support - // floating point - succeeded = false; - break; - case OT_V: // Word or doubleword, depending on operand-size attribute. - if (operand_is_32_bits_) - operand_bytes_ += OS_DOUBLE_WORD; - else - operand_bytes_ += OS_WORD; - break; - case OT_W: // Word, regardless of operand-size attribute. - operand_bytes_ += OS_WORD; - break; - - // Can safely ignore these. - case OT_A: // Two one-word operands in memory or two double-word - // operands in memory - case OT_PI: // Quadword MMX technology register (e.g. mm0) - case OT_SI: // Doubleword integer register (e.g., eax) - break; - - default: - break; - } - break; - - default: - break; - } - - return succeeded; -} - -bool MiniDisassembler::ProcessModrm(unsigned char* start_byte, - unsigned int* size) { - // If we don't need to decode, we just return the size of the ModR/M - // byte (there is never a SIB byte in this case). - if (!should_decode_modrm_) { - (*size)++; - return true; - } - - // We never care about the reg field, only the combination of the mod - // and r/m fields, so let's start by packing those fields together into - // 5 bits. - unsigned char modrm = (*start_byte); - unsigned char mod = modrm & 0xC0; // mask out top two bits to get mod field - modrm = modrm & 0x07; // mask out bottom 3 bits to get r/m field - mod = mod >> 3; // shift the mod field to the right place - modrm = mod | modrm; // combine the r/m and mod fields as discussed - mod = mod >> 3; // shift the mod field to bits 2..0 - - // Invariant: modrm contains the mod field in bits 4..3 and the r/m field - // in bits 2..0, and mod contains the mod field in bits 2..0 - - const ModrmEntry* modrm_entry = 0; - if (address_is_32_bits_) - modrm_entry = &s_ia32_modrm_map_[modrm]; - else - modrm_entry = &s_ia16_modrm_map_[modrm]; - - // Invariant: modrm_entry points to information that we need to decode - // the ModR/M byte. - - // Add to the count of operand bytes, if the ModR/M byte indicates - // that some operands are encoded in the instruction. - if (modrm_entry->is_encoded_in_instruction_) - operand_bytes_ += modrm_entry->operand_size_; - - // Process the SIB byte if necessary, and return the count - // of ModR/M and SIB bytes. - if (modrm_entry->use_sib_byte_) { - (*size)++; - return ProcessSib(start_byte + 1, mod, size); - } else { - (*size)++; - return true; - } -} - -bool MiniDisassembler::ProcessSib(unsigned char* start_byte, - unsigned char mod, - unsigned int* size) { - // get the mod field from the 2..0 bits of the SIB byte - unsigned char sib_base = (*start_byte) & 0x07; - if (0x05 == sib_base) { - switch (mod) { - case 0x00: // mod == 00 - case 0x02: // mod == 10 - operand_bytes_ += OS_DOUBLE_WORD; - break; - case 0x01: // mod == 01 - operand_bytes_ += OS_BYTE; - break; - case 0x03: // mod == 11 - // According to the IA-32 docs, there does not seem to be a disp - // value for this value of mod - default: - break; - } - } - - (*size)++; - return true; -} - -}; // namespace sidestep diff --git a/sandbox/win/src/sidestep/mini_disassembler.h b/sandbox/win/src/sidestep/mini_disassembler.h deleted file mode 100644 index 202c4ecc20..0000000000 --- a/sandbox/win/src/sidestep/mini_disassembler.h +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2012 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. - -// Definition of MiniDisassembler. - -#ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__ -#define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__ - -#include "sandbox/win/src/sidestep/mini_disassembler_types.h" - -namespace sidestep { - -// This small disassembler is very limited -// in its functionality, and in fact does only the bare minimum required by the -// preamble patching utility. It may be useful for other purposes, however. -// -// The limitations include at least the following: -// -# No support for coprocessor opcodes, MMX, etc. -// -# No machine-readable identification of opcodes or decoding of -// assembly parameters. The name of the opcode (as a string) is given, -// however, to aid debugging. -// -// You may ask what this little disassembler actually does, then? The answer is -// that it does the following, which is exactly what the patching utility needs: -// -# Indicates if opcode is a jump (any kind) or a return (any kind) -// because this is important for the patching utility to determine if -// a function is too short or there are jumps too early in it for it -// to be preamble patched. -// -# The opcode length is always calculated, so that the patching utility -// can figure out where the next instruction starts, and whether it -// already has enough instructions to replace with the absolute jump -// to the patching code. -// -// The usage is quite simple; just create a MiniDisassembler and use its -// Disassemble() method. -// -// If you would like to extend this disassembler, please refer to the -// IA-32 Intel Architecture Software Developer's Manual Volume 2: -// Instruction Set Reference for information about operand decoding -// etc. -class MiniDisassembler { - public: - - // Creates a new instance and sets defaults. - // - // operand_default_32_bits: If true, the default operand size is - // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits. - // address_default_32_bits: If true, the default address size is - // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits. - MiniDisassembler(bool operand_default_32_bits, - bool address_default_32_bits); - - // Equivalent to MiniDisassembler(true, true); - MiniDisassembler(); - - // Attempts to disassemble a single instruction starting from the - // address in memory it is pointed to. - // - // start: Address where disassembly should start. - // instruction_bytes: Variable that will be incremented by - // the length in bytes of the instruction. - // Returns enItJump, enItReturn or enItGeneric on success. enItUnknown - // if unable to disassemble, enItUnused if this seems to be an unused - // opcode. In the last two (error) cases, cbInstruction will be set - // to 0xffffffff. - // - // Postcondition: This instance of the disassembler is ready to be used again, - // with unchanged defaults from creation time. - InstructionType Disassemble(unsigned char* start, - unsigned int* instruction_bytes); - - private: - - // Makes the disassembler ready for reuse. - void Initialize(); - - // Sets the flags for address and operand sizes. - // Returns Number of prefix bytes. - InstructionType ProcessPrefixes(unsigned char* start, unsigned int* size); - - // Sets the flag for whether we have ModR/M, and increments - // operand_bytes_ if any are specifies by the opcode directly. - // Returns Number of opcode bytes. - InstructionType ProcessOpcode(unsigned char* start, - unsigned int table, - unsigned int* size); - - // Checks the type of the supplied operand. Increments - // operand_bytes_ if it directly indicates an immediate etc. - // operand. Asserts have_modrm_ if the operand specifies - // a ModR/M byte. - bool ProcessOperand(int flag_operand); - - // Increments operand_bytes_ by size specified by ModR/M and - // by SIB if present. - // Returns 0 in case of error, 1 if there is just a ModR/M byte, - // 2 if there is a ModR/M byte and a SIB byte. - bool ProcessModrm(unsigned char* start, unsigned int* size); - - // Processes the SIB byte that it is pointed to. - // start: Pointer to the SIB byte. - // mod: The mod field from the ModR/M byte. - // Returns 1 to indicate success (indicates 1 SIB byte) - bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int* size); - - // The instruction type we have decoded from the opcode. - InstructionType instruction_type_; - - // Counts the number of bytes that is occupied by operands in - // the current instruction (note: we don't care about how large - // operands stored in registers etc. are). - unsigned int operand_bytes_; - - // True iff there is a ModR/M byte in this instruction. - bool have_modrm_; - - // True iff we need to decode the ModR/M byte (sometimes it just - // points to a register, we can tell by the addressing mode). - bool should_decode_modrm_; - - // Current operand size is 32 bits if true, 16 bits if false. - bool operand_is_32_bits_; - - // Default operand size is 32 bits if true, 16 bits if false. - bool operand_default_is_32_bits_; - - // Current address size is 32 bits if true, 16 bits if false. - bool address_is_32_bits_; - - // Default address size is 32 bits if true, 16 bits if false. - bool address_default_is_32_bits_; - - // Huge big opcode table based on the IA-32 manual, defined - // in Ia32OpcodeMap.cpp - static const OpcodeTable s_ia32_opcode_map_[]; - - // Somewhat smaller table to help with decoding ModR/M bytes - // when 16-bit addressing mode is being used. Defined in - // Ia32ModrmMap.cpp - static const ModrmEntry s_ia16_modrm_map_[]; - - // Somewhat smaller table to help with decoding ModR/M bytes - // when 32-bit addressing mode is being used. Defined in - // Ia32ModrmMap.cpp - static const ModrmEntry s_ia32_modrm_map_[]; - - // Indicators of whether we got certain prefixes that certain - // silly Intel instructions depend on in nonstandard ways for - // their behaviors. - bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_; -}; - -}; // namespace sidestep - -#endif // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__ diff --git a/sandbox/win/src/sidestep/mini_disassembler_types.h b/sandbox/win/src/sidestep/mini_disassembler_types.h deleted file mode 100644 index 1c10626313..0000000000 --- a/sandbox/win/src/sidestep/mini_disassembler_types.h +++ /dev/null @@ -1,197 +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. -// -// Several simple types used by the disassembler and some of the patching -// mechanisms. - -#ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__ -#define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__ - -namespace sidestep { - -// Categories of instructions that we care about -enum InstructionType { - // This opcode is not used - IT_UNUSED, - // This disassembler does not recognize this opcode (error) - IT_UNKNOWN, - // This is not an instruction but a reference to another table - IT_REFERENCE, - // This byte is a prefix byte that we can ignore - IT_PREFIX, - // This is a prefix byte that switches to the nondefault address size - IT_PREFIX_ADDRESS, - // This is a prefix byte that switches to the nondefault operand size - IT_PREFIX_OPERAND, - // A jump or call instruction - IT_JUMP, - // A return instruction - IT_RETURN, - // Any other type of instruction (in this case we don't care what it is) - IT_GENERIC, -}; - -// Lists IA-32 operand sizes in multiples of 8 bits -enum OperandSize { - OS_ZERO = 0, - OS_BYTE = 1, - OS_WORD = 2, - OS_DOUBLE_WORD = 4, - OS_QUAD_WORD = 8, - OS_DOUBLE_QUAD_WORD = 16, - OS_32_BIT_POINTER = 32/8, - OS_48_BIT_POINTER = 48/8, - OS_SINGLE_PRECISION_FLOATING = 32/8, - OS_DOUBLE_PRECISION_FLOATING = 64/8, - OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8, - OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8, - OS_PSEUDO_DESCRIPTOR = 6 -}; - -// Operand addressing methods from the IA-32 manual. The enAmMask value -// is a mask for the rest. The other enumeration values are named for the -// names given to the addressing methods in the manual, e.g. enAm_D is for -// the D addressing method. -// -// The reason we use a full 4 bytes and a mask, is that we need to combine -// these flags with the enOperandType to store the details -// on the operand in a single integer. -enum AddressingMethod { - AM_NOT_USED = 0, // This operand is not used for this instruction - AM_MASK = 0x00FF0000, // Mask for the rest of the values in this enumeration - AM_A = 0x00010000, // A addressing type - AM_C = 0x00020000, // C addressing type - AM_D = 0x00030000, // D addressing type - AM_E = 0x00040000, // E addressing type - AM_F = 0x00050000, // F addressing type - AM_G = 0x00060000, // G addressing type - AM_I = 0x00070000, // I addressing type - AM_J = 0x00080000, // J addressing type - AM_M = 0x00090000, // M addressing type - AM_O = 0x000A0000, // O addressing type - AM_P = 0x000B0000, // P addressing type - AM_Q = 0x000C0000, // Q addressing type - AM_R = 0x000D0000, // R addressing type - AM_S = 0x000E0000, // S addressing type - AM_T = 0x000F0000, // T addressing type - AM_V = 0x00100000, // V addressing type - AM_W = 0x00110000, // W addressing type - AM_X = 0x00120000, // X addressing type - AM_Y = 0x00130000, // Y addressing type - AM_REGISTER = 0x00140000, // Specific register is always used as this op - AM_IMPLICIT = 0x00150000, // An implicit, fixed value is used -}; - -// Operand types from the IA-32 manual. The enOtMask value is -// a mask for the rest. The rest of the values are named for the -// names given to these operand types in the manual, e.g. enOt_ps -// is for the ps operand type in the manual. -// -// The reason we use a full 4 bytes and a mask, is that we need -// to combine these flags with the enAddressingMethod to store the details -// on the operand in a single integer. -enum OperandType { - OT_MASK = 0xFF000000, - OT_A = 0x01000000, - OT_B = 0x02000000, - OT_C = 0x03000000, - OT_D = 0x04000000, - OT_DQ = 0x05000000, - OT_P = 0x06000000, - OT_PI = 0x07000000, - OT_PS = 0x08000000, // actually unsupported for (we don't know its size) - OT_Q = 0x09000000, - OT_S = 0x0A000000, - OT_SS = 0x0B000000, - OT_SI = 0x0C000000, - OT_V = 0x0D000000, - OT_W = 0x0E000000, - OT_SD = 0x0F000000, // scalar double-precision floating-point value - OT_PD = 0x10000000, // double-precision floating point - // dummy "operand type" for address mode M - which doesn't specify - // operand type - OT_ADDRESS_MODE_M = 0x80000000 -}; - -// Everything that's in an Opcode (see below) except the three -// alternative opcode structs for different prefixes. -struct SpecificOpcode { - // Index to continuation table, or 0 if this is the last - // byte in the opcode. - int table_index_; - - // The opcode type - InstructionType type_; - - // Description of the type of the dest, src and aux operands, - // put together from an enOperandType flag and an enAddressingMethod - // flag. - int flag_dest_; - int flag_source_; - int flag_aux_; - - // We indicate the mnemonic for debugging purposes - const char* mnemonic_; -}; - -// The information we keep in our tables about each of the different -// valid instructions recognized by the IA-32 architecture. -struct Opcode { - // Index to continuation table, or 0 if this is the last - // byte in the opcode. - int table_index_; - - // The opcode type - InstructionType type_; - - // Description of the type of the dest, src and aux operands, - // put together from an enOperandType flag and an enAddressingMethod - // flag. - int flag_dest_; - int flag_source_; - int flag_aux_; - - // We indicate the mnemonic for debugging purposes - const char* mnemonic_; - - // Alternative opcode info if certain prefixes are specified. - // In most cases, all of these are zeroed-out. Only used if - // bPrefixDependent is true. - bool is_prefix_dependent_; - SpecificOpcode opcode_if_f2_prefix_; - SpecificOpcode opcode_if_f3_prefix_; - SpecificOpcode opcode_if_66_prefix_; -}; - -// Information about each table entry. -struct OpcodeTable { - // Table of instruction entries - const Opcode* table_; - // How many bytes left to shift ModR/M byte <b>before</b> applying mask - unsigned char shift_; - // Mask to apply to byte being looked at before comparing to table - unsigned char mask_; - // Minimum/maximum indexes in table. - unsigned char min_lim_; - unsigned char max_lim_; -}; - -// Information about each entry in table used to decode ModR/M byte. -struct ModrmEntry { - // Is the operand encoded as bytes in the instruction (rather than - // if it's e.g. a register in which case it's just encoded in the - // ModR/M byte) - bool is_encoded_in_instruction_; - - // Is there a SIB byte? In this case we always need to decode it. - bool use_sib_byte_; - - // What is the size of the operand (only important if it's encoded - // in the instruction)? - OperandSize operand_size_; -}; - -}; // namespace sidestep - -#endif // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__ diff --git a/sandbox/win/src/sidestep/preamble_patcher.h b/sandbox/win/src/sidestep/preamble_patcher.h deleted file mode 100644 index 3a0985ce9f..0000000000 --- a/sandbox/win/src/sidestep/preamble_patcher.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2012 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. - -// Definition of PreamblePatcher - -#ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ -#define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ - -#include <stddef.h> - -namespace sidestep { - -// Maximum size of the preamble stub. We overwrite at least the first 5 -// bytes of the function. Considering the worst case scenario, we need 4 -// bytes + the max instruction size + 5 more bytes for our jump back to -// the original code. With that in mind, 32 is a good number :) -const size_t kMaxPreambleStubSize = 32; - -// Possible results of patching/unpatching -enum SideStepError { - SIDESTEP_SUCCESS = 0, - SIDESTEP_INVALID_PARAMETER, - SIDESTEP_INSUFFICIENT_BUFFER, - SIDESTEP_JUMP_INSTRUCTION, - SIDESTEP_FUNCTION_TOO_SMALL, - SIDESTEP_UNSUPPORTED_INSTRUCTION, - SIDESTEP_NO_SUCH_MODULE, - SIDESTEP_NO_SUCH_FUNCTION, - SIDESTEP_ACCESS_DENIED, - SIDESTEP_UNEXPECTED, -}; - -// Implements a patching mechanism that overwrites the first few bytes of -// a function preamble with a jump to our hook function, which is then -// able to call the original function via a specially-made preamble-stub -// that imitates the action of the original preamble. -// -// Note that there are a number of ways that this method of patching can -// fail. The most common are: -// - If there is a jump (jxx) instruction in the first 5 bytes of -// the function being patched, we cannot patch it because in the -// current implementation we do not know how to rewrite relative -// jumps after relocating them to the preamble-stub. Note that -// if you really really need to patch a function like this, it -// would be possible to add this functionality (but at some cost). -// - If there is a return (ret) instruction in the first 5 bytes -// we cannot patch the function because it may not be long enough -// for the jmp instruction we use to inject our patch. -// - If there is another thread currently executing within the bytes -// that are copied to the preamble stub, it will crash in an undefined -// way. -// -// If you get any other error than the above, you're either pointing the -// patcher at an invalid instruction (e.g. into the middle of a multi- -// byte instruction, or not at memory containing executable instructions) -// or, there may be a bug in the disassembler we use to find -// instruction boundaries. -class PreamblePatcher { - public: - // Patches target_function to point to replacement_function using a provided - // preamble_stub of stub_size bytes. - // Returns An error code indicating the result of patching. - template <class T> - static SideStepError Patch(T target_function, T replacement_function, - void* preamble_stub, size_t stub_size) { - return RawPatchWithStub(target_function, replacement_function, - reinterpret_cast<unsigned char*>(preamble_stub), - stub_size, NULL); - } - - private: - - // Patches a function by overwriting its first few bytes with - // a jump to a different function. This is similar to the RawPatch - // function except that it uses the stub allocated by the caller - // instead of allocating it. - // - // To use this function, you first have to call VirtualProtect to make the - // target function writable at least for the duration of the call. - // - // target_function: A pointer to the function that should be - // patched. - // - // replacement_function: A pointer to the function that should - // replace the target function. The replacement function must have - // exactly the same calling convention and parameters as the original - // function. - // - // preamble_stub: A pointer to a buffer where the preamble stub - // should be copied. The size of the buffer should be sufficient to - // hold the preamble bytes. - // - // stub_size: Size in bytes of the buffer allocated for the - // preamble_stub - // - // bytes_needed: Pointer to a variable that receives the minimum - // number of bytes required for the stub. Can be set to NULL if you're - // not interested. - // - // Returns An error code indicating the result of patching. - static SideStepError RawPatchWithStub(void* target_function, - void *replacement_function, - unsigned char* preamble_stub, - size_t stub_size, - size_t* bytes_needed); -}; - -}; // namespace sidestep - -#endif // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ diff --git a/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp b/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp deleted file mode 100644 index b5016009d6..0000000000 --- a/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2012 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. - -// Implementation of PreamblePatcher - -#include "sandbox/win/src/sidestep/preamble_patcher.h" - -#include <stddef.h> - -#include "sandbox/win/src/sandbox_nt_util.h" -#include "sandbox/win/src/sidestep/mini_disassembler.h" - -// Definitions of assembly statements we need -#define ASM_JMP32REL 0xE9 -#define ASM_INT3 0xCC - -namespace { - -// Very basic memcpy. We are copying 4 to 12 bytes most of the time, so there -// is no attempt to optimize this code or have a general purpose function. -// We don't want to call the crt from this code. -inline void* RawMemcpy(void* destination, const void* source, size_t bytes) { - const char* from = reinterpret_cast<const char*>(source); - char* to = reinterpret_cast<char*>(destination); - - for (size_t i = 0; i < bytes ; i++) - to[i] = from[i]; - - return destination; -} - -// Very basic memset. We are filling 1 to 7 bytes most of the time, so there -// is no attempt to optimize this code or have a general purpose function. -// We don't want to call the crt from this code. -inline void* RawMemset(void* destination, int value, size_t bytes) { - char* to = reinterpret_cast<char*>(destination); - - for (size_t i = 0; i < bytes ; i++) - to[i] = static_cast<char>(value); - - return destination; -} - -} // namespace - -#define ASSERT(a, b) DCHECK_NT(a) - -namespace sidestep { - -SideStepError PreamblePatcher::RawPatchWithStub( - void* target_function, - void* replacement_function, - unsigned char* preamble_stub, - size_t stub_size, - size_t* bytes_needed) { - if ((NULL == target_function) || - (NULL == replacement_function) || - (NULL == preamble_stub)) { - ASSERT(false, (L"Invalid parameters - either pTargetFunction or " - L"pReplacementFunction or pPreambleStub were NULL.")); - return SIDESTEP_INVALID_PARAMETER; - } - - // TODO(V7:joi) Siggi and I just had a discussion and decided that both - // patching and unpatching are actually unsafe. We also discussed a - // method of making it safe, which is to freeze all other threads in the - // process, check their thread context to see if their eip is currently - // inside the block of instructions we need to copy to the stub, and if so - // wait a bit and try again, then unfreeze all threads once we've patched. - // Not implementing this for now since we're only using SideStep for unit - // testing, but if we ever use it for production code this is what we - // should do. - // - // NOTE: Stoyan suggests we can write 8 or even 10 bytes atomically using - // FPU instructions, and on newer processors we could use cmpxchg8b or - // cmpxchg16b. So it might be possible to do the patching/unpatching - // atomically and avoid having to freeze other threads. Note though, that - // doing it atomically does not help if one of the other threads happens - // to have its eip in the middle of the bytes you change while you change - // them. - unsigned char* target = reinterpret_cast<unsigned char*>(target_function); - - // Let's disassemble the preamble of the target function to see if we can - // patch, and to see how much of the preamble we need to take. We need 5 - // bytes for our jmp instruction, so let's find the minimum number of - // instructions to get 5 bytes. - MiniDisassembler disassembler; - unsigned int preamble_bytes = 0; - while (preamble_bytes < 5) { - InstructionType instruction_type = - disassembler.Disassemble(target + preamble_bytes, &preamble_bytes); - if (IT_JUMP == instruction_type) { - ASSERT(false, (L"Unable to patch because there is a jump instruction " - L"in the first 5 bytes.")); - return SIDESTEP_JUMP_INSTRUCTION; - } else if (IT_RETURN == instruction_type) { - ASSERT(false, (L"Unable to patch because function is too short")); - return SIDESTEP_FUNCTION_TOO_SMALL; - } else if (IT_GENERIC != instruction_type) { - ASSERT(false, (L"Disassembler encountered unsupported instruction " - L"(either unused or unknown")); - return SIDESTEP_UNSUPPORTED_INSTRUCTION; - } - } - - if (NULL != bytes_needed) - *bytes_needed = preamble_bytes + 5; - - // Inv: preamble_bytes is the number of bytes (at least 5) that we need to - // take from the preamble to have whole instructions that are 5 bytes or more - // in size total. The size of the stub required is cbPreamble + size of - // jmp (5) - if (preamble_bytes + 5 > stub_size) { - NOTREACHED_NT(); - return SIDESTEP_INSUFFICIENT_BUFFER; - } - - // First, copy the preamble that we will overwrite. - RawMemcpy(reinterpret_cast<void*>(preamble_stub), - reinterpret_cast<void*>(target), preamble_bytes); - - // Now, make a jmp instruction to the rest of the target function (minus the - // preamble bytes we moved into the stub) and copy it into our preamble-stub. - // find address to jump to, relative to next address after jmp instruction -#pragma warning(push) -#pragma warning(disable:4244) - // This assignment generates a warning because it is 32 bit specific. - int relative_offset_to_target_rest - = ((reinterpret_cast<unsigned char*>(target) + preamble_bytes) - - (preamble_stub + preamble_bytes + 5)); -#pragma warning(pop) - // jmp (Jump near, relative, displacement relative to next instruction) - preamble_stub[preamble_bytes] = ASM_JMP32REL; - // copy the address - RawMemcpy(reinterpret_cast<void*>(preamble_stub + preamble_bytes + 1), - reinterpret_cast<void*>(&relative_offset_to_target_rest), 4); - - // Inv: preamble_stub points to assembly code that will execute the - // original function by first executing the first cbPreamble bytes of the - // preamble, then jumping to the rest of the function. - - // Overwrite the first 5 bytes of the target function with a jump to our - // replacement function. - // (Jump near, relative, displacement relative to next instruction) - target[0] = ASM_JMP32REL; - - // Find offset from instruction after jmp, to the replacement function. -#pragma warning(push) -#pragma warning(disable:4244) - int offset_to_replacement_function = - reinterpret_cast<unsigned char*>(replacement_function) - - reinterpret_cast<unsigned char*>(target) - 5; -#pragma warning(pop) - // complete the jmp instruction - RawMemcpy(reinterpret_cast<void*>(target + 1), - reinterpret_cast<void*>(&offset_to_replacement_function), 4); - // Set any remaining bytes that were moved to the preamble-stub to INT3 so - // as not to cause confusion (otherwise you might see some strange - // instructions if you look at the disassembly, or even invalid - // instructions). Also, by doing this, we will break into the debugger if - // some code calls into this portion of the code. If this happens, it - // means that this function cannot be patched using this patcher without - // further thought. - if (preamble_bytes > 5) { - RawMemset(reinterpret_cast<void*>(target + 5), ASM_INT3, - preamble_bytes - 5); - } - - // Inv: The memory pointed to by target_function now points to a relative - // jump instruction that jumps over to the preamble_stub. The preamble - // stub contains the first stub_size bytes of the original target - // function's preamble code, followed by a relative jump back to the next - // instruction after the first cbPreamble bytes. - - return SIDESTEP_SUCCESS; -} - -}; // namespace sidestep - -#undef ASSERT diff --git a/sandbox/win/tests/integration_tests/sbox_integration_tests.vcproj b/sandbox/win/tests/integration_tests/sbox_integration_tests.vcproj deleted file mode 100644 index 53816e73e2..0000000000 --- a/sandbox/win/tests/integration_tests/sbox_integration_tests.vcproj +++ /dev/null @@ -1,242 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="sbox_integration_tests" - ProjectGUID="{542D4B3B-98D4-4233-B68D-0103891508C6}" - RootNamespace="unit_tests" - 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;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - PreprocessorDefinitions="_CONSOLE" - UsePrecompiledHeader="2" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalOptions="/safeseh /dynamicbase /ignore:4199 $(NoInherit)" - /> - <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;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - PreprocessorDefinitions="_CONSOLE" - UsePrecompiledHeader="0" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalOptions="/safeseh /dynamicbase /ignore:4199 $(NoInherit)" - /> - <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> - <Filter - Name="Common" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{49F2D231-E141-4455-B241-7D37C09B6EEB}" - > - <File - RelativePath="..\common\controller.cc" - > - </File> - <File - RelativePath="..\common\controller.h" - > - </File> - <File - RelativePath="..\..\..\testing\gtest\src\gtest.cc" - > - </File> - <File - RelativePath=".\integration_tests.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> - </Filter> - <File - RelativePath="..\..\src\dep_test.cc" - > - </File> - <File - RelativePath="..\..\src\file_policy_test.cc" - > - </File> - <File - RelativePath=".\integration_tests_test.cc" - > - </File> - <File - RelativePath="..\..\src\integrity_level_test.cc" - > - </File> - <File - RelativePath="..\..\src\ipc_ping_test.cc" - > - </File> - <File - RelativePath="..\..\src\named_pipe_policy_test.cc" - > - </File> - <File - RelativePath="..\..\src\policy_target_test.cc" - > - </File> - <File - RelativePath="..\..\src\process_policy_test.cc" - > - </File> - <File - RelativePath="..\..\src\registry_policy_test.cc" - > - </File> - <File - RelativePath="..\..\src\sync_policy_test.cc" - > - </File> - <File - RelativePath="..\..\src\unload_dll_test.cc" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/sandbox/win/tests/unit_tests/sbox_unittests.vcproj b/sandbox/win/tests/unit_tests/sbox_unittests.vcproj deleted file mode 100644 index a2df79210c..0000000000 --- a/sandbox/win/tests/unit_tests/sbox_unittests.vcproj +++ /dev/null @@ -1,258 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="sbox_unittests" - ProjectGUID="{883553BE-2A9D-418C-A121-61FE1DFBC562}" - RootNamespace="unit_tests" - 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;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - PreprocessorDefinitions="_CONSOLE" - UsePrecompiledHeader="2" - WarningLevel="3" - 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;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - PreprocessorDefinitions="_CONSOLE" - UsePrecompiledHeader="0" - WarningLevel="3" - /> - <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> - <Filter - Name="Common" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - <File - RelativePath="..\..\..\testing\gtest\src\gtest.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> - <File - RelativePath=".\unit_tests.cc" - > - </File> - </Filter> - <Filter - Name="TestInterception" - > - <File - RelativePath="..\..\src\interception_unittest.cc" - > - </File> - <File - RelativePath="..\..\src\pe_image_unittest.cc" - > - </File> - <File - RelativePath="..\..\src\service_resolver_unittest.cc" - > - </File> - </Filter> - <Filter - Name="TestRestrictedToken" - > - <File - RelativePath="..\..\src\restricted_token_unittest.cc" - > - </File> - </Filter> - <Filter - Name="TestJob" - > - <File - RelativePath="..\..\src\job_unittest.cc" - > - </File> - </Filter> - <Filter - Name="Sid" - > - <File - RelativePath="..\..\src\sid_unittest.cc" - > - </File> - </Filter> - <Filter - Name="Policy" - > - <File - RelativePath="..\..\src\policy_engine_unittest.cc" - > - </File> - <File - RelativePath="..\..\src\policy_low_level_unittest.cc" - > - </File> - <File - RelativePath="..\..\src\policy_opcodes_unittest.cc" - > - </File> - </Filter> - <Filter - Name="IPC" - > - <File - RelativePath="..\..\src\ipc_unittest.cc" - > - </File> - <File - RelativePath="..\..\src\threadpool_unittest.cc" - > - </File> - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/sandbox/win/tests/validation_tests/sbox_validation_tests.vcproj b/sandbox/win/tests/validation_tests/sbox_validation_tests.vcproj deleted file mode 100644 index 9b7b599295..0000000000 --- a/sandbox/win/tests/validation_tests/sbox_validation_tests.vcproj +++ /dev/null @@ -1,216 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="sbox_validation_tests" - ProjectGUID="{B9CC7B0D-145A-49C2-B887-84E43CFA0F27}" - RootNamespace="unit_tests" - 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;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - PreprocessorDefinitions="_CONSOLE" - UsePrecompiledHeader="2" - WarningLevel="3" - ForcedIncludeFiles="stdafx.h" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="shlwapi.lib" - /> - <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;$(SolutionDir)..\testing\using_gtest.vsprops" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - PreprocessorDefinitions="_CONSOLE" - UsePrecompiledHeader="0" - WarningLevel="3" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="shlwapi.lib" - /> - <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> - <Filter - Name="Common" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{2E6C7E35-7538-4883-B80C-C89961A80D66}" - > - <File - RelativePath="..\common\controller.cc" - > - </File> - <File - RelativePath="..\common\controller.h" - > - </File> - <File - RelativePath="..\..\..\testing\gtest\src\gtest.cc" - > - </File> - <File - RelativePath=".\stdafx.cc" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\stdafx.h" - > - </File> - <File - RelativePath=".\unit_tests.cc" - > - </File> - </Filter> - <Filter - Name="Suite" - > - <File - RelativePath=".\commands.cc" - > - </File> - <File - RelativePath=".\commands.h" - > - </File> - <File - RelativePath=".\suite.cc" - > - </File> - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/sandbox/win/tools/finder/finder.vcproj b/sandbox/win/tools/finder/finder.vcproj deleted file mode 100644 index 787c8477c2..0000000000 --- a/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/sandbox/win/tools/finder/ntundoc.h b/sandbox/win/tools/finder/ntundoc.h deleted file mode 100644 index dc8c3a57cb..0000000000 --- a/sandbox/win/tools/finder/ntundoc.h +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) 2006-2011 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_NTUNDOC_H__ -#define SANDBOX_TOOLS_FINDER_NTUNDOC_H__ - -#define NTSTATUS ULONG -#define STATUS_SUCCESS 0x00000000 -#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 -#define STATUS_ACCESS_DENIED 0xC0000022 -#define STATUS_BUFFER_OVERFLOW 0x80000005 - -typedef struct _LSA_UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING; - -typedef struct _OBJDIR_INFORMATION { - UNICODE_STRING ObjectName; - UNICODE_STRING ObjectTypeName; - BYTE Data[1]; -} OBJDIR_INFORMATION; - -typedef struct _OBJECT_ATTRIBUTES { - ULONG Length; - HANDLE RootDirectory; - UNICODE_STRING *ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES; - -typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION { - ULONG Attributes; - ACCESS_MASK GrantedAccess; - ULONG HandleCount; - ULONG PointerCount; - ULONG Reserved[10]; // reserved for internal use - } PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION; - -typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION { - UNICODE_STRING TypeName; - ULONG Reserved [22]; // reserved for internal use -} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION; - -typedef enum _POOL_TYPE { - NonPagedPool, - PagedPool, - NonPagedPoolMustSucceed, - ReservedType, - NonPagedPoolCacheAligned, - PagedPoolCacheAligned, - NonPagedPoolCacheAlignedMustS -} POOL_TYPE; - -typedef struct _OBJECT_TYPE_INFORMATION { - UNICODE_STRING Name; - ULONG TotalNumberOfObjects; - ULONG TotalNumberOfHandles; - ULONG TotalPagedPoolUsage; - ULONG TotalNonPagedPoolUsage; - ULONG TotalNamePoolUsage; - ULONG TotalHandleTableUsage; - ULONG HighWaterNumberOfObjects; - ULONG HighWaterNumberOfHandles; - ULONG HighWaterPagedPoolUsage; - ULONG HighWaterNonPagedPoolUsage; - ULONG HighWaterNamePoolUsage; - ULONG HighWaterHandleTableUsage; - ULONG InvalidAttributes; - GENERIC_MAPPING GenericMapping; - ULONG ValidAccess; - BOOLEAN SecurityRequired; - BOOLEAN MaintainHandleCount; - USHORT MaintainTypeList; - POOL_TYPE PoolType; - ULONG PagedPoolUsage; - ULONG NonPagedPoolUsage; -} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; - -typedef struct _OBJECT_NAME_INFORMATION { - UNICODE_STRING ObjectName; -} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; - -typedef enum _OBJECT_INFORMATION_CLASS { - ObjectBasicInformation, - ObjectNameInformation, - ObjectTypeInformation, - ObjectAllInformation, - ObjectDataInformation -} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - -typedef enum _FILE_INFORMATION_CLASS { - // end_wdm - FileDirectoryInformation = 1, - FileFullDirectoryInformation, // 2 - FileBothDirectoryInformation, // 3 - FileBasicInformation, // 4 wdm - FileStandardInformation, // 5 wdm - FileInternalInformation, // 6 - FileEaInformation, // 7 - FileAccessInformation, // 8 - FileNameInformation, // 9 - FileRenameInformation, // 10 - FileLinkInformation, // 11 - FileNamesInformation, // 12 - FileDispositionInformation, // 13 - FilePositionInformation, // 14 wdm - FileFullEaInformation, // 15 - FileModeInformation, // 16 - FileAlignmentInformation, // 17 - FileAllInformation, // 18 - FileAllocationInformation, // 19 - FileEndOfFileInformation, // 20 wdm - FileAlternateNameInformation, // 21 - FileStreamInformation, // 22 - FilePipeInformation, // 23 - FilePipeLocalInformation, // 24 - FilePipeRemoteInformation, // 25 - FileMailslotQueryInformation, // 26 - FileMailslotSetInformation, // 27 - FileCompressionInformation, // 28 - FileObjectIdInformation, // 29 - FileCompletionInformation, // 30 - FileMoveClusterInformation, // 31 - FileQuotaInformation, // 32 - FileReparsePointInformation, // 33 - FileNetworkOpenInformation, // 34 - FileAttributeTagInformation, // 35 - FileTrackingInformation, // 36 - FileMaximumInformation - // begin_wdm -} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; - -typedef enum _SYSTEM_INFORMATION_CLASS { - SystemHandleInformation = 16 -} SYSTEM_INFORMATION_CLASS; - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - }; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -#define InitializeObjectAttributes( p, n, a, r, s ) { \ - (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ - (p)->RootDirectory = r; \ - (p)->Attributes = a; \ - (p)->ObjectName = n; \ - (p)->SecurityDescriptor = s; \ - (p)->SecurityQualityOfService = NULL; \ -} - -typedef struct _SYSTEM_HANDLE_INFORMATION { - USHORT ProcessId; - USHORT CreatorBackTraceIndex; - UCHAR ObjectTypeNumber; - UCHAR Flags; - USHORT Handle; - PVOID Object; - ACCESS_MASK GrantedAccess; -} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; - -typedef struct _SYSTEM_HANDLE_INFORMATION_EX { - ULONG NumberOfHandles; - SYSTEM_HANDLE_INFORMATION Information[1]; -} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; - -#define POBJECT_ATTRIBUTES OBJECT_ATTRIBUTES* - -typedef NTSTATUS (WINAPI* NTQUERYDIRECTORYOBJECT)( - HANDLE, - OBJDIR_INFORMATION*, - DWORD, - DWORD, - DWORD, - DWORD*, - DWORD*); - -typedef NTSTATUS (WINAPI* NTOPENDIRECTORYOBJECT)( - HANDLE *, - DWORD, - OBJECT_ATTRIBUTES* ); - -typedef NTSTATUS (WINAPI* NTGENERICOPEN) ( - OUT PHANDLE EventHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENEVENT)( - OUT PHANDLE EventHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENJOBOBJECT)( - OUT PHANDLE JobHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENKEYEDEVENT)( - OUT PHANDLE KeyedEventHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENMUTANT)( - OUT PHANDLE MutantHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENSECTION)( - OUT PHANDLE SectionHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENSEMAPHORE)( - OUT PHANDLE SemaphoreHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENSYMBOLICLINKOBJECT)( - OUT PHANDLE SymbolicLinkHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENTIMER)( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes); - -typedef NTSTATUS (WINAPI* NTOPENFILE)( - HANDLE *, - DWORD, - OBJECT_ATTRIBUTES *, - IO_STATUS_BLOCK *, - DWORD, - DWORD); - -typedef NTSTATUS (WINAPI* NTQUERYINFORMATIONFILE)( - HANDLE, - PIO_STATUS_BLOCK, - PVOID, - ULONG, - FILE_INFORMATION_CLASS); - -typedef NTSTATUS (WINAPI* NTQUERYSYSTEMINFORMATION)( - SYSTEM_INFORMATION_CLASS SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength); - -typedef NTSTATUS (WINAPI* NTQUERYOBJECT)( - HANDLE Handle, - OBJECT_INFORMATION_CLASS ObjectInformationClass, - PVOID ObjectInformation, - ULONG ObjectInformationLength, - PULONG ReturnLength); - -typedef NTSTATUS (WINAPI* NTCLOSE) (HANDLE); - -#define DIRECTORY_QUERY 0x0001 -#define DIRECTORY_TRAVERSE 0x0002 -#define DIRECTORY_CREATE_OBJECT 0x0004 -#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 -#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF) - -#endif // SANDBOX_TOOLS_FINDER_NTUNDOC_H__ diff --git a/sandbox/win/tools/launcher/launcher.vcproj b/sandbox/win/tools/launcher/launcher.vcproj deleted file mode 100644 index 71ed011d2b..0000000000 --- a/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> diff --git a/sandbox/win/wow_helper/wow_helper.exe b/sandbox/win/wow_helper/wow_helper.exe Binary files differdeleted file mode 100755 index f9bfb4bbdd..0000000000 --- a/sandbox/win/wow_helper/wow_helper.exe +++ /dev/null diff --git a/sandbox/win/wow_helper/wow_helper.pdb b/sandbox/win/wow_helper/wow_helper.pdb Binary files differdeleted file mode 100644 index 9cb67d001d..0000000000 --- a/sandbox/win/wow_helper/wow_helper.pdb +++ /dev/null |