aboutsummaryrefslogtreecommitdiff
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/commands/process_sandboxer/Android.bp25
-rw-r--r--host/commands/process_sandboxer/main.cpp10
-rw-r--r--host/commands/process_sandboxer/policies.cpp5
-rw-r--r--host/commands/process_sandboxer/policies.h5
-rw-r--r--host/commands/process_sandboxer/policies/baseline.cpp41
-rw-r--r--host/commands/process_sandboxer/policies/kernel_log_monitor.cpp18
-rw-r--r--host/commands/process_sandboxer/policies/logcat_receiver.cpp16
-rw-r--r--host/commands/process_sandboxer/policies/process_sandboxer_test_hello_world.cpp33
-rw-r--r--host/commands/process_sandboxer/process_sandboxer_test.cpp70
-rw-r--r--host/commands/process_sandboxer/test_executables/Android.bp25
-rw-r--r--host/commands/process_sandboxer/test_executables/process_sandboxer_test_hello_world.cpp13
11 files changed, 229 insertions, 32 deletions
diff --git a/host/commands/process_sandboxer/Android.bp b/host/commands/process_sandboxer/Android.bp
index a685a7194..d56459ed2 100644
--- a/host/commands/process_sandboxer/Android.bp
+++ b/host/commands/process_sandboxer/Android.bp
@@ -26,8 +26,10 @@ cc_binary_host {
srcs: [
"main.cpp",
"policies.cpp",
+ "policies/baseline.cpp",
"policies/kernel_log_monitor.cpp",
"policies/logcat_receiver.cpp",
+ "policies/process_sandboxer_test_hello_world.cpp",
],
shared_libs: ["sandboxed_api_sandbox2"],
static_libs: [
@@ -43,3 +45,26 @@ cc_binary_host {
},
},
}
+
+cc_test_host {
+ name: "process_sandboxer_test",
+ defaults: ["cuttlefish_buildhost_only"],
+ srcs: ["process_sandboxer_test.cpp"],
+ // When running `atest --host process_sandboxer_test`, these are only
+ // refreshed after running `m installclean`.
+ data_bins: [
+ "process_sandboxer",
+ "process_sandboxer_test_hello_world",
+ ],
+ static_libs: [
+ "libbase",
+ "libcuttlefish_fs",
+ "libcuttlefish_utils",
+ "liblog",
+ ],
+ team: "trendy_team_cloud_android",
+ // TODO(schuffelen): See if this is possible to enable on CI
+ test_options: {
+ unit_test: false,
+ },
+}
diff --git a/host/commands/process_sandboxer/main.cpp b/host/commands/process_sandboxer/main.cpp
index 2ddcfb5f3..78e68d8e0 100644
--- a/host/commands/process_sandboxer/main.cpp
+++ b/host/commands/process_sandboxer/main.cpp
@@ -17,7 +17,9 @@
#include <stdlib.h>
#include <memory>
+#include <optional>
#include <string>
+#include <string_view>
#include <vector>
#include "absl/flags/flag.h"
@@ -46,13 +48,19 @@ using sapi::file::JoinPath;
namespace cuttlefish {
+static std::optional<std::string_view> FromEnv(const std::string& name) {
+ auto value = getenv(name.c_str());
+ return value == NULL ? std::optional<std::string_view>() : value;
+}
+
int ProcessSandboxerMain(int argc, char** argv) {
absl::InitializeLog();
auto args = absl::ParseCommandLine(argc, argv);
HostInfo host;
host.artifacts_path = CleanPath(absl::GetFlag(FLAGS_host_artifacts_path));
- host.cuttlefish_config_path = CleanPath(getenv(kCuttlefishConfigEnvVarName));
+ host.cuttlefish_config_path =
+ CleanPath(FromEnv(kCuttlefishConfigEnvVarName).value_or(""));
host.log_dir = CleanPath(absl::GetFlag(FLAGS_log_dir));
setenv("LD_LIBRARY_PATH", JoinPath(host.artifacts_path, "lib64").c_str(), 1);
diff --git a/host/commands/process_sandboxer/policies.cpp b/host/commands/process_sandboxer/policies.cpp
index f9777e8c3..e2339967f 100644
--- a/host/commands/process_sandboxer/policies.cpp
+++ b/host/commands/process_sandboxer/policies.cpp
@@ -37,6 +37,11 @@ std::unique_ptr<sandbox2::Policy> PolicyForExecutable(
builders[JoinPath(host.artifacts_path, "bin", "logcat_receiver")] =
LogcatReceiverPolicy;
+ // TODO(schuffelen): Don't include test policies in the production impl
+ builders[JoinPath(host.artifacts_path, "testcases", "process_sandboxer_test",
+ "x86_64", "process_sandboxer_test_hello_world")] =
+ HelloWorldPolicy;
+
if (auto it = builders.find(executable); it != builders.end()) {
return (it->second)(host).BuildOrDie();
} else {
diff --git a/host/commands/process_sandboxer/policies.h b/host/commands/process_sandboxer/policies.h
index 0f38b2a50..aa0ffc9dc 100644
--- a/host/commands/process_sandboxer/policies.h
+++ b/host/commands/process_sandboxer/policies.h
@@ -29,9 +29,14 @@ struct HostInfo {
std::string log_dir;
};
+sandbox2::PolicyBuilder BaselinePolicy(const HostInfo&, std::string_view exe);
+
sandbox2::PolicyBuilder KernelLogMonitorPolicy(const HostInfo&);
sandbox2::PolicyBuilder LogcatReceiverPolicy(const HostInfo&);
+// Testing policies
+sandbox2::PolicyBuilder HelloWorldPolicy(const HostInfo&);
+
std::unique_ptr<sandbox2::Policy> PolicyForExecutable(
const HostInfo& host_info, std::string_view executable_path);
diff --git a/host/commands/process_sandboxer/policies/baseline.cpp b/host/commands/process_sandboxer/policies/baseline.cpp
new file mode 100644
index 000000000..732fe3351
--- /dev/null
+++ b/host/commands/process_sandboxer/policies/baseline.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "host/commands/process_sandboxer/policies.h"
+
+#include "sandboxed_api/sandbox2/policybuilder.h"
+#include "sandboxed_api/util/path.h"
+
+using sapi::file::JoinPath;
+
+namespace cuttlefish {
+
+sandbox2::PolicyBuilder BaselinePolicy(const HostInfo& host,
+ std::string_view exe) {
+ return sandbox2::PolicyBuilder()
+ .AddLibrariesForBinary(exe, JoinPath(host.artifacts_path, "lib64"))
+ // For dynamic linking and memory allocation
+ .AllowDynamicStartup()
+ .AllowExit()
+ .AllowGetPIDs()
+ .AllowGetRandom()
+ .AllowMmap()
+ .AllowReadlink()
+ .AllowRestartableSequences(sandbox2::PolicyBuilder::kAllowSlowFences)
+ .AllowWrite();
+}
+
+} // namespace cuttlefish
diff --git a/host/commands/process_sandboxer/policies/kernel_log_monitor.cpp b/host/commands/process_sandboxer/policies/kernel_log_monitor.cpp
index 97b1611d4..fe9ceddac 100644
--- a/host/commands/process_sandboxer/policies/kernel_log_monitor.cpp
+++ b/host/commands/process_sandboxer/policies/kernel_log_monitor.cpp
@@ -28,29 +28,15 @@ namespace cuttlefish {
sandbox2::PolicyBuilder KernelLogMonitorPolicy(const HostInfo& host) {
auto exe = JoinPath(host.artifacts_path, "bin", "kernel_log_monitor");
- auto lib64 = JoinPath(host.artifacts_path, "lib64");
- return sandbox2::PolicyBuilder()
- .AddDirectory(lib64)
+ return BaselinePolicy(host, exe)
.AddDirectory(host.log_dir, /* is_ro= */ false)
.AddFile(host.cuttlefish_config_path)
- .AddLibrariesForBinary(exe, lib64)
- // For dynamic linking
- .AddPolicyOnSyscall(__NR_prctl,
- {ARG_32(0), JEQ32(PR_CAPBSET_READ, ALLOW)})
- .AllowDynamicStartup()
- .AllowGetPIDs()
- .AllowGetRandom()
.AllowHandleSignals()
- .AllowMmap()
.AllowOpen()
.AllowRead()
- .AllowReadlink()
- .AllowRestartableSequences(sandbox2::PolicyBuilder::kAllowSlowFences)
.AllowSelect()
.AllowSafeFcntl()
- .AllowSyscall(__NR_tgkill)
- .AllowTCGETS()
- .AllowWrite();
+ .AllowTCGETS();
}
} // namespace cuttlefish
diff --git a/host/commands/process_sandboxer/policies/logcat_receiver.cpp b/host/commands/process_sandboxer/policies/logcat_receiver.cpp
index b761144eb..c03e4d6fa 100644
--- a/host/commands/process_sandboxer/policies/logcat_receiver.cpp
+++ b/host/commands/process_sandboxer/policies/logcat_receiver.cpp
@@ -28,27 +28,13 @@ namespace cuttlefish {
sandbox2::PolicyBuilder LogcatReceiverPolicy(const HostInfo& host) {
auto exe = JoinPath(host.artifacts_path, "bin", "logcat_receiver");
- auto lib64 = JoinPath(host.artifacts_path, "lib64");
- return sandbox2::PolicyBuilder()
- .AddDirectory(lib64)
+ return BaselinePolicy(host, exe)
.AddDirectory(host.log_dir, /* is_ro= */ false)
.AddFile(host.cuttlefish_config_path)
- .AddLibrariesForBinary(exe, lib64)
- // For dynamic linking
- .AddPolicyOnSyscall(__NR_prctl,
- {ARG_32(0), JEQ32(PR_CAPBSET_READ, ALLOW)})
- .AllowDynamicStartup()
- .AllowExit()
- .AllowGetPIDs()
- .AllowGetRandom()
.AllowHandleSignals()
- .AllowMmap()
.AllowOpen()
.AllowRead()
- .AllowReadlink()
- .AllowRestartableSequences(sandbox2::PolicyBuilder::kAllowSlowFences)
.AllowSafeFcntl()
- .AllowSyscall(__NR_tgkill)
.AllowWrite();
}
diff --git a/host/commands/process_sandboxer/policies/process_sandboxer_test_hello_world.cpp b/host/commands/process_sandboxer/policies/process_sandboxer_test_hello_world.cpp
new file mode 100644
index 000000000..2a9fe70c3
--- /dev/null
+++ b/host/commands/process_sandboxer/policies/process_sandboxer_test_hello_world.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "host/commands/process_sandboxer/policies.h"
+
+#include "sandboxed_api/sandbox2/policybuilder.h"
+#include "sandboxed_api/util/path.h"
+
+using sapi::file::JoinPath;
+
+namespace cuttlefish {
+
+sandbox2::PolicyBuilder HelloWorldPolicy(const HostInfo& host) {
+ auto exe =
+ JoinPath(host.artifacts_path, "testcases", "process_sandboxer_test",
+ "x86_64", "process_sandboxer_test_hello_world");
+ return BaselinePolicy(host, exe);
+}
+
+} // namespace cuttlefish
diff --git a/host/commands/process_sandboxer/process_sandboxer_test.cpp b/host/commands/process_sandboxer/process_sandboxer_test.cpp
new file mode 100644
index 000000000..0043a068e
--- /dev/null
+++ b/host/commands/process_sandboxer/process_sandboxer_test.cpp
@@ -0,0 +1,70 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// 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.
+
+#include <libgen.h>
+#include <stdlib.h>
+
+#include <string>
+#include <string_view>
+
+#include <fmt/format.h>
+#include <gtest/gtest.h>
+
+#include "common/libs/utils/subprocess.h"
+
+namespace cuttlefish {
+
+static std::string ExecutableSelfPath() {
+ char exe_path[PATH_MAX + 1];
+ auto path_size = readlink("/proc/self/exe", exe_path, PATH_MAX);
+ CHECK_GT(path_size, 0) << strerror(errno);
+ CHECK_LE(path_size, PATH_MAX);
+ exe_path[path_size + 1] = '\0'; // Readlink does not append a null terminator
+ char abs_path[PATH_MAX];
+ char* real = realpath(exe_path, abs_path);
+ CHECK(real) << strerror(errno);
+ return real;
+}
+
+static std::string HostArtifactsDir() {
+ auto path = ExecutableSelfPath();
+ path = dirname(path.data()); // x86_64
+ path = dirname(path.data()); // <test case>
+ path = dirname(path.data()); // testcases
+ path = dirname(path.data()); // linux-86
+ return path;
+}
+
+static std::string ExecutablePath(std::string_view exe) {
+ auto dir_path = ExecutableSelfPath();
+ dir_path = dirname(dir_path.data());
+ return fmt::format("{}/{}", dir_path, exe);
+}
+
+TEST(SandboxExecutable, HelloWorld) {
+ Command executable(ExecutablePath("process_sandboxer_test_hello_world"));
+ auto opt = SubprocessOptions().SandboxArguments({
+ ExecutablePath("process_sandboxer"),
+ "--host_artifacts_path=" + HostArtifactsDir(),
+ });
+
+ std::string in, out, err;
+ int code = RunWithManagedStdio(std::move(executable), &in, &out, &err, opt);
+
+ EXPECT_EQ(code, 0) << err;
+ EXPECT_EQ(out, "Allocated vector with 100 members\n");
+}
+
+} // namespace cuttlefish
diff --git a/host/commands/process_sandboxer/test_executables/Android.bp b/host/commands/process_sandboxer/test_executables/Android.bp
new file mode 100644
index 000000000..c9feefb5e
--- /dev/null
+++ b/host/commands/process_sandboxer/test_executables/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// 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.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Executables intended to validate process_sandboxer itself
+
+cc_binary_host {
+ name: "process_sandboxer_test_hello_world",
+ defaults: ["cuttlefish_buildhost_only"],
+ srcs: ["process_sandboxer_test_hello_world.cpp"],
+}
diff --git a/host/commands/process_sandboxer/test_executables/process_sandboxer_test_hello_world.cpp b/host/commands/process_sandboxer/test_executables/process_sandboxer_test_hello_world.cpp
new file mode 100644
index 000000000..b1cd1bf3b
--- /dev/null
+++ b/host/commands/process_sandboxer/test_executables/process_sandboxer_test_hello_world.cpp
@@ -0,0 +1,13 @@
+#include <iostream>
+#include <string>
+#include <vector>
+
+int main() {
+ // Exercise dynamic memory allocation
+ std::vector<std::string> test_vec;
+ for (size_t i = 0; i < 100; i++) {
+ test_vec.emplace_back(std::to_string(i));
+ }
+ // Exercise writing to stderr
+ std::cout << "Allocated vector with " << test_vec.size() << " members\n";
+}