summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux/xattr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux/xattr.cc')
-rw-r--r--test/syscalls/linux/xattr.cc191
1 files changed, 82 insertions, 109 deletions
diff --git a/test/syscalls/linux/xattr.cc b/test/syscalls/linux/xattr.cc
index 75740238c..e77c355d7 100644
--- a/test/syscalls/linux/xattr.cc
+++ b/test/syscalls/linux/xattr.cc
@@ -26,6 +26,7 @@
#include "gtest/gtest.h"
#include "test/syscalls/linux/file_base.h"
#include "test/util/capability_util.h"
+#include "test/util/file_descriptor.h"
#include "test/util/posix_error.h"
#include "test/util/temp_path.h"
#include "test/util/test_util.h"
@@ -59,7 +60,8 @@ TEST_F(XattrTest, XattrLargeName) {
std::string name = "user.";
name += std::string(XATTR_NAME_MAX - name.length(), 'a');
- // TODO(b/127675828): Support setxattr and getxattr.
+ // An xattr should be whitelisted before it can be accessed--do not allow
+ // arbitrary xattrs to be read/written in gVisor.
if (!IsRunningOnGvisor()) {
EXPECT_THAT(setxattr(path, name.c_str(), nullptr, 0, /*flags=*/0),
SyscallSucceeds());
@@ -83,59 +85,53 @@ TEST_F(XattrTest, XattrInvalidPrefix) {
SyscallFailsWithErrno(EOPNOTSUPP));
}
-TEST_F(XattrTest, XattrReadOnly) {
+// Do not allow save/restore cycles after making the test file read-only, as
+// the restore will fail to open it with r/w permissions.
+TEST_F(XattrTest, XattrReadOnly_NoRandomSave) {
// Drop capabilities that allow us to override file and directory permissions.
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false));
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
size_t size = sizeof(val);
- // TODO(b/127675828): Support setxattr and getxattr.
- if (!IsRunningOnGvisor()) {
- EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0),
- SyscallSucceeds());
- }
+ EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0), SyscallSucceeds());
+ DisableSave ds;
ASSERT_NO_ERRNO(testing::Chmod(test_file_name_, S_IRUSR));
EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0),
SyscallFailsWithErrno(EACCES));
- // TODO(b/127675828): Support setxattr and getxattr.
- if (!IsRunningOnGvisor()) {
- char buf = '-';
- EXPECT_THAT(getxattr(path, name, &buf, size),
- SyscallSucceedsWithValue(size));
- EXPECT_EQ(buf, val);
- }
+ char buf = '-';
+ EXPECT_THAT(getxattr(path, name, &buf, size), SyscallSucceedsWithValue(size));
+ EXPECT_EQ(buf, val);
}
-TEST_F(XattrTest, XattrWriteOnly) {
+// Do not allow save/restore cycles after making the test file write-only, as
+// the restore will fail to open it with r/w permissions.
+TEST_F(XattrTest, XattrWriteOnly_NoRandomSave) {
// Drop capabilities that allow us to override file and directory permissions.
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false));
+ DisableSave ds;
ASSERT_NO_ERRNO(testing::Chmod(test_file_name_, S_IWUSR));
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
size_t size = sizeof(val);
- // TODO(b/127675828): Support setxattr and getxattr.
- if (!IsRunningOnGvisor()) {
- EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0),
- SyscallSucceeds());
- }
+ EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0), SyscallSucceeds());
EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(EACCES));
}
TEST_F(XattrTest, XattrTrustedWithNonadmin) {
- // TODO(b/127675828): Support setxattr and getxattr.
+ // TODO(b/127675828): Support setxattr and getxattr with "trusted" prefix.
SKIP_IF(IsRunningOnGvisor());
SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
@@ -147,11 +143,8 @@ TEST_F(XattrTest, XattrTrustedWithNonadmin) {
}
TEST_F(XattrTest, XattrOnDirectory) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
- char name[] = "user.abc";
+ const char name[] = "user.test";
EXPECT_THAT(setxattr(dir.path().c_str(), name, NULL, 0, /*flags=*/0),
SyscallSucceeds());
EXPECT_THAT(getxattr(dir.path().c_str(), name, NULL, 0),
@@ -159,13 +152,10 @@ TEST_F(XattrTest, XattrOnDirectory) {
}
TEST_F(XattrTest, XattrOnSymlink) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
TempPath link = ASSERT_NO_ERRNO_AND_VALUE(
TempPath::CreateSymlinkTo(dir.path(), test_file_name_));
- char name[] = "user.abc";
+ const char name[] = "user.test";
EXPECT_THAT(setxattr(link.path().c_str(), name, NULL, 0, /*flags=*/0),
SyscallSucceeds());
EXPECT_THAT(getxattr(link.path().c_str(), name, NULL, 0),
@@ -173,7 +163,7 @@ TEST_F(XattrTest, XattrOnSymlink) {
}
TEST_F(XattrTest, XattrOnInvalidFileTypes) {
- char name[] = "user.abc";
+ const char name[] = "user.test";
char char_device[] = "/dev/zero";
EXPECT_THAT(setxattr(char_device, name, NULL, 0, /*flags=*/0),
@@ -191,11 +181,8 @@ TEST_F(XattrTest, XattrOnInvalidFileTypes) {
}
TEST_F(XattrTest, SetxattrSizeSmallerThanValue) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
size_t size = 1;
EXPECT_THAT(setxattr(path, name, val.data(), size, /*flags=*/0),
@@ -209,11 +196,8 @@ TEST_F(XattrTest, SetxattrSizeSmallerThanValue) {
}
TEST_F(XattrTest, SetxattrZeroSize) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
EXPECT_THAT(setxattr(path, name, &val, 0, /*flags=*/0), SyscallSucceeds());
@@ -225,7 +209,7 @@ TEST_F(XattrTest, SetxattrZeroSize) {
TEST_F(XattrTest, SetxattrSizeTooLarge) {
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
// Note that each particular fs implementation may stipulate a lower size
// limit, in which case we actually may fail (e.g. error with ENOSPC) for
@@ -235,43 +219,29 @@ TEST_F(XattrTest, SetxattrSizeTooLarge) {
EXPECT_THAT(setxattr(path, name, val.data(), size, /*flags=*/0),
SyscallFailsWithErrno(E2BIG));
- // TODO(b/127675828): Support setxattr and getxattr.
- if (!IsRunningOnGvisor()) {
- EXPECT_THAT(getxattr(path, name, nullptr, 0),
- SyscallFailsWithErrno(ENODATA));
- }
+ EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
}
TEST_F(XattrTest, SetxattrNullValueAndNonzeroSize) {
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 1, /*flags=*/0),
SyscallFailsWithErrno(EFAULT));
- // TODO(b/127675828): Support setxattr and getxattr.
- if (!IsRunningOnGvisor()) {
- EXPECT_THAT(getxattr(path, name, nullptr, 0),
- SyscallFailsWithErrno(ENODATA));
- }
+ EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
}
TEST_F(XattrTest, SetxattrNullValueAndZeroSize) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallSucceedsWithValue(0));
}
TEST_F(XattrTest, SetxattrValueTooLargeButOKSize) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
std::vector<char> val(XATTR_SIZE_MAX + 1);
std::fill(val.begin(), val.end(), 'a');
size_t size = 1;
@@ -286,11 +256,8 @@ TEST_F(XattrTest, SetxattrValueTooLargeButOKSize) {
}
TEST_F(XattrTest, SetxattrReplaceWithSmaller) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
EXPECT_THAT(setxattr(path, name, val.data(), 2, /*flags=*/0),
SyscallSucceeds());
@@ -304,11 +271,8 @@ TEST_F(XattrTest, SetxattrReplaceWithSmaller) {
}
TEST_F(XattrTest, SetxattrReplaceWithLarger) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
EXPECT_THAT(setxattr(path, name, val.data(), 1, /*flags=*/0),
SyscallSucceeds());
@@ -321,11 +285,8 @@ TEST_F(XattrTest, SetxattrReplaceWithLarger) {
}
TEST_F(XattrTest, SetxattrCreateFlag) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 0, XATTR_CREATE),
SyscallSucceeds());
EXPECT_THAT(setxattr(path, name, nullptr, 0, XATTR_CREATE),
@@ -335,11 +296,8 @@ TEST_F(XattrTest, SetxattrCreateFlag) {
}
TEST_F(XattrTest, SetxattrReplaceFlag) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 0, XATTR_REPLACE),
SyscallFailsWithErrno(ENODATA));
EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
@@ -357,11 +315,8 @@ TEST_F(XattrTest, SetxattrInvalidFlags) {
}
TEST_F(XattrTest, Getxattr) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
int val = 1234;
size_t size = sizeof(val);
EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0), SyscallSucceeds());
@@ -372,11 +327,8 @@ TEST_F(XattrTest, Getxattr) {
}
TEST_F(XattrTest, GetxattrSizeSmallerThanValue) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
size_t size = val.size();
EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0), SyscallSucceeds());
@@ -387,11 +339,8 @@ TEST_F(XattrTest, GetxattrSizeSmallerThanValue) {
}
TEST_F(XattrTest, GetxattrSizeLargerThanValue) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
EXPECT_THAT(setxattr(path, name, &val, 1, /*flags=*/0), SyscallSucceeds());
@@ -405,11 +354,8 @@ TEST_F(XattrTest, GetxattrSizeLargerThanValue) {
}
TEST_F(XattrTest, GetxattrZeroSize) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
EXPECT_THAT(setxattr(path, name, &val, sizeof(val), /*flags=*/0),
SyscallSucceeds());
@@ -421,11 +367,8 @@ TEST_F(XattrTest, GetxattrZeroSize) {
}
TEST_F(XattrTest, GetxattrSizeTooLarge) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
EXPECT_THAT(setxattr(path, name, &val, sizeof(val), /*flags=*/0),
SyscallSucceeds());
@@ -440,11 +383,8 @@ TEST_F(XattrTest, GetxattrSizeTooLarge) {
}
TEST_F(XattrTest, GetxattrNullValue) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
size_t size = sizeof(val);
EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0), SyscallSucceeds());
@@ -454,11 +394,8 @@ TEST_F(XattrTest, GetxattrNullValue) {
}
TEST_F(XattrTest, GetxattrNullValueAndZeroSize) {
- // TODO(b/127675828): Support setxattr and getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- char name[] = "user.abc";
+ const char name[] = "user.test";
char val = 'a';
size_t size = sizeof(val);
// Set value with zero size.
@@ -473,15 +410,51 @@ TEST_F(XattrTest, GetxattrNullValueAndZeroSize) {
}
TEST_F(XattrTest, GetxattrNonexistentName) {
- // TODO(b/127675828): Support getxattr.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
- std::string name = "user.nonexistent";
- EXPECT_THAT(getxattr(path, name.c_str(), nullptr, 0),
+ const char name[] = "user.test";
+ EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
+}
+
+TEST_F(XattrTest, LGetSetxattrOnSymlink) {
+ TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
+ TempPath link = ASSERT_NO_ERRNO_AND_VALUE(
+ TempPath::CreateSymlinkTo(dir.path(), test_file_name_));
+
+ EXPECT_THAT(lsetxattr(link.path().c_str(), nullptr, nullptr, 0, 0),
+ SyscallFailsWithErrno(EPERM));
+ EXPECT_THAT(lgetxattr(link.path().c_str(), nullptr, nullptr, 0),
SyscallFailsWithErrno(ENODATA));
}
+TEST_F(XattrTest, LGetSetxattrOnNonsymlink) {
+ const char* path = test_file_name_.c_str();
+ const char name[] = "user.test";
+ int val = 1234;
+ size_t size = sizeof(val);
+ EXPECT_THAT(lsetxattr(path, name, &val, size, /*flags=*/0),
+ SyscallSucceeds());
+
+ int buf = 0;
+ EXPECT_THAT(lgetxattr(path, name, &buf, size),
+ SyscallSucceedsWithValue(size));
+ EXPECT_EQ(buf, val);
+}
+
+TEST_F(XattrTest, FGetSetxattr) {
+ const FileDescriptor fd =
+ ASSERT_NO_ERRNO_AND_VALUE(Open(test_file_name_.c_str(), 0));
+ const char name[] = "user.test";
+ int val = 1234;
+ size_t size = sizeof(val);
+ EXPECT_THAT(fsetxattr(fd.get(), name, &val, size, /*flags=*/0),
+ SyscallSucceeds());
+
+ int buf = 0;
+ EXPECT_THAT(fgetxattr(fd.get(), name, &buf, size),
+ SyscallSucceedsWithValue(size));
+ EXPECT_EQ(buf, val);
+}
+
} // namespace
} // namespace testing