Add initial verity ioctl syscall tests

PiperOrigin-RevId: 366907152
This commit is contained in:
Chong Cai
2021-04-05 17:31:48 -07:00
committed by gVisor bot
parent 661e5ae7ae
commit 63340e6138
3 changed files with 153 additions and 0 deletions
+4
View File
@@ -243,6 +243,10 @@ syscall_test(
test = "//test/syscalls/linux:ioctl_test",
)
syscall_test(
test = "//test/syscalls/linux:verity_ioctl_test",
)
syscall_test(
test = "//test/syscalls/linux:iptables_test",
)
+16
View File
@@ -1014,6 +1014,22 @@ cc_binary(
],
)
cc_binary(
name = "verity_ioctl_test",
testonly = 1,
srcs = ["verity_ioctl.cc"],
linkstatic = 1,
deps = [
"//test/util:capability_util",
gtest,
"//test/util:fs_util",
"//test/util:mount_util",
"//test/util:temp_path",
"//test/util:test_main",
"//test/util:test_util",
],
)
cc_library(
name = "iptables_types",
testonly = 1,
+133
View File
@@ -0,0 +1,133 @@
// Copyright 2021 The gVisor Authors.
//
// 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 <sys/mount.h>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "test/util/capability_util.h"
#include "test/util/fs_util.h"
#include "test/util/mount_util.h"
#include "test/util/temp_path.h"
#include "test/util/test_util.h"
namespace gvisor {
namespace testing {
namespace {
#ifndef FS_IOC_ENABLE_VERITY
#define FS_IOC_ENABLE_VERITY 1082156677
#endif
#ifndef FS_IOC_MEASURE_VERITY
#define FS_IOC_MEASURE_VERITY 3221513862
#endif
#ifndef FS_VERITY_FL
#define FS_VERITY_FL 1048576
#endif
#ifndef FS_IOC_GETFLAGS
#define FS_IOC_GETFLAGS 2148034049
#endif
struct fsverity_digest {
__u16 digest_algorithm;
__u16 digest_size; /* input/output */
__u8 digest[];
};
const int fsverity_max_digest_size = 64;
const int fsverity_default_digest_size = 32;
class IoctlTest : public ::testing::Test {
protected:
void SetUp() override {
// Verity is implemented in VFS2.
SKIP_IF(IsRunningWithVFS1());
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
// Mount a tmpfs file system, to be wrapped by a verity fs.
tmpfs_dir_ = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
ASSERT_THAT(mount("", tmpfs_dir_.path().c_str(), "tmpfs", 0, ""),
SyscallSucceeds());
// Create a new file in the tmpfs mount.
constexpr char kContents[] = "foobarbaz";
file_ = ASSERT_NO_ERRNO_AND_VALUE(
TempPath::CreateFileWith(tmpfs_dir_.path(), kContents, 0777));
filename_ = Basename(file_.path());
}
TempPath tmpfs_dir_;
TempPath file_;
std::string filename_;
};
TEST_F(IoctlTest, Enable) {
// mount a verity fs on the existing tmpfs mount.
std::string mount_opts = "lower_path=" + tmpfs_dir_.path();
auto const verity_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
ASSERT_THAT(
mount("", verity_dir.path().c_str(), "verity", 0, mount_opts.c_str()),
SyscallSucceeds());
printf("verity path: %s, filename: %s\n", verity_dir.path().c_str(),
filename_.c_str());
fflush(nullptr);
// Confirm that the verity flag is absent.
int flag = 0;
auto const fd = ASSERT_NO_ERRNO_AND_VALUE(
Open(JoinPath(verity_dir.path(), filename_), O_RDONLY, 0777));
ASSERT_THAT(ioctl(fd.get(), FS_IOC_GETFLAGS, &flag), SyscallSucceeds());
EXPECT_EQ(flag & FS_VERITY_FL, 0);
// Enable the file and confirm that the verity flag is present.
ASSERT_THAT(ioctl(fd.get(), FS_IOC_ENABLE_VERITY), SyscallSucceeds());
ASSERT_THAT(ioctl(fd.get(), FS_IOC_GETFLAGS, &flag), SyscallSucceeds());
EXPECT_EQ(flag & FS_VERITY_FL, FS_VERITY_FL);
}
TEST_F(IoctlTest, Measure) {
// mount a verity fs on the existing tmpfs mount.
std::string mount_opts = "lower_path=" + tmpfs_dir_.path();
auto const verity_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
ASSERT_THAT(
mount("", verity_dir.path().c_str(), "verity", 0, mount_opts.c_str()),
SyscallSucceeds());
// Confirm that the file cannot be measured.
auto const fd = ASSERT_NO_ERRNO_AND_VALUE(
Open(JoinPath(verity_dir.path(), filename_), O_RDONLY, 0777));
int digest_size = sizeof(struct fsverity_digest) + fsverity_max_digest_size;
struct fsverity_digest *digest =
reinterpret_cast<struct fsverity_digest *>(malloc(digest_size));
memset(digest, 0, digest_size);
digest->digest_size = fsverity_max_digest_size;
ASSERT_THAT(ioctl(fd.get(), FS_IOC_MEASURE_VERITY, digest),
SyscallFailsWithErrno(ENODATA));
// Enable the file and confirm that the file can be measured.
ASSERT_THAT(ioctl(fd.get(), FS_IOC_ENABLE_VERITY), SyscallSucceeds());
ASSERT_THAT(ioctl(fd.get(), FS_IOC_MEASURE_VERITY, digest),
SyscallSucceeds());
EXPECT_EQ(digest->digest_size, fsverity_default_digest_size);
free(digest);
}
} // namespace
} // namespace testing
} // namespace gvisor