mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Introduce config header to centralize CPU architecture checks
This allows us to remove some uses of macros. Related changes: - Make it clear that we support hosting sandboxed binaries from 64-bit processes only. CPU architectures are x86-64 and POWER64 (little endian). - Introduced CPU architecture macros, abstracting away compiler specifics PiperOrigin-RevId: 330918134 Change-Id: Ife7ad5f14723eec9f68055127b0583b8aecd38dd
This commit is contained in:
parent
1f8e88586b
commit
6a1e4b881c
|
@ -26,6 +26,13 @@ licenses(["notice"]) # Apache 2.0
|
||||||
|
|
||||||
exports_files(["testdata/hostname"])
|
exports_files(["testdata/hostname"])
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "config",
|
||||||
|
hdrs = ["config.h"],
|
||||||
|
copts = sapi_platform_copts(),
|
||||||
|
deps = ["@com_google_absl//absl/base:config"],
|
||||||
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "bpfdisassembler",
|
name = "bpfdisassembler",
|
||||||
srcs = ["bpfdisassembler.cc"],
|
srcs = ["bpfdisassembler.cc"],
|
||||||
|
@ -40,6 +47,7 @@ cc_library(
|
||||||
hdrs = ["regs.h"],
|
hdrs = ["regs.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":syscall",
|
":syscall",
|
||||||
":violation_cc_proto",
|
":violation_cc_proto",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
|
@ -60,6 +68,7 @@ cc_library(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":util",
|
":util",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
|
@ -73,6 +82,7 @@ cc_test(
|
||||||
srcs = ["syscall_test.cc"],
|
srcs = ["syscall_test.cc"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":syscall",
|
":syscall",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_googletest//:gtest_main",
|
"@com_google_googletest//:gtest_main",
|
||||||
|
@ -85,6 +95,7 @@ cc_library(
|
||||||
hdrs = ["result.h"],
|
hdrs = ["result.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":regs",
|
":regs",
|
||||||
":syscall",
|
":syscall",
|
||||||
":util",
|
":util",
|
||||||
|
@ -272,6 +283,7 @@ cc_library(
|
||||||
deps = [
|
deps = [
|
||||||
":client",
|
":client",
|
||||||
":comms",
|
":comms",
|
||||||
|
":config",
|
||||||
":executor",
|
":executor",
|
||||||
":fork_client",
|
":fork_client",
|
||||||
":forkserver_cc_proto",
|
":forkserver_cc_proto",
|
||||||
|
@ -404,6 +416,7 @@ cc_library(
|
||||||
hdrs = ["mounts.h"],
|
hdrs = ["mounts.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":mounttree_cc_proto",
|
":mounttree_cc_proto",
|
||||||
"//sandboxed_api/sandbox2/util:file_base",
|
"//sandboxed_api/sandbox2/util:file_base",
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
|
@ -468,6 +481,7 @@ cc_test(
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
":comms",
|
":comms",
|
||||||
|
":config",
|
||||||
":namespace",
|
":namespace",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
|
@ -505,6 +519,7 @@ cc_library(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
"//sandboxed_api/sandbox2/util:file_base",
|
"//sandboxed_api/sandbox2/util:file_base",
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
|
@ -541,6 +556,7 @@ cc_test(
|
||||||
deps = [
|
deps = [
|
||||||
":buffer",
|
":buffer",
|
||||||
":comms",
|
":comms",
|
||||||
|
":config",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
"//sandboxed_api/util:status_matchers",
|
"//sandboxed_api/util:status_matchers",
|
||||||
|
@ -629,6 +645,7 @@ cc_test(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
data = ["//sandboxed_api/sandbox2/testcases:limits"],
|
data = ["//sandboxed_api/sandbox2/testcases:limits"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":limits",
|
":limits",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
|
@ -671,6 +688,7 @@ cc_test(
|
||||||
"//sandboxed_api/sandbox2/testcases:policy",
|
"//sandboxed_api/sandbox2/testcases:policy",
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":limits",
|
":limits",
|
||||||
":regs",
|
":regs",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
|
@ -695,6 +713,7 @@ cc_test(
|
||||||
],
|
],
|
||||||
tags = ["local"],
|
tags = ["local"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||||
|
|
|
@ -17,6 +17,16 @@ add_subdirectory(unwind)
|
||||||
add_subdirectory(util)
|
add_subdirectory(util)
|
||||||
add_subdirectory(network_proxy)
|
add_subdirectory(network_proxy)
|
||||||
|
|
||||||
|
# sandboxed_api/sandbox2:config
|
||||||
|
add_library(sandbox2_config STATIC
|
||||||
|
config.h
|
||||||
|
)
|
||||||
|
add_library(sandbox2::config ALIAS sandbox2_config)
|
||||||
|
target_link_libraries(sandbox2_config PRIVATE
|
||||||
|
absl::config
|
||||||
|
sapi::base
|
||||||
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2:bpfdisassembler
|
# sandboxed_api/sandbox2:bpfdisassembler
|
||||||
add_library(sandbox2_bpfdisassembler STATIC
|
add_library(sandbox2_bpfdisassembler STATIC
|
||||||
bpfdisassembler.cc
|
bpfdisassembler.cc
|
||||||
|
@ -37,6 +47,7 @@ add_library(sandbox2::regs ALIAS sandbox2_regs)
|
||||||
target_link_libraries(sandbox2_regs PRIVATE
|
target_link_libraries(sandbox2_regs PRIVATE
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sandbox2::syscall
|
sandbox2::syscall
|
||||||
sandbox2::violation_proto
|
sandbox2::violation_proto
|
||||||
|
@ -72,6 +83,7 @@ target_link_libraries(sandbox2_result PRIVATE
|
||||||
absl::base
|
absl::base
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::regs
|
sandbox2::regs
|
||||||
sandbox2::syscall
|
sandbox2::syscall
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
|
@ -280,6 +292,7 @@ target_link_libraries(sandbox2_sandbox2
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
sandbox2::client
|
sandbox2::client
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::executor
|
sandbox2::executor
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
|
@ -403,6 +416,7 @@ target_link_libraries(sandbox2_mounts PRIVATE
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
protobuf::libprotobuf
|
protobuf::libprotobuf
|
||||||
|
sandbox2::config
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
sandbox2::minielf
|
sandbox2::minielf
|
||||||
|
@ -460,6 +474,7 @@ target_link_libraries(sandbox2_util
|
||||||
PRIVATE absl::core_headers
|
PRIVATE absl::core_headers
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
|
@ -570,6 +585,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
)
|
)
|
||||||
target_link_libraries(syscall_test PRIVATE
|
target_link_libraries(syscall_test PRIVATE
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::syscall
|
sandbox2::syscall
|
||||||
sapi::test_main
|
sapi::test_main
|
||||||
)
|
)
|
||||||
|
@ -608,6 +624,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
sandbox2::namespace
|
sandbox2::namespace
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
|
@ -632,6 +649,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
sandbox2::buffer
|
sandbox2::buffer
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
sandbox2::testing
|
sandbox2::testing
|
||||||
sapi::status_matchers
|
sapi::status_matchers
|
||||||
|
@ -706,6 +724,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
target_link_libraries(limits_test PRIVATE
|
target_link_libraries(limits_test PRIVATE
|
||||||
absl::memory
|
absl::memory
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
|
sandbox2::config
|
||||||
sandbox2::limits
|
sandbox2::limits
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
sandbox2::testing
|
sandbox2::testing
|
||||||
|
@ -755,6 +774,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
|
sandbox2::config
|
||||||
sandbox2::limits
|
sandbox2::limits
|
||||||
sandbox2::regs
|
sandbox2::regs
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
|
@ -780,6 +800,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
|
sandbox2::config
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
sandbox2::testing
|
sandbox2::testing
|
||||||
sapi::status_matchers
|
sapi::status_matchers
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/ipc.h"
|
#include "sandboxed_api/sandbox2/ipc.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
|
@ -90,12 +91,6 @@ std::unique_ptr<Policy> BufferTestcasePolicy() {
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
#if defined(__powerpc64__)
|
|
||||||
|
|
||||||
s2p->AllowUnsafeMmapFiles();
|
|
||||||
s2p->AllowUnsafeMmapShared();
|
|
||||||
#endif /* defined(__powerpc64__) */
|
|
||||||
|
|
||||||
return s2p;
|
return s2p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
83
sandboxed_api/sandbox2/config.h
Normal file
83
sandboxed_api/sandbox2/config.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef SANDBOXED_API_SANDBOX2_CONFIG_H_
|
||||||
|
#define SANDBOXED_API_SANDBOX2_CONFIG_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
|
|
||||||
|
// GCC/Clang define __x86_64__, Visual Studio uses _M_X64
|
||||||
|
#if defined(__x86_64__) || defined(_M_X64)
|
||||||
|
#define SAPI_X86_64 1
|
||||||
|
|
||||||
|
// Check various spellings for 64-bit POWER. Not checking for Visual Studio, as
|
||||||
|
// it does not support 64-bit POWER.
|
||||||
|
#elif (defined(__PPC64__) || defined(__powerpc64__) || defined(__ppc64__)) && \
|
||||||
|
defined(ABSL_IS_LITTLE_ENDIAN)
|
||||||
|
#define SAPI_PPC64_LE 1
|
||||||
|
|
||||||
|
// Spellings for AArch64
|
||||||
|
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||||
|
#define SAPI_ARM64 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
namespace cpu {
|
||||||
|
|
||||||
|
// CPU architectures known to Sandbox2
|
||||||
|
enum Architecture : uint16_t {
|
||||||
|
// Linux: Use a magic value, so it can be easily spotted in the seccomp-bpf
|
||||||
|
// bytecode decompilation stream. Must be < (1<<15), as/ that's the size of
|
||||||
|
// data which can be returned by BPF.
|
||||||
|
kUnknown = 0xCAF0,
|
||||||
|
kX8664,
|
||||||
|
kX86,
|
||||||
|
kPPC64LE,
|
||||||
|
kArm64,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cpu
|
||||||
|
|
||||||
|
namespace host_cpu {
|
||||||
|
|
||||||
|
// Returns the current host CPU architecture if supported. If not supported,
|
||||||
|
// returns cpu::kUnknown.
|
||||||
|
constexpr cpu::Architecture Architecture() {
|
||||||
|
#if defined(SAPI_X86_64)
|
||||||
|
return cpu::kX8664;
|
||||||
|
#elif defined(SAPI_PPC64_LE)
|
||||||
|
return cpu::kPPC64LE;
|
||||||
|
#else
|
||||||
|
return cpu::kUnknown;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsX8664() { return Architecture() == cpu::kX8664; }
|
||||||
|
|
||||||
|
constexpr bool IsPPC64LE() { return Architecture() == cpu::kPPC64LE; }
|
||||||
|
|
||||||
|
constexpr bool IsArm64() { return Architecture() == cpu::kArm64; }
|
||||||
|
|
||||||
|
} // namespace host_cpu
|
||||||
|
|
||||||
|
static_assert(host_cpu::Architecture() != cpu::kUnknown,
|
||||||
|
"Host CPU architecture is not supported: One of x86-64 or "
|
||||||
|
"POWER64 (little endian) is required.");
|
||||||
|
|
||||||
|
} // namespace sandbox2
|
||||||
|
|
||||||
|
#endif // SANDBOXED_API_SANDBOX2_CONFIG_H_
|
|
@ -23,6 +23,7 @@
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "absl/time/time.h"
|
#include "absl/time/time.h"
|
||||||
#include "sandboxed_api/sandbox2/client.h"
|
#include "sandboxed_api/sandbox2/client.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/limits.h"
|
#include "sandboxed_api/sandbox2/limits.h"
|
||||||
#include "sandboxed_api/sandbox2/mounts.h"
|
#include "sandboxed_api/sandbox2/mounts.h"
|
||||||
|
@ -761,7 +762,7 @@ void Monitor::LogSyscallViolation(const Syscall& syscall) const {
|
||||||
void Monitor::EventPtraceSeccomp(pid_t pid, int event_msg) {
|
void Monitor::EventPtraceSeccomp(pid_t pid, int event_msg) {
|
||||||
// If the seccomp-policy is using RET_TRACE, we request that it returns the
|
// If the seccomp-policy is using RET_TRACE, we request that it returns the
|
||||||
// syscall architecture identifier in the SECCOMP_RET_DATA.
|
// syscall architecture identifier in the SECCOMP_RET_DATA.
|
||||||
const auto syscall_arch = static_cast<Syscall::CpuArch>(event_msg);
|
const auto syscall_arch = static_cast<cpu::Architecture>(event_msg);
|
||||||
Regs regs(pid);
|
Regs regs(pid);
|
||||||
auto status = regs.Fetch();
|
auto status = regs.Fetch();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "absl/strings/str_join.h"
|
#include "absl/strings/str_join.h"
|
||||||
#include "absl/strings/str_split.h"
|
#include "absl/strings/str_split.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/minielf.h"
|
#include "sandboxed_api/sandbox2/util/minielf.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
|
@ -132,15 +133,19 @@ std::string ResolveLibraryPath(absl::string_view lib_name,
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr absl::string_view GetPlatformCPUName() {
|
||||||
|
switch (host_cpu::Architecture()) {
|
||||||
|
case cpu::kX8664:
|
||||||
|
return "x86_64";
|
||||||
|
case cpu::kPPC64LE:
|
||||||
|
return "ppc64";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetPlatform(absl::string_view interpreter) {
|
std::string GetPlatform(absl::string_view interpreter) {
|
||||||
#if defined(__x86_64__)
|
return absl::StrCat(GetPlatformCPUName(), "-linux-gnu");
|
||||||
constexpr absl::string_view kCpuPlatform = "x86_64";
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
constexpr absl::string_view kCpuPlatform = "ppc64";
|
|
||||||
#else
|
|
||||||
constexpr absl::string_view kCpuPlatform = "unknown";
|
|
||||||
#endif
|
|
||||||
return absl::StrCat(kCpuPlatform, "-linux-gnu");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "absl/strings/numbers.h"
|
#include "absl/strings/numbers.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
|
@ -44,6 +44,7 @@ cc_library(
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//sandboxed_api/sandbox2:comms",
|
"//sandboxed_api/sandbox2:comms",
|
||||||
|
"//sandboxed_api/sandbox2:config",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
|
|
|
@ -54,6 +54,7 @@ target_link_libraries(sandbox2_network_proxy_client PRIVATE
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
glog::glog
|
glog::glog
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::status
|
sapi::status
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
|
|
||||||
|
@ -36,14 +37,13 @@ namespace sandbox2 {
|
||||||
constexpr int SYS_SECCOMP = 1;
|
constexpr int SYS_SECCOMP = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
constexpr int kRegResult = REG_RAX;
|
constexpr int kRegResult = REG_RAX;
|
||||||
constexpr int kRegSyscall = REG_RAX;
|
constexpr int kRegSyscall = REG_RAX;
|
||||||
constexpr int kRegArg0 = REG_RDI;
|
constexpr int kRegArg0 = REG_RDI;
|
||||||
constexpr int kRegArg1 = REG_RSI;
|
constexpr int kRegArg1 = REG_RSI;
|
||||||
constexpr int kRegArg2 = REG_RDX;
|
constexpr int kRegArg2 = REG_RDX;
|
||||||
#endif
|
#elif defined(SAPI_PPC64_LE)
|
||||||
#if defined(__powerpc64__)
|
|
||||||
constexpr int kRegResult = 3;
|
constexpr int kRegResult = 3;
|
||||||
constexpr int kRegSyscall = 0;
|
constexpr int kRegSyscall = 0;
|
||||||
constexpr int kRegArg0 = 3;
|
constexpr int kRegArg0 = 3;
|
||||||
|
@ -161,9 +161,9 @@ void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||||
}
|
}
|
||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
auto* registers = ctx->uc_mcontext.gregs;
|
auto* registers = ctx->uc_mcontext.gregs;
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
auto* registers = ctx->uc_mcontext.gp_regs;
|
auto* registers = ctx->uc_mcontext.gp_regs;
|
||||||
using ppc_gpreg_t = std::decay<decltype(registers[0])>::type;
|
using ppc_gpreg_t = std::decay<decltype(registers[0])>::type;
|
||||||
#endif
|
#endif
|
||||||
|
@ -178,7 +178,7 @@ void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||||
sockfd = static_cast<int>(registers[kRegArg0]);
|
sockfd = static_cast<int>(registers[kRegArg0]);
|
||||||
addr = reinterpret_cast<const struct sockaddr*>(registers[kRegArg1]);
|
addr = reinterpret_cast<const struct sockaddr*>(registers[kRegArg1]);
|
||||||
addrlen = static_cast<socklen_t>(registers[kRegArg2]);
|
addrlen = static_cast<socklen_t>(registers[kRegArg2]);
|
||||||
#if defined(__powerpc64__)
|
#if defined(SAPI_PPC64_LE)
|
||||||
} else if (syscall == __NR_socketcall &&
|
} else if (syscall == __NR_socketcall &&
|
||||||
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
||||||
ppc_gpreg_t* args = reinterpret_cast<ppc_gpreg_t*>(registers[kRegArg1]);
|
ppc_gpreg_t* args = reinterpret_cast<ppc_gpreg_t*>(registers[kRegArg1]);
|
||||||
|
|
|
@ -85,10 +85,10 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
||||||
// If compiled arch is different than the runtime one, inform the Monitor.
|
// If compiled arch is different than the runtime one, inform the Monitor.
|
||||||
LOAD_ARCH,
|
LOAD_ARCH,
|
||||||
JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)),
|
JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)),
|
||||||
JEQ32(AUDIT_ARCH_X86_64, TRACE(Syscall::kX86_64)),
|
JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)),
|
||||||
JEQ32(AUDIT_ARCH_I386, TRACE(Syscall::kX86_32)),
|
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)),
|
||||||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(Syscall::kPPC_64)),
|
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)),
|
||||||
TRACE(Syscall::kUnknown),
|
TRACE(cpu::kUnknown),
|
||||||
LABEL(&l, past_arch_check_l),
|
LABEL(&l, past_arch_check_l),
|
||||||
|
|
||||||
// After the policy is uploaded, forkserver will execve the sandboxee. We
|
// After the policy is uploaded, forkserver will execve the sandboxee. We
|
||||||
|
@ -130,10 +130,10 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
||||||
std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
||||||
return {
|
return {
|
||||||
LOAD_ARCH,
|
LOAD_ARCH,
|
||||||
JEQ32(AUDIT_ARCH_X86_64, TRACE(Syscall::kX86_64)),
|
JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)),
|
||||||
JEQ32(AUDIT_ARCH_I386, TRACE(Syscall::kX86_32)),
|
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)),
|
||||||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(Syscall::kPPC_64)),
|
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)),
|
||||||
TRACE(Syscall::kUnknown),
|
TRACE(cpu::kUnknown),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/limits.h"
|
#include "sandboxed_api/sandbox2/limits.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
@ -56,7 +57,7 @@ std::unique_ptr<Policy> PolicyTestcasePolicy() {
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#ifdef SAPI_X86_64
|
||||||
// Test that 32-bit syscalls from 64-bit are disallowed.
|
// Test that 32-bit syscalls from 64-bit are disallowed.
|
||||||
TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
||||||
SKIP_SANITIZERS_AND_COVERAGE;
|
SKIP_SANITIZERS_AND_COVERAGE;
|
||||||
|
@ -72,7 +73,7 @@ TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
||||||
|
|
||||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||||
EXPECT_THAT(result.reason_code(), Eq(1)); // __NR_exit in 32-bit
|
EXPECT_THAT(result.reason_code(), Eq(1)); // __NR_exit in 32-bit
|
||||||
EXPECT_THAT(result.GetSyscallArch(), Eq(Syscall::kX86_32));
|
EXPECT_THAT(result.GetSyscallArch(), Eq(cpu::kX86));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that 32-bit syscalls from 64-bit for FS checks are disallowed.
|
// Test that 32-bit syscalls from 64-bit for FS checks are disallowed.
|
||||||
|
@ -90,9 +91,9 @@ TEST(PolicyTest, AMD64Syscall32FsAllowed) {
|
||||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||||
EXPECT_THAT(result.reason_code(),
|
EXPECT_THAT(result.reason_code(),
|
||||||
Eq(33)); // __NR_access in 32-bit
|
Eq(33)); // __NR_access in 32-bit
|
||||||
EXPECT_THAT(result.GetSyscallArch(), Eq(Syscall::kX86_32));
|
EXPECT_THAT(result.GetSyscallArch(), Eq(cpu::kX86));
|
||||||
}
|
}
|
||||||
#endif // defined(__x86_64__)
|
#endif
|
||||||
|
|
||||||
// Test that ptrace(2) is disallowed.
|
// Test that ptrace(2) is disallowed.
|
||||||
TEST(PolicyTest, PtraceDisallowed) {
|
TEST(PolicyTest, PtraceDisallowed) {
|
||||||
|
|
|
@ -15,13 +15,6 @@
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
||||||
#include <asm/ioctls.h> // For TCGETS
|
#include <asm/ioctls.h> // For TCGETS
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
#include <asm/prctl.h>
|
|
||||||
#endif
|
|
||||||
#if defined(__powerpc64__)
|
|
||||||
#include <asm/termbits.h> // On PPC, TCGETS macro needs termios
|
|
||||||
#endif
|
|
||||||
#include <fcntl.h> // For the fcntl flags
|
#include <fcntl.h> // For the fcntl flags
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
#include <linux/net.h> // For SYS_CONNECT
|
#include <linux/net.h> // For SYS_CONNECT
|
||||||
|
@ -38,11 +31,18 @@
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/escaping.h"
|
#include "absl/strings/escaping.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/namespace.h"
|
#include "sandboxed_api/sandbox2/namespace.h"
|
||||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
|
|
||||||
|
#if defined(SAPI_X86_64)
|
||||||
|
#include <asm/prctl.h>
|
||||||
|
#elif defined(SAPI_PPC64_LE)
|
||||||
|
#include <asm/termbits.h> // On PPC, TCGETS macro needs termios
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
||||||
JEQ32(SIG_UNBLOCK, ALLOW),
|
JEQ32(SIG_UNBLOCK, ALLOW),
|
||||||
});
|
});
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#ifdef SAPI_X86_64
|
||||||
// The second argument is a pointer.
|
// The second argument is a pointer.
|
||||||
AddPolicyOnSyscall(__NR_arch_prctl, {
|
AddPolicyOnSyscall(__NR_arch_prctl, {
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
|
@ -901,7 +901,7 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyPolicy() {
|
||||||
LABEL(&labels, getsockopt_end),
|
LABEL(&labels, getsockopt_end),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_PPC64_LE
|
||||||
AddPolicyOnSyscall(__NR_socketcall, {
|
AddPolicyOnSyscall(__NR_socketcall, {
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
JEQ32(SYS_SOCKET, ALLOW),
|
JEQ32(SYS_SOCKET, ALLOW),
|
||||||
|
@ -927,7 +927,7 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyHandlerPolicy() {
|
||||||
});
|
});
|
||||||
|
|
||||||
AddPolicyOnSyscall(__NR_connect, {TRAP(0)});
|
AddPolicyOnSyscall(__NR_connect, {TRAP(0)});
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_PPC64_LE
|
||||||
AddPolicyOnSyscall(__NR_socketcall, {
|
AddPolicyOnSyscall(__NR_socketcall, {
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
JEQ32(SYS_CONNECT, TRAP(0)),
|
JEQ32(SYS_CONNECT, TRAP(0)),
|
||||||
|
|
|
@ -39,8 +39,6 @@ struct bpf_labels;
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
constexpr char kDefaultHostname[] = "sandbox2";
|
|
||||||
|
|
||||||
// PolicyBuilder is a helper class to simplify creation of policies. The builder
|
// PolicyBuilder is a helper class to simplify creation of policies. The builder
|
||||||
// uses fluent interface for convenience and increased readability of policies.
|
// uses fluent interface for convenience and increased readability of policies.
|
||||||
//
|
//
|
||||||
|
@ -91,6 +89,8 @@ constexpr char kDefaultHostname[] = "sandbox2";
|
||||||
// For a more complicated example, see examples/persistent/persistent_sandbox.cc
|
// For a more complicated example, see examples/persistent/persistent_sandbox.cc
|
||||||
class PolicyBuilder final {
|
class PolicyBuilder final {
|
||||||
public:
|
public:
|
||||||
|
static constexpr absl::string_view kDefaultHostname = "sandbox2";
|
||||||
|
|
||||||
using BpfInitializer = std::initializer_list<sock_filter>;
|
using BpfInitializer = std::initializer_list<sock_filter>;
|
||||||
using BpfFunc = const std::function<std::vector<sock_filter>(bpf_labels&)>&;
|
using BpfFunc = const std::function<std::vector<sock_filter>(bpf_labels&)>&;
|
||||||
using SyscallInitializer = std::initializer_list<unsigned int>;
|
using SyscallInitializer = std::initializer_list<unsigned int>;
|
||||||
|
@ -542,7 +542,7 @@ class PolicyBuilder final {
|
||||||
bool use_namespaces_ = true;
|
bool use_namespaces_ = true;
|
||||||
bool requires_namespaces_ = false;
|
bool requires_namespaces_ = false;
|
||||||
bool allow_unrestricted_networking_ = false;
|
bool allow_unrestricted_networking_ = false;
|
||||||
std::string hostname_ = kDefaultHostname;
|
std::string hostname_ = std::string(kDefaultHostname);
|
||||||
|
|
||||||
bool collect_stacktrace_on_violation_ = true;
|
bool collect_stacktrace_on_violation_ = true;
|
||||||
bool collect_stacktrace_on_signal_ = true;
|
bool collect_stacktrace_on_signal_ = true;
|
||||||
|
|
|
@ -24,17 +24,25 @@
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
absl::Status Regs::Fetch() {
|
absl::Status Regs::Fetch() {
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_X86_64
|
||||||
|
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
|
||||||
|
return absl::InternalError(absl::StrCat("ptrace(PTRACE_GETREGS, pid=", pid_,
|
||||||
|
") failed: ", StrError(errno)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if constexpr (host_cpu::IsPPC64LE()) {
|
||||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||||
|
|
||||||
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||||
return absl::InternalError(absl::StrCat(
|
return absl::InternalError(
|
||||||
"ptrace(PTRACE_GETREGSET, pid=", pid_, ") failed: ", StrError(errno)));
|
absl::StrCat("ptrace(PTRACE_GETREGSET, pid=", pid_,
|
||||||
|
") failed: ", StrError(errno)));
|
||||||
}
|
}
|
||||||
if (pt_iov.iov_len != sizeof(user_regs_)) {
|
if (pt_iov.iov_len != sizeof(user_regs_)) {
|
||||||
return absl::InternalError(absl::StrCat(
|
return absl::InternalError(absl::StrCat(
|
||||||
|
@ -42,46 +50,43 @@ absl::Status Regs::Fetch() {
|
||||||
") size returned: ", pt_iov.iov_len,
|
") size returned: ", pt_iov.iov_len,
|
||||||
" different than sizeof(user_regs_): ", sizeof(user_regs_)));
|
" different than sizeof(user_regs_): ", sizeof(user_regs_)));
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
|
|
||||||
return absl::InternalError(absl::StrCat("ptrace(PTRACE_GETREGS, pid=", pid_,
|
|
||||||
") failed: ", StrError(errno)));
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Regs::Store() {
|
absl::Status Regs::Store() {
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_X86_64
|
||||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
|
||||||
|
|
||||||
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
|
||||||
return absl::InternalError(absl::StrCat(
|
|
||||||
"ptrace(PTRACE_SETREGSET, pid=", pid_, ") failed: ", StrError(errno)));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (ptrace(PTRACE_SETREGS, pid_, 0, &user_regs_) == -1) {
|
if (ptrace(PTRACE_SETREGS, pid_, 0, &user_regs_) == -1) {
|
||||||
return absl::InternalError(absl::StrCat("ptrace(PTRACE_SETREGS, pid=", pid_,
|
return absl::InternalError(absl::StrCat("ptrace(PTRACE_SETREGS, pid=", pid_,
|
||||||
") failed: ", StrError(errno)));
|
") failed: ", StrError(errno)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if constexpr (host_cpu::IsPPC64LE()) {
|
||||||
|
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("ptrace(PTRACE_SETREGSET, pid=", pid_,
|
||||||
|
") failed: ", StrError(errno)));
|
||||||
|
}
|
||||||
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
user_regs_.orig_rax = -1;
|
user_regs_.orig_rax = -1;
|
||||||
user_regs_.rax = value;
|
user_regs_.rax = value;
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
user_regs_.gpr[0] = -1;
|
user_regs_.gpr[0] = -1;
|
||||||
user_regs_.gpr[3] = value;
|
user_regs_.gpr[3] = value;
|
||||||
#endif
|
#endif
|
||||||
return Store();
|
return Store();
|
||||||
}
|
}
|
||||||
|
|
||||||
Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
Syscall Regs::ToSyscall(cpu::Architecture syscall_arch) const {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
if (ABSL_PREDICT_TRUE(syscall_arch == Syscall::kX86_64)) {
|
if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kX8664)) {
|
||||||
auto syscall = user_regs_.orig_rax;
|
auto syscall = user_regs_.orig_rax;
|
||||||
Syscall::Args args = {user_regs_.rdi, user_regs_.rsi, user_regs_.rdx,
|
Syscall::Args args = {user_regs_.rdi, user_regs_.rsi, user_regs_.rdx,
|
||||||
user_regs_.r10, user_regs_.r8, user_regs_.r9};
|
user_regs_.r10, user_regs_.r8, user_regs_.r9};
|
||||||
|
@ -89,7 +94,7 @@ Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
||||||
auto ip = user_regs_.rip;
|
auto ip = user_regs_.rip;
|
||||||
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
||||||
}
|
}
|
||||||
if (syscall_arch == Syscall::kX86_32) {
|
if (syscall_arch == cpu::kX86) {
|
||||||
auto syscall = user_regs_.orig_rax & 0xFFFFFFFF;
|
auto syscall = user_regs_.orig_rax & 0xFFFFFFFF;
|
||||||
Syscall::Args args = {
|
Syscall::Args args = {
|
||||||
user_regs_.rbx & 0xFFFFFFFF, user_regs_.rcx & 0xFFFFFFFF,
|
user_regs_.rbx & 0xFFFFFFFF, user_regs_.rcx & 0xFFFFFFFF,
|
||||||
|
@ -99,8 +104,8 @@ Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
||||||
auto ip = user_regs_.rip & 0xFFFFFFFF;
|
auto ip = user_regs_.rip & 0xFFFFFFFF;
|
||||||
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
||||||
}
|
}
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
if (ABSL_PREDICT_TRUE(syscall_arch == Syscall::kPPC_64)) {
|
if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kPPC64LE)) {
|
||||||
auto syscall = user_regs_.gpr[0];
|
auto syscall = user_regs_.gpr[0];
|
||||||
Syscall::Args args = {user_regs_.orig_gpr3, user_regs_.gpr[4],
|
Syscall::Args args = {user_regs_.orig_gpr3, user_regs_.gpr[4],
|
||||||
user_regs_.gpr[5], user_regs_.gpr[6],
|
user_regs_.gpr[5], user_regs_.gpr[6],
|
||||||
|
@ -114,7 +119,7 @@ Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
RegisterX8664* regs = values->mutable_register_x86_64();
|
RegisterX8664* regs = values->mutable_register_x86_64();
|
||||||
regs->set_r15(user_regs_.r15);
|
regs->set_r15(user_regs_.r15);
|
||||||
regs->set_r14(user_regs_.r14);
|
regs->set_r14(user_regs_.r14);
|
||||||
|
@ -143,7 +148,7 @@ void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
||||||
regs->set_es(user_regs_.es);
|
regs->set_es(user_regs_.es);
|
||||||
regs->set_fs(user_regs_.fs);
|
regs->set_fs(user_regs_.fs);
|
||||||
regs->set_gs(user_regs_.gs);
|
regs->set_gs(user_regs_.gs);
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
RegisterPowerpc64* regs = values->mutable_register_powerpc64();
|
RegisterPowerpc64* regs = values->mutable_register_powerpc64();
|
||||||
for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.gpr); ++i) {
|
for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.gpr); ++i) {
|
||||||
regs->add_gpr(user_regs_.gpr[i]);
|
regs->add_gpr(user_regs_.gpr[i]);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
#include "sandboxed_api/sandbox2/violation.pb.h"
|
#include "sandboxed_api/sandbox2/violation.pb.h"
|
||||||
|
|
||||||
|
@ -33,10 +34,6 @@ namespace sandbox2 {
|
||||||
// assumes the process is already attached.
|
// assumes the process is already attached.
|
||||||
class Regs {
|
class Regs {
|
||||||
public:
|
public:
|
||||||
#if !defined(__x86_64__) && !defined(__powerpc64__)
|
|
||||||
static_assert(false, "No support for the current CPU architecture");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
explicit Regs(pid_t pid) : pid_(pid) {}
|
explicit Regs(pid_t pid) : pid_(pid) {}
|
||||||
|
|
||||||
// Copies register values from the process
|
// Copies register values from the process
|
||||||
|
@ -49,7 +46,7 @@ class Regs {
|
||||||
absl::Status SkipSyscallReturnValue(uint64_t value);
|
absl::Status SkipSyscallReturnValue(uint64_t value);
|
||||||
|
|
||||||
// Converts raw register values obtained on syscall entry to syscall info
|
// Converts raw register values obtained on syscall entry to syscall info
|
||||||
Syscall ToSyscall(Syscall::CpuArch syscall_arch) const;
|
Syscall ToSyscall(cpu::Architecture syscall_arch) const;
|
||||||
|
|
||||||
pid_t pid() const { return pid_; }
|
pid_t pid() const { return pid_; }
|
||||||
|
|
||||||
|
@ -60,7 +57,7 @@ class Regs {
|
||||||
friend class StackTracePeer;
|
friend class StackTracePeer;
|
||||||
|
|
||||||
struct PtraceRegisters {
|
struct PtraceRegisters {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
uint64_t r15;
|
uint64_t r15;
|
||||||
uint64_t r14;
|
uint64_t r14;
|
||||||
uint64_t r13;
|
uint64_t r13;
|
||||||
|
@ -88,7 +85,7 @@ class Regs {
|
||||||
uint64_t es;
|
uint64_t es;
|
||||||
uint64_t fs;
|
uint64_t fs;
|
||||||
uint64_t gs;
|
uint64_t gs;
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
uint64_t gpr[32];
|
uint64_t gpr[32];
|
||||||
uint64_t nip;
|
uint64_t nip;
|
||||||
uint64_t msr;
|
uint64_t msr;
|
||||||
|
@ -108,6 +105,8 @@ class Regs {
|
||||||
uint64_t zero1;
|
uint64_t zero1;
|
||||||
uint64_t zero2;
|
uint64_t zero2;
|
||||||
uint64_t zero3;
|
uint64_t zero3;
|
||||||
|
#else
|
||||||
|
static_assert(false, "Host CPU architecture not supported, see config.h");
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/regs.h"
|
#include "sandboxed_api/sandbox2/regs.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
|
|
||||||
|
@ -131,8 +132,8 @@ class Result {
|
||||||
// Returns the current syscall architecture.
|
// Returns the current syscall architecture.
|
||||||
// Client architecture when final_status_ == VIOLATION, might be different
|
// Client architecture when final_status_ == VIOLATION, might be different
|
||||||
// from the host architecture (32-bit vs 64-bit syscalls).
|
// from the host architecture (32-bit vs 64-bit syscalls).
|
||||||
Syscall::CpuArch GetSyscallArch() const {
|
cpu::Architecture GetSyscallArch() const {
|
||||||
return syscall_ ? syscall_->arch() : Syscall::kUnknown;
|
return syscall_ ? syscall_->arch() : cpu::kUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> stack_trace() { return stack_trace_; }
|
const std::vector<std::string> stack_trace() { return stack_trace_; }
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
|
@ -12,12 +12,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// Implementation of the sandbox2::Syscall class.
|
|
||||||
|
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
|
|
||||||
#include <linux/audit.h>
|
#include <linux/audit.h>
|
||||||
#include <linux/elf-em.h>
|
#include <linux/elf-em.h>
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/strings/str_join.h"
|
#include "absl/strings/str_join.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall_defs.h"
|
#include "sandboxed_api/sandbox2/syscall_defs.h"
|
||||||
|
|
||||||
#ifndef AUDIT_ARCH_PPC64LE
|
#ifndef AUDIT_ARCH_PPC64LE
|
||||||
|
@ -34,13 +34,13 @@
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
std::string Syscall::GetArchDescription(CpuArch arch) {
|
std::string Syscall::GetArchDescription(cpu::Architecture arch) {
|
||||||
switch (arch) {
|
switch (arch) {
|
||||||
case kX86_64:
|
case cpu::kX8664:
|
||||||
return "[X86-64]";
|
return "[X86-64]";
|
||||||
case kX86_32:
|
case cpu::kX86:
|
||||||
return "[X86-32]";
|
return "[X86-32]";
|
||||||
case kPPC_64:
|
case cpu::kPPC64LE:
|
||||||
return "[PPC-64]";
|
return "[PPC-64]";
|
||||||
default:
|
default:
|
||||||
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
||||||
|
@ -48,32 +48,25 @@ std::string Syscall::GetArchDescription(CpuArch arch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Syscall::CpuArch Syscall::GetHostArch() {
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
return kX86_64;
|
|
||||||
#elif defined(__i386__)
|
|
||||||
return kX86_32;
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
return kPPC_64;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Syscall::GetHostAuditArch() {
|
uint32_t Syscall::GetHostAuditArch() {
|
||||||
#if defined(__x86_64__)
|
switch (host_cpu::Architecture()) {
|
||||||
|
case cpu::kX8664:
|
||||||
return AUDIT_ARCH_X86_64;
|
return AUDIT_ARCH_X86_64;
|
||||||
#elif defined(__i386__)
|
case cpu::kPPC64LE:
|
||||||
return AUDIT_ARCH_I386;
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
return AUDIT_ARCH_PPC64LE;
|
return AUDIT_ARCH_PPC64LE;
|
||||||
#endif
|
default:
|
||||||
|
// The static_assert() in config.h should prevent us from ever getting
|
||||||
|
// here.
|
||||||
|
return 0; // Not reached
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Syscall::GetName() const {
|
std::string Syscall::GetName() const {
|
||||||
absl::string_view name = SyscallTable::get(arch_).GetName(nr_);
|
if (absl::string_view name = SyscallTable::get(arch_).GetName(nr_);
|
||||||
if (name.empty()) {
|
!name.empty()) {
|
||||||
return absl::StrFormat("UNKNOWN[%d/0x%x]", nr_, nr_);
|
|
||||||
}
|
|
||||||
return std::string(name);
|
return std::string(name);
|
||||||
|
}
|
||||||
|
return absl::StrFormat("UNKNOWN[%d/0x%x]", nr_, nr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> Syscall::GetArgumentsDescription() const {
|
std::vector<std::string> Syscall::GetArgumentsDescription() const {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// The sandbox2::Syscalls class defines mostly static helper methods which
|
// The sandbox2::Syscalls class defines mostly static helper methods which
|
||||||
// are used to analyze status of the ptraced process
|
// are used to analyze the status of the sandboxed process.
|
||||||
|
|
||||||
#ifndef SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
#ifndef SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
||||||
#define SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
#define SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
||||||
|
@ -26,40 +26,34 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
class Syscall {
|
class Syscall {
|
||||||
public:
|
public:
|
||||||
// Supported CPU architectures.
|
|
||||||
// Linux: Use a magic value, so it can be easily spotted in the seccomp-bpf
|
|
||||||
// bytecode decompilation stream. Must be < (1<<15), as/ that's the size of
|
|
||||||
// data which can be returned by BPF.
|
|
||||||
enum CpuArch {
|
|
||||||
kUnknown = 0xCAF0,
|
|
||||||
kX86_64,
|
|
||||||
kX86_32,
|
|
||||||
kPPC_64,
|
|
||||||
};
|
|
||||||
// Maximum number of syscall arguments
|
// Maximum number of syscall arguments
|
||||||
static constexpr size_t kMaxArgs = 6;
|
static constexpr size_t kMaxArgs = 6;
|
||||||
using Args = std::array<uint64_t, kMaxArgs>;
|
using Args = std::array<uint64_t, kMaxArgs>;
|
||||||
|
|
||||||
// Returns the host architecture, according to CpuArch.
|
// Returns the host architecture, according to CpuArch.
|
||||||
static CpuArch GetHostArch();
|
static constexpr cpu::Architecture GetHostArch() {
|
||||||
|
return host_cpu::Architecture();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the host architecture, according to <linux/audit.h>.
|
// Returns the host architecture, according to <linux/audit.h>.
|
||||||
static uint32_t GetHostAuditArch();
|
static uint32_t GetHostAuditArch();
|
||||||
|
|
||||||
// Returns a description of the architecture.
|
// Returns a description of the architecture.
|
||||||
static std::string GetArchDescription(CpuArch arch);
|
static std::string GetArchDescription(cpu::Architecture arch);
|
||||||
|
|
||||||
Syscall() = default;
|
Syscall() = default;
|
||||||
Syscall(CpuArch arch, uint64_t nr, Args args = {})
|
Syscall(cpu::Architecture arch, uint64_t nr, Args args = {})
|
||||||
: arch_(arch), nr_(nr), args_(args) {}
|
: arch_(arch), nr_(nr), args_(args) {}
|
||||||
|
|
||||||
pid_t pid() const { return pid_; }
|
pid_t pid() const { return pid_; }
|
||||||
uint64_t nr() const { return nr_; }
|
uint64_t nr() const { return nr_; }
|
||||||
CpuArch arch() const { return arch_; }
|
cpu::Architecture arch() const { return arch_; }
|
||||||
const Args& args() const { return args_; }
|
const Args& args() const { return args_; }
|
||||||
uint64_t stack_pointer() const { return sp_; }
|
uint64_t stack_pointer() const { return sp_; }
|
||||||
uint64_t instruction_pointer() const { return ip_; }
|
uint64_t instruction_pointer() const { return ip_; }
|
||||||
|
@ -72,12 +66,12 @@ class Syscall {
|
||||||
private:
|
private:
|
||||||
friend class Regs;
|
friend class Regs;
|
||||||
|
|
||||||
Syscall(pid_t pid) : pid_(pid) {}
|
explicit Syscall(pid_t pid) : pid_(pid) {}
|
||||||
Syscall(CpuArch arch, uint64_t nr, Args args, pid_t pid, uint64_t sp,
|
Syscall(cpu::Architecture arch, uint64_t nr, Args args, pid_t pid,
|
||||||
uint64_t ip)
|
uint64_t sp, uint64_t ip)
|
||||||
: arch_(arch), nr_(nr), args_(args), pid_(pid), sp_(sp), ip_(ip) {}
|
: arch_(arch), nr_(nr), args_(args), pid_(pid), sp_(sp), ip_(ip) {}
|
||||||
|
|
||||||
CpuArch arch_ = kUnknown;
|
cpu::Architecture arch_ = cpu::kUnknown;
|
||||||
uint64_t nr_ = -1;
|
uint64_t nr_ = -1;
|
||||||
Args args_ = {};
|
Args args_ = {};
|
||||||
pid_t pid_ = -1;
|
pid_t pid_ = -1;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "absl/strings/escaping.h"
|
#include "absl/strings/escaping.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util.h"
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
@ -128,7 +129,6 @@ std::vector<std::string> SyscallTable::GetArgumentsDescription(
|
||||||
#define SYSCALLS_UNUSED00_99(prefix) \
|
#define SYSCALLS_UNUSED00_99(prefix) \
|
||||||
SYSCALLS_UNUSED00_49(prefix), SYSCALLS_UNUSED50_99(prefix)
|
SYSCALLS_UNUSED00_49(prefix), SYSCALLS_UNUSED50_99(prefix)
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
// Syscall description table for Linux x86_64
|
// Syscall description table for Linux x86_64
|
||||||
constexpr SyscallTable::Entry kSyscallDataX8664[] = {
|
constexpr SyscallTable::Entry kSyscallDataX8664[] = {
|
||||||
MakeEntry("read", kInt, kHex, kInt), // 0
|
MakeEntry("read", kInt, kHex, kInt), // 0
|
||||||
|
@ -824,12 +824,10 @@ constexpr SyscallTable::Entry kSyscallDataX8632[] = {
|
||||||
MakeEntry("bpf", kHex, kHex, kHex, kHex, kHex, kHex), // 357
|
MakeEntry("bpf", kHex, kHex, kHex, kHex, kHex, kHex), // 357
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
|
|
||||||
// http://lxr.free-electrons.com/source/arch/powerpc/include/uapi/asm/unistd.h
|
// http://lxr.free-electrons.com/source/arch/powerpc/include/uapi/asm/unistd.h
|
||||||
// Note: PPC64 syscalls can have up to 7 register arguments, but nobody is
|
// Note: PPC64 syscalls can have up to 7 register arguments, but nobody is
|
||||||
// using the 7th argument - probably for x64 compatibility reasons.
|
// using the 7th argument - probably for x64 compatibility reasons.
|
||||||
constexpr SyscallTable::Entry kSyscallDataPPC64[] = {
|
constexpr SyscallTable::Entry kSyscallDataPPC64LE[] = {
|
||||||
MakeEntry("restart_syscall", kGen, kGen, kGen, kGen, kGen, kGen), // 0
|
MakeEntry("restart_syscall", kGen, kGen, kGen, kGen, kGen, kGen), // 0
|
||||||
MakeEntry("exit", kInt, kGen, kGen, kGen, kGen, kGen), // 1
|
MakeEntry("exit", kInt, kGen, kGen, kGen, kGen, kGen), // 1
|
||||||
MakeEntry("fork", kGen, kGen, kGen, kGen, kGen, kGen), // 2
|
MakeEntry("fork", kGen, kGen, kGen, kGen, kGen, kGen), // 2
|
||||||
|
@ -1218,25 +1216,20 @@ constexpr SyscallTable::Entry kSyscallDataPPC64[] = {
|
||||||
MakeEntry("pwritev2", kHex, kHex, kHex, kHex, kHex, kHex), // 381
|
MakeEntry("pwritev2", kHex, kHex, kHex, kHex, kHex, kHex), // 381
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef SYSCALLS_UNUSED00_99
|
#undef SYSCALLS_UNUSED00_99
|
||||||
#undef SYSCALLS_UNUSED50_99
|
#undef SYSCALLS_UNUSED50_99
|
||||||
#undef SYSCALLS_UNUSED00_49
|
#undef SYSCALLS_UNUSED00_49
|
||||||
#undef SYSCALLS_UNUSED0_9
|
#undef SYSCALLS_UNUSED0_9
|
||||||
#undef SYSCALLS_UNUSED
|
#undef SYSCALLS_UNUSED
|
||||||
|
|
||||||
SyscallTable SyscallTable::get(Syscall::CpuArch arch) {
|
SyscallTable SyscallTable::get(cpu::Architecture arch) {
|
||||||
switch (arch) {
|
switch (host_cpu::Architecture()) {
|
||||||
#if defined(__x86_64__)
|
case cpu::kX8664:
|
||||||
case Syscall::kX86_64:
|
|
||||||
return SyscallTable(kSyscallDataX8664);
|
return SyscallTable(kSyscallDataX8664);
|
||||||
case Syscall::kX86_32:
|
case cpu::kX86:
|
||||||
return SyscallTable(kSyscallDataX8632);
|
return SyscallTable(kSyscallDataX8632);
|
||||||
#elif defined(__powerpc64__)
|
case cpu::kPPC64LE:
|
||||||
case Syscall::kPPC_64:
|
return SyscallTable(kSyscallDataPPC64LE);
|
||||||
return SyscallTable(kSyscallDataPPC64);
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return SyscallTable();
|
return SyscallTable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/types/span.h"
|
#include "absl/types/span.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
@ -23,7 +24,7 @@ class SyscallTable {
|
||||||
struct Entry;
|
struct Entry;
|
||||||
|
|
||||||
// Returns the syscall table for the architecture.
|
// Returns the syscall table for the architecture.
|
||||||
static SyscallTable get(Syscall::CpuArch arch);
|
static SyscallTable get(cpu::Architecture arch);
|
||||||
|
|
||||||
int size() { return data_.size(); }
|
int size() { return data_.size(); }
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
|
|
||||||
using ::testing::Eq;
|
using ::testing::Eq;
|
||||||
using ::testing::StartsWith;
|
using ::testing::StartsWith;
|
||||||
|
@ -45,7 +46,7 @@ TEST(SyscallTest, Basic) {
|
||||||
EXPECT_THAT(arg_desc[2], Eq("0x5 [5]"));
|
EXPECT_THAT(arg_desc[2], Eq("0x5 [5]"));
|
||||||
EXPECT_THAT(
|
EXPECT_THAT(
|
||||||
syscall.GetDescription(),
|
syscall.GetDescription(),
|
||||||
Eq(absl::StrCat(Syscall::GetArchDescription(Syscall::GetHostArch()),
|
Eq(absl::StrCat(Syscall::GetArchDescription(host_cpu::Architecture()),
|
||||||
" read [", __NR_read,
|
" read [", __NR_read,
|
||||||
"](0x1 [1], 0xbadbeef, 0x5 [5]) IP: 0, STACK: 0")));
|
"](0x1 [1], 0xbadbeef, 0x5 [5]) IP: 0, STACK: 0")));
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ TEST(SyscallTest, Basic) {
|
||||||
TEST(SyscallTest, Empty) {
|
TEST(SyscallTest, Empty) {
|
||||||
Syscall syscall;
|
Syscall syscall;
|
||||||
|
|
||||||
EXPECT_THAT(syscall.arch(), Eq(Syscall::kUnknown));
|
EXPECT_THAT(syscall.arch(), Eq(cpu::kUnknown));
|
||||||
EXPECT_THAT(syscall.GetName(), StartsWith("UNKNOWN"));
|
EXPECT_THAT(syscall.GetName(), StartsWith("UNKNOWN"));
|
||||||
EXPECT_THAT(syscall.GetArgumentsDescription().size(), Eq(Syscall::kMaxArgs));
|
EXPECT_THAT(syscall.GetArgumentsDescription().size(), Eq(Syscall::kMaxArgs));
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,7 @@ cc_binary(
|
||||||
"fully_static_link", # link libc statically
|
"fully_static_link", # link libc statically
|
||||||
],
|
],
|
||||||
linkstatic = 1, # prefer static libraries
|
linkstatic = 1, # prefer static libraries
|
||||||
|
deps = ["//sandboxed_api/sandbox2:config"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# security: disable=cc-static-no-pie
|
# security: disable=cc-static-no-pie
|
||||||
|
|
|
@ -159,6 +159,7 @@ set_target_properties(policy PROPERTIES
|
||||||
)
|
)
|
||||||
target_link_libraries(policy PRIVATE
|
target_link_libraries(policy PRIVATE
|
||||||
sapi::base
|
sapi::base
|
||||||
|
sandbox2::config
|
||||||
${_sandbox2_fully_static_linkopts}
|
${_sandbox2_fully_static_linkopts}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
|
|
||||||
|
#ifdef SAPI_X86_64
|
||||||
void TestAMD64SyscallMismatch() {
|
void TestAMD64SyscallMismatch() {
|
||||||
int64_t result;
|
int64_t result;
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ void TestAMD64SyscallMismatchFs() {
|
||||||
: "rax", "rbx", "rcx");
|
: "rax", "rbx", "rcx");
|
||||||
exit(-result);
|
exit(-result);
|
||||||
}
|
}
|
||||||
#endif // defined(__x86_64__)
|
#endif
|
||||||
|
|
||||||
void TestPtrace() {
|
void TestPtrace() {
|
||||||
ptrace(PTRACE_SEIZE, getppid(), 0, 0);
|
ptrace(PTRACE_SEIZE, getppid(), 0, 0);
|
||||||
|
@ -97,14 +99,14 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
int testno = atoi(argv[1]); // NOLINT
|
int testno = atoi(argv[1]); // NOLINT
|
||||||
switch (testno) {
|
switch (testno) {
|
||||||
#if defined(__x86_64__)
|
#ifdef SAPI_X86_64
|
||||||
case 1:
|
case 1:
|
||||||
TestAMD64SyscallMismatch();
|
TestAMD64SyscallMismatch();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
TestAMD64SyscallMismatchFs();
|
TestAMD64SyscallMismatchFs();
|
||||||
break;
|
break;
|
||||||
#endif // defined(__x86_64__)
|
#endif
|
||||||
case 3:
|
case 3:
|
||||||
TestPtrace();
|
TestPtrace();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,13 +39,13 @@
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/strings/strip.h"
|
#include "absl/strings/strip.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2::util {
|
||||||
namespace util {
|
|
||||||
|
|
||||||
void CharPtrArrToVecString(char* const* arr, std::vector<std::string>* vec) {
|
void CharPtrArrToVecString(char* const* arr, std::vector<std::string>* vec) {
|
||||||
for (int i = 0; arr[i]; ++i) {
|
for (int i = 0; arr[i]; ++i) {
|
||||||
|
@ -126,13 +126,10 @@ ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
|
||||||
ABSL_ATTRIBUTE_NOINLINE
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
pid_t CloneAndJump(int flags, jmp_buf* env_ptr) {
|
pid_t CloneAndJump(int flags, jmp_buf* env_ptr) {
|
||||||
uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED;
|
uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED;
|
||||||
#if defined(__x86_64__) || defined(__x86__) || defined(__i386__) || \
|
static_assert(host_cpu::IsX8664() || host_cpu::IsPPC64LE(),
|
||||||
defined(__powerpc64__)
|
"Host CPU architecture not supported, see config.h");
|
||||||
// Stack grows down.
|
// Stack grows down.
|
||||||
void* stack = stack_buf + sizeof(stack_buf);
|
void* stack = stack_buf + sizeof(stack_buf);
|
||||||
#else
|
|
||||||
#error "Architecture is not supported"
|
|
||||||
#endif
|
|
||||||
int r;
|
int r;
|
||||||
{
|
{
|
||||||
r = clone(&ChildFunc, stack, flags, env_ptr, nullptr, nullptr, nullptr);
|
r = clone(&ChildFunc, stack, flags, env_ptr, nullptr, nullptr, nullptr);
|
||||||
|
@ -321,5 +318,4 @@ absl::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace sandbox2::util
|
||||||
} // namespace sandbox2
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user