mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Migrate namespaces related tests out of policybuilder_test
PiperOrigin-RevId: 514325688 Change-Id: I9c581d14da3ac9fe5c3c0b43e156d8ad8d90c73f
This commit is contained in:
parent
64b52ff3b5
commit
526401166e
|
@ -663,9 +663,9 @@ cc_test(
|
|||
name = "namespace_test",
|
||||
srcs = ["namespace_test.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
data = [
|
||||
"//sandboxed_api/sandbox2/testcases:hostname",
|
||||
"//sandboxed_api/sandbox2/testcases:namespace",
|
||||
data = ["//sandboxed_api/sandbox2/testcases:namespace"],
|
||||
tags = [
|
||||
"requires-net:external",
|
||||
],
|
||||
deps = [
|
||||
":namespace",
|
||||
|
@ -1009,17 +1009,8 @@ cc_test(
|
|||
name = "policybuilder_test",
|
||||
srcs = ["policybuilder_test.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
tags = [
|
||||
"no_qemu_user_mode",
|
||||
"requires-net:external",
|
||||
],
|
||||
deps = [
|
||||
":comms",
|
||||
":policybuilder",
|
||||
":sandbox2",
|
||||
":testonly_allow_all_syscalls",
|
||||
"//sandboxed_api:config",
|
||||
"//sandboxed_api:testing",
|
||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||
"//sandboxed_api/util:status_matchers",
|
||||
"@com_google_absl//absl/log",
|
||||
|
|
|
@ -800,7 +800,6 @@ if(BUILD_TESTING AND SAPI_BUILD_TESTING)
|
|||
OUTPUT_NAME namespace_test
|
||||
)
|
||||
add_dependencies(sandbox2_namespace_test
|
||||
sandbox2::testcase_hostname
|
||||
sandbox2::testcase_namespace
|
||||
)
|
||||
target_link_libraries(sandbox2_namespace_test PRIVATE
|
||||
|
@ -1109,11 +1108,11 @@ if(BUILD_TESTING AND SAPI_BUILD_TESTING)
|
|||
)
|
||||
target_link_libraries(sandbox2_policybuilder_test
|
||||
PRIVATE absl::strings
|
||||
sandbox2::allow_all_syscalls
|
||||
absl::log
|
||||
absl::status
|
||||
absl::statusor
|
||||
sandbox2::bpf_helper
|
||||
sandbox2::comms
|
||||
sandbox2::policybuilder
|
||||
sandbox2::sandbox2
|
||||
sapi::testing
|
||||
sapi::status_matchers
|
||||
sapi::test_main
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
@ -47,15 +49,23 @@ using ::sapi::CreateDefaultPermissiveTestPolicy;
|
|||
using ::sapi::CreateNamedTempFile;
|
||||
using ::sapi::GetTestSourcePath;
|
||||
using ::sapi::GetTestTempPath;
|
||||
using ::testing::Contains;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
using ::testing::Gt;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::Ne;
|
||||
using ::testing::SizeIs;
|
||||
using ::testing::StartsWith;
|
||||
using ::testing::StrEq; // sapi::google3-only(broken matchers)
|
||||
|
||||
std::string GetTestcaseBinPath(absl::string_view bin_name) {
|
||||
return GetTestSourcePath(absl::StrCat("sandbox2/testcases/", bin_name));
|
||||
}
|
||||
|
||||
int RunSandboxeeWithArgsAndPolicy(const std::string& bin_path,
|
||||
std::initializer_list<std::string> args,
|
||||
std::vector<std::string> RunSandboxeeWithArgsAndPolicy(
|
||||
const std::string& bin_path, std::initializer_list<std::string> args,
|
||||
std::unique_ptr<Policy> policy = nullptr) {
|
||||
if (!policy) {
|
||||
policy = CreateDefaultPermissiveTestPolicy(bin_path).BuildOrDie();
|
||||
|
@ -63,12 +73,24 @@ int RunSandboxeeWithArgsAndPolicy(const std::string& bin_path,
|
|||
Sandbox2 sandbox(std::make_unique<Executor>(bin_path, args),
|
||||
std::move(policy));
|
||||
|
||||
Result result = sandbox.Run();
|
||||
EXPECT_THAT(result.final_status(), Eq(Result::OK));
|
||||
return result.reason_code();
|
||||
}
|
||||
CHECK(sandbox.RunAsync());
|
||||
Comms* comms = sandbox.comms();
|
||||
uint64_t num;
|
||||
|
||||
constexpr absl::string_view kHostnameTestBinary = "sandbox2/testcases/hostname";
|
||||
std::vector<std::string> entries;
|
||||
if (comms->RecvUint64(&num)) {
|
||||
entries.reserve(num);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
std::string entry;
|
||||
CHECK(comms->RecvString(&entry));
|
||||
entries.push_back(std::move(entry));
|
||||
}
|
||||
}
|
||||
Result result = sandbox.AwaitResult();
|
||||
EXPECT_THAT(result.final_status(), Eq(Result::OK));
|
||||
EXPECT_THAT(result.reason_code(), Eq(0));
|
||||
return entries;
|
||||
}
|
||||
|
||||
TEST(NamespaceTest, FileNamespaceWorks) {
|
||||
// Mount /binary_path RO and check that it exists and is readable.
|
||||
|
@ -78,9 +100,9 @@ TEST(NamespaceTest, FileNamespaceWorks) {
|
|||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy, CreateDefaultPermissiveTestPolicy(path)
|
||||
.AddFileAt(path, "/binary_path")
|
||||
.TryBuild());
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "0", "/binary_path", "/etc/passwd"}, std::move(policy));
|
||||
EXPECT_THAT(reason_code, Eq(2));
|
||||
EXPECT_THAT(result, ElementsAre("/binary_path"));
|
||||
}
|
||||
|
||||
TEST(NamespaceTest, ReadOnlyIsRespected) {
|
||||
|
@ -95,9 +117,9 @@ TEST(NamespaceTest, ReadOnlyIsRespected) {
|
|||
.AddFileAt(name, "/temp_file")
|
||||
.TryBuild());
|
||||
// Check that it is readable
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "0", "/temp_file"}, std::move(policy));
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
EXPECT_THAT(result, ElementsAre("/temp_file"));
|
||||
}
|
||||
{
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
|
||||
|
@ -105,9 +127,9 @@ TEST(NamespaceTest, ReadOnlyIsRespected) {
|
|||
.AddFileAt(name, "/temp_file")
|
||||
.TryBuild());
|
||||
// Now check that it is not writeable
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "1", "/temp_file"}, std::move(policy));
|
||||
EXPECT_THAT(reason_code, Eq(1));
|
||||
EXPECT_THAT(result, IsEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,19 +138,20 @@ TEST(NamespaceTest, UserNamespaceWorks) {
|
|||
|
||||
// Check that getpid() returns 2 (which is the case inside pid NS).
|
||||
{
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(path, {path, "2"});
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
std::vector<std::string> result =
|
||||
RunSandboxeeWithArgsAndPolicy(path, {path, "2"});
|
||||
EXPECT_THAT(result, ElementsAre("2"));
|
||||
}
|
||||
|
||||
// Validate that getpid() does not return 2 when outside of a pid NS.
|
||||
{
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "2"},
|
||||
PolicyBuilder()
|
||||
.DisableNamespaces()
|
||||
.DefaultAction(AllowAllSyscalls()) // Do not restrict syscalls
|
||||
.BuildOrDie());
|
||||
EXPECT_THAT(reason_code, Ne(0));
|
||||
EXPECT_THAT(result, ElementsAre(Ne("2")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,20 +160,21 @@ TEST(NamespaceTest, UserNamespaceIDMapWritten) {
|
|||
// started.
|
||||
const std::string path = GetTestcaseBinPath("namespace");
|
||||
{
|
||||
int reason_code =
|
||||
std::vector<std::string> result =
|
||||
RunSandboxeeWithArgsAndPolicy(path, {path, "3", "1000", "1000"});
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
EXPECT_THAT(result, ElementsAre("1000", "1000"));
|
||||
}
|
||||
|
||||
// Check that the uid/gid is the same when not using namespaces.
|
||||
{
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "3", absl::StrCat(getuid()), absl::StrCat(getgid())},
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "3"},
|
||||
PolicyBuilder()
|
||||
.DisableNamespaces()
|
||||
.DefaultAction(AllowAllSyscalls()) // Do not restrict syscalls
|
||||
.BuildOrDie());
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
EXPECT_THAT(result,
|
||||
ElementsAre(absl::StrCat(getuid()), absl::StrCat(getgid())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,9 +186,9 @@ TEST(NamespaceTest, RootReadOnly) {
|
|||
auto policy, CreateDefaultPermissiveTestPolicy(path)
|
||||
.AddTmpfs("/tmp", /*size=*/4ULL << 20 /* 4 MiB */)
|
||||
.TryBuild());
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "4", "/tmp/testfile", "/testfile"}, std::move(policy));
|
||||
EXPECT_THAT(reason_code, Eq(2));
|
||||
EXPECT_THAT(result, ElementsAre("/tmp/testfile"));
|
||||
}
|
||||
|
||||
TEST(NamespaceTest, RootWritable) {
|
||||
|
@ -173,36 +197,58 @@ TEST(NamespaceTest, RootWritable) {
|
|||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
auto policy,
|
||||
CreateDefaultPermissiveTestPolicy(path).SetRootWritable().TryBuild());
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "4", "/testfile"}, std::move(policy));
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
EXPECT_THAT(result, ElementsAre("/testfile"));
|
||||
}
|
||||
|
||||
TEST(HostnameTest, None) {
|
||||
const std::string path = GetTestcaseBinPath("hostname");
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "sandbox2"},
|
||||
TEST(NamespaceTest, HostnameNone) {
|
||||
const std::string path = GetTestcaseBinPath("namespace");
|
||||
std::vector<std::string> result = RunSandboxeeWithArgsAndPolicy(
|
||||
path, {path, "7"},
|
||||
PolicyBuilder()
|
||||
.DisableNamespaces()
|
||||
.DefaultAction(AllowAllSyscalls()) // Do not restrict syscalls
|
||||
.BuildOrDie());
|
||||
EXPECT_THAT(reason_code, Eq(1));
|
||||
EXPECT_THAT(result, ElementsAre(Ne("sandbox2")));
|
||||
}
|
||||
|
||||
TEST(HostnameTest, Default) {
|
||||
const std::string path = GetTestcaseBinPath("hostname");
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(path, {path, "sandbox2"});
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
TEST(NamespaceTest, HostnameDefault) {
|
||||
const std::string path = GetTestcaseBinPath("namespace");
|
||||
std::vector<std::string> result =
|
||||
RunSandboxeeWithArgsAndPolicy(path, {path, "7"});
|
||||
EXPECT_THAT(result, ElementsAre("sandbox2"));
|
||||
}
|
||||
|
||||
TEST(HostnameTest, Configured) {
|
||||
const std::string path = GetTestcaseBinPath("hostname");
|
||||
TEST(NamespaceTest, HostnameConfigured) {
|
||||
const std::string path = GetTestcaseBinPath("namespace");
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy, CreateDefaultPermissiveTestPolicy(path)
|
||||
.SetHostname("configured")
|
||||
.TryBuild());
|
||||
int reason_code = RunSandboxeeWithArgsAndPolicy(path, {path, "configured"},
|
||||
std::move(policy));
|
||||
EXPECT_THAT(reason_code, Eq(0));
|
||||
std::vector<std::string> result =
|
||||
RunSandboxeeWithArgsAndPolicy(path, {path, "7"}, std::move(policy));
|
||||
EXPECT_THAT(result, ElementsAre("configured"));
|
||||
}
|
||||
|
||||
TEST(NamespaceTest, TestInterfacesNoNetwork) {
|
||||
const std::string path = GetTestcaseBinPath("namespace");
|
||||
std::vector<std::string> result =
|
||||
RunSandboxeeWithArgsAndPolicy(path, {path, "5"});
|
||||
// Only loopback network interface 'lo'.
|
||||
EXPECT_THAT(result, ElementsAre("lo"));
|
||||
}
|
||||
|
||||
TEST(NamespaceTest, TestInterfacesWithNetwork) {
|
||||
const std::string path = GetTestcaseBinPath("namespace");
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy, CreateDefaultPermissiveTestPolicy(path)
|
||||
.AllowUnrestrictedNetworking()
|
||||
.TryBuild());
|
||||
|
||||
std::vector<std::string> result =
|
||||
RunSandboxeeWithArgsAndPolicy(path, {path, "5"}, std::move(policy));
|
||||
// Loopback network interface 'lo' and more.
|
||||
EXPECT_THAT(result, Contains("lo"));
|
||||
EXPECT_THAT(result, SizeIs(Gt(1)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -26,18 +26,7 @@
|
|||
#include "absl/log/log.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "sandboxed_api/config.h"
|
||||
#include "sandboxed_api/sandbox2/allow_all_syscalls.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/executor.h"
|
||||
#include "sandboxed_api/sandbox2/ipc.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/sandbox2.h"
|
||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||
#include "sandboxed_api/testing.h"
|
||||
#include "sandboxed_api/util/status_matchers.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
@ -59,24 +48,14 @@ class PolicyBuilderPeer {
|
|||
|
||||
namespace {
|
||||
|
||||
using ::testing::AllOf;
|
||||
using ::testing::AnyOf;
|
||||
using ::testing::Eq;
|
||||
using ::testing::Gt;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::Lt;
|
||||
using ::testing::StartsWith;
|
||||
using ::testing::StrEq;
|
||||
using ::sapi::IsOk;
|
||||
using ::sapi::StatusIs;
|
||||
|
||||
class PolicyBuilderTest : public testing::Test {
|
||||
protected:
|
||||
static std::string Run(const std::vector<std::string>& args,
|
||||
bool network = false);
|
||||
};
|
||||
|
||||
TEST_F(PolicyBuilderTest, Testpolicy_size) {
|
||||
TEST(PolicyBuilderTest, Testpolicy_size) {
|
||||
ssize_t last_size = 0;
|
||||
PolicyBuilder builder;
|
||||
PolicyBuilderPeer builder_peer{&builder};
|
||||
|
@ -131,7 +110,7 @@ TEST_F(PolicyBuilderTest, Testpolicy_size) {
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestValidateAbsolutePath) {
|
||||
TEST(PolicyBuilderTest, TestValidateAbsolutePath) {
|
||||
for (auto const& bad_path : {
|
||||
"..",
|
||||
"a",
|
||||
|
@ -155,52 +134,14 @@ TEST_F(PolicyBuilderTest, TestValidateAbsolutePath) {
|
|||
}
|
||||
}
|
||||
|
||||
std::string PolicyBuilderTest::Run(const std::vector<std::string>& args,
|
||||
bool network) {
|
||||
PolicyBuilder builder;
|
||||
// Don't restrict the syscalls at all.
|
||||
builder.DefaultAction(AllowAllSyscalls());
|
||||
|
||||
if constexpr (sapi::host_os::IsAndroid()) {
|
||||
builder.DisableNamespaces();
|
||||
} else {
|
||||
builder.AddLibrariesForBinary(args[0]);
|
||||
}
|
||||
|
||||
if (network) {
|
||||
builder.AllowUnrestrictedNetworking();
|
||||
}
|
||||
|
||||
auto executor = std::make_unique<sandbox2::Executor>(args[0], args);
|
||||
int fd1 = executor->ipc()->ReceiveFd(STDOUT_FILENO);
|
||||
sandbox2::Sandbox2 s2(std::move(executor), builder.BuildOrDie());
|
||||
|
||||
s2.RunAsync();
|
||||
|
||||
char buf[4096];
|
||||
std::string output;
|
||||
|
||||
while (true) {
|
||||
int nbytes;
|
||||
PCHECK((nbytes = read(fd1, buf, sizeof(buf))) >= 0);
|
||||
|
||||
if (nbytes == 0) break;
|
||||
output += std::string(buf, nbytes);
|
||||
}
|
||||
|
||||
auto result = s2.AwaitResult();
|
||||
EXPECT_EQ(result.final_status(), sandbox2::Result::OK);
|
||||
return output;
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestCanOnlyBuildOnce) {
|
||||
TEST(PolicyBuilderTest, TestCanOnlyBuildOnce) {
|
||||
PolicyBuilder b;
|
||||
ASSERT_THAT(b.TryBuild(), IsOk());
|
||||
EXPECT_THAT(b.TryBuild(), StatusIs(absl::StatusCode::kFailedPrecondition,
|
||||
"Can only build policy once."));
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestIsCopyable) {
|
||||
TEST(PolicyBuilderTest, TestIsCopyable) {
|
||||
PolicyBuilder builder;
|
||||
builder.AllowSyscall(__NR_getpid);
|
||||
|
||||
|
@ -212,40 +153,5 @@ TEST_F(PolicyBuilderTest, TestIsCopyable) {
|
|||
EXPECT_THAT(builder.TryBuild(), IsOk());
|
||||
EXPECT_THAT(copy.TryBuild(), IsOk());
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestEcho) {
|
||||
ASSERT_THAT(Run({"/bin/echo", "HELLO"}), StrEq("HELLO\n"));
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestInterfacesNoNetwork) {
|
||||
SKIP_ANDROID;
|
||||
auto lines = absl::StrSplit(Run({"/sbin/ip", "addr", "show", "up"}), '\n');
|
||||
|
||||
int count = 0;
|
||||
for (auto const& line : lines) {
|
||||
if (!line.empty() && !absl::StartsWith(line, " ")) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Only loopback network interface 'lo'.
|
||||
EXPECT_THAT(count, Eq(1));
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestInterfacesNetwork) {
|
||||
SKIP_ANDROID;
|
||||
auto lines =
|
||||
absl::StrSplit(Run({"/sbin/ip", "addr", "show", "up"}, true), '\n');
|
||||
|
||||
int count = 0;
|
||||
for (auto const& line : lines) {
|
||||
if (!line.empty() && !absl::StartsWith(line, " ")) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Loopback network interface 'lo' and more.
|
||||
EXPECT_THAT(count, Gt(1));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -213,14 +213,6 @@ cc_binary(
|
|||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "hostname",
|
||||
testonly = True,
|
||||
srcs = ["hostname.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "limits",
|
||||
testonly = True,
|
||||
|
@ -235,4 +227,11 @@ cc_binary(
|
|||
srcs = ["namespace.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = ["fully_static_link"],
|
||||
deps = [
|
||||
"//sandboxed_api/sandbox2:comms",
|
||||
"//sandboxed_api/util:file_base",
|
||||
"//sandboxed_api/util:fileops",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/log:check",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -261,19 +261,6 @@ target_link_libraries(sandbox2_testcase_tsync PRIVATE
|
|||
sapi::base
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:hostname
|
||||
add_executable(sandbox2_testcase_hostname
|
||||
hostname.cc
|
||||
)
|
||||
add_executable(sandbox2::testcase_hostname ALIAS sandbox2_testcase_hostname)
|
||||
set_target_properties(sandbox2_testcase_hostname PROPERTIES
|
||||
OUTPUT_NAME hostname
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_hostname PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:limits
|
||||
add_executable(sandbox2_testcase_limits
|
||||
limits.cc
|
||||
|
@ -297,5 +284,10 @@ set_target_properties(sandbox2_testcase_namespace PROPERTIES
|
|||
)
|
||||
target_link_libraries(sandbox2_testcase_namespace PRIVATE
|
||||
-static
|
||||
absl::check
|
||||
absl::flat_hash_set
|
||||
sandbox2::comms
|
||||
sapi::base
|
||||
sapi::file_base
|
||||
sapi::fileops
|
||||
)
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright 2019 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// A binary to test network namespace hostname.
|
||||
// Usage: ./hostname <expected hostname>
|
||||
// Success only if the hostname is as expected.
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("argc < 2\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char hostname[1024];
|
||||
if (gethostname(hostname, sizeof(hostname)) == -1) {
|
||||
printf("gethostname: error %d\n", errno);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(hostname, argv[1]) != 0) {
|
||||
printf("gethostname: got %s, want %s\n", hostname, argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -29,11 +29,48 @@
|
|||
// Create provided files, return 0 on OK.
|
||||
// Returns the index of the first non-creatable file on failure.
|
||||
#include <fcntl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/log/check.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/util/fileops.h"
|
||||
#include "sandboxed_api/util/path.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using sapi::file::JoinPath;
|
||||
using sapi::file_util::fileops::ListDirectoryEntries;
|
||||
|
||||
bool IsDirectory(const std::string& path) {
|
||||
struct stat statbuf;
|
||||
PCHECK(stat(path.c_str(), &statbuf) == 0);
|
||||
return statbuf.st_mode & S_IFDIR;
|
||||
}
|
||||
|
||||
void ListDirectoriesRecursively(const std::string& path,
|
||||
std::vector<std::string>& files) {
|
||||
std::string error;
|
||||
std::vector<std::string> entries;
|
||||
CHECK(ListDirectoryEntries(path, &entries, &error)) << error;
|
||||
for (const std::string& entry : entries) {
|
||||
std::string new_path = JoinPath(path, entry);
|
||||
if (IsDirectory(new_path)) {
|
||||
ListDirectoriesRecursively(new_path, files);
|
||||
} else {
|
||||
files.push_back(new_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
|
@ -41,53 +78,78 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
|
||||
int mode = atoi(argv[1]); // NOLINT(runtime/deprecated_fn)
|
||||
std::vector<std::string> result;
|
||||
|
||||
sandbox2::Comms comms(sandbox2::Comms::kDefaultConnection);
|
||||
|
||||
switch (mode) {
|
||||
case 0: {
|
||||
case 0:
|
||||
// Make sure file exist
|
||||
for (int i = 2; i < argc; i++) {
|
||||
if (access(argv[i], R_OK)) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case 1: {
|
||||
for (int i = 2; i < argc; i++) {
|
||||
if (access(argv[i], W_OK)) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
if (getpid() != 2) {
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
if (argc != 4) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (getuid() != atoi(argv[2]) // NOLINT(runtime/deprecated_fn)
|
||||
|| getgid() != atoi(argv[3])) { // NOLINT(runtime/deprecated_fn)
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 4:
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
if (open(argv[i], O_CREAT | O_WRONLY, 0644) == -1) {
|
||||
return i - 1;
|
||||
if (access(argv[i], R_OK) == 0) {
|
||||
result.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = 2; i < argc; i++) {
|
||||
if (access(argv[i], W_OK) == 0) {
|
||||
result.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result.push_back(absl::StrCat(getpid()));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
result.push_back(absl::StrCat(getuid()));
|
||||
result.push_back(absl::StrCat(getgid()));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
if (open(argv[i], O_CREAT | O_WRONLY, 0644) != -1) {
|
||||
result.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: {
|
||||
absl::flat_hash_set<std::string> ifnames;
|
||||
struct ifaddrs* addrs;
|
||||
if (getifaddrs(&addrs)) {
|
||||
return -1;
|
||||
}
|
||||
for (struct ifaddrs* cur = addrs; cur; cur = cur->ifa_next) {
|
||||
ifnames.insert(cur->ifa_name);
|
||||
}
|
||||
result.insert(result.end(), ifnames.begin(), ifnames.end());
|
||||
freeifaddrs(addrs);
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
ListDirectoriesRecursively(argv[2], result);
|
||||
break;
|
||||
case 7: {
|
||||
char hostname[1000];
|
||||
if (gethostname(hostname, sizeof(hostname)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
result.push_back(hostname);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
CHECK(comms.SendUint64(result.size()));
|
||||
for (const std::string& entry : result) {
|
||||
CHECK(comms.SendString(entry));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user