summaryrefslogtreecommitdiffhomepage
path: root/test/util
diff options
context:
space:
mode:
Diffstat (limited to 'test/util')
-rw-r--r--test/util/BUILD23
-rw-r--r--test/util/fs_util.cc9
-rw-r--r--test/util/fs_util.h3
-rw-r--r--test/util/memory_util.h12
-rw-r--r--test/util/proc_util.cc2
-rw-r--r--test/util/save_util.cc12
-rw-r--r--test/util/save_util.h5
-rw-r--r--test/util/save_util_linux.cc33
-rw-r--r--test/util/save_util_other.cc23
-rw-r--r--test/util/test_util.cc4
-rw-r--r--test/util/test_util.h1
-rw-r--r--test/util/thread_util.h18
-rw-r--r--test/util/uid_util.cc44
-rw-r--r--test/util/uid_util.h29
14 files changed, 199 insertions, 19 deletions
diff --git a/test/util/BUILD b/test/util/BUILD
index c124cef34..5d2a9cc2c 100644
--- a/test/util/BUILD
+++ b/test/util/BUILD
@@ -1,3 +1,6 @@
+load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
+load("//test/syscalls:build_defs.bzl", "select_for_linux")
+
package(
default_visibility = ["//:sandbox"],
licenses = ["notice"],
@@ -139,7 +142,11 @@ cc_library(
cc_library(
name = "save_util",
testonly = 1,
- srcs = ["save_util.cc"],
+ srcs = ["save_util.cc"] +
+ select_for_linux(
+ ["save_util_linux.cc"],
+ ["save_util_other.cc"],
+ ),
hdrs = ["save_util.h"],
)
@@ -232,8 +239,9 @@ cc_library(
":logging",
":posix_error",
":save_util",
- "@com_github_gflags_gflags//:gflags",
"@com_google_absl//absl/base:core_headers",
+ "@com_google_absl//absl/flags:flag",
+ "@com_google_absl//absl/flags:parse",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
@@ -316,3 +324,14 @@ cc_library(
":test_util",
],
)
+
+cc_library(
+ name = "uid_util",
+ testonly = 1,
+ srcs = ["uid_util.cc"],
+ hdrs = ["uid_util.h"],
+ deps = [
+ ":posix_error",
+ ":save_util",
+ ],
+)
diff --git a/test/util/fs_util.cc b/test/util/fs_util.cc
index ae49725a0..f7d231b14 100644
--- a/test/util/fs_util.cc
+++ b/test/util/fs_util.cc
@@ -105,6 +105,15 @@ PosixErrorOr<struct stat> Stat(absl::string_view path) {
return stat_buf;
}
+PosixErrorOr<struct stat> Fstat(int fd) {
+ struct stat stat_buf;
+ int res = fstat(fd, &stat_buf);
+ if (res < 0) {
+ return PosixError(errno, absl::StrCat("fstat ", fd));
+ }
+ return stat_buf;
+}
+
PosixErrorOr<bool> Exists(absl::string_view path) {
struct stat stat_buf;
int res = stat(std::string(path).c_str(), &stat_buf);
diff --git a/test/util/fs_util.h b/test/util/fs_util.h
index 3969f8309..e5b555891 100644
--- a/test/util/fs_util.h
+++ b/test/util/fs_util.h
@@ -35,6 +35,9 @@ PosixErrorOr<bool> Exists(absl::string_view path);
// Returns a stat structure for the given path or an error.
PosixErrorOr<struct stat> Stat(absl::string_view path);
+// Returns a stat struct for the given fd.
+PosixErrorOr<struct stat> Fstat(int fd);
+
// Deletes the file or directory at path or returns an error.
PosixError Delete(absl::string_view path);
diff --git a/test/util/memory_util.h b/test/util/memory_util.h
index 190c469b5..e189b73e8 100644
--- a/test/util/memory_util.h
+++ b/test/util/memory_util.h
@@ -118,6 +118,18 @@ inline PosixErrorOr<Mapping> MmapAnon(size_t length, int prot, int flags) {
return Mmap(nullptr, length, prot, flags | MAP_ANONYMOUS, -1, 0);
}
+// Wrapper for mremap that returns a PosixErrorOr<>, since the return type of
+// void* isn't directly compatible with SyscallSucceeds.
+inline PosixErrorOr<void*> Mremap(void* old_address, size_t old_size,
+ size_t new_size, int flags,
+ void* new_address) {
+ void* rv = mremap(old_address, old_size, new_size, flags, new_address);
+ if (rv == MAP_FAILED) {
+ return PosixError(errno, "mremap failed");
+ }
+ return rv;
+}
+
// Returns true if the page containing addr is mapped.
inline bool IsMapped(uintptr_t addr) {
int const rv = msync(reinterpret_cast<void*>(addr & ~(kPageSize - 1)),
diff --git a/test/util/proc_util.cc b/test/util/proc_util.cc
index 75b24da37..34d636ba9 100644
--- a/test/util/proc_util.cc
+++ b/test/util/proc_util.cc
@@ -88,7 +88,7 @@ PosixErrorOr<std::vector<ProcMapsEntry>> ParseProcMaps(
std::vector<ProcMapsEntry> entries;
auto lines = absl::StrSplit(contents, '\n', absl::SkipEmpty());
for (const auto& l : lines) {
- std::cout << "line: " << l;
+ std::cout << "line: " << l << std::endl;
ASSIGN_OR_RETURN_ERRNO(auto entry, ParseProcMapsLine(l));
entries.push_back(entry);
}
diff --git a/test/util/save_util.cc b/test/util/save_util.cc
index 05f52b80d..384d626f0 100644
--- a/test/util/save_util.cc
+++ b/test/util/save_util.cc
@@ -16,8 +16,8 @@
#include <stddef.h>
#include <stdlib.h>
-#include <sys/syscall.h>
#include <unistd.h>
+
#include <atomic>
#include <cerrno>
@@ -61,13 +61,11 @@ void DisableSave::reset() {
}
}
-void MaybeSave() {
- if (CooperativeSaveEnabled() && !save_disable.load()) {
- int orig_errno = errno;
- syscall(SYS_create_module, nullptr, 0);
- errno = orig_errno;
- }
+namespace internal {
+bool ShouldSave() {
+ return CooperativeSaveEnabled() && (save_disable.load() == 0);
}
+} // namespace internal
} // namespace testing
} // namespace gvisor
diff --git a/test/util/save_util.h b/test/util/save_util.h
index 90460701e..bddad6120 100644
--- a/test/util/save_util.h
+++ b/test/util/save_util.h
@@ -41,6 +41,11 @@ class DisableSave {
//
// errno is guaranteed to be preserved.
void MaybeSave();
+
+namespace internal {
+bool ShouldSave();
+} // namespace internal
+
} // namespace testing
} // namespace gvisor
diff --git a/test/util/save_util_linux.cc b/test/util/save_util_linux.cc
new file mode 100644
index 000000000..7a0f14342
--- /dev/null
+++ b/test/util/save_util_linux.cc
@@ -0,0 +1,33 @@
+// Copyright 2019 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 <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include "test/util/save_util.h"
+
+namespace gvisor {
+namespace testing {
+
+void MaybeSave() {
+ if (internal::ShouldSave()) {
+ int orig_errno = errno;
+ syscall(SYS_create_module, nullptr, 0);
+ errno = orig_errno;
+ }
+}
+
+} // namespace testing
+} // namespace gvisor
diff --git a/test/util/save_util_other.cc b/test/util/save_util_other.cc
new file mode 100644
index 000000000..1aca663b7
--- /dev/null
+++ b/test/util/save_util_other.cc
@@ -0,0 +1,23 @@
+// Copyright 2019 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.
+
+namespace gvisor {
+namespace testing {
+
+void MaybeSave() {
+ // Saving is never available in a non-linux environment.
+}
+
+} // namespace testing
+} // namespace gvisor
diff --git a/test/util/test_util.cc b/test/util/test_util.cc
index e42bba04a..ba0dcf7d0 100644
--- a/test/util/test_util.cc
+++ b/test/util/test_util.cc
@@ -28,6 +28,8 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/flags/flag.h" // IWYU pragma: keep
+#include "absl/flags/parse.h" // IWYU pragma: keep
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
@@ -224,7 +226,7 @@ bool Equivalent(uint64_t current, uint64_t target, double tolerance) {
void TestInit(int* argc, char*** argv) {
::testing::InitGoogleTest(argc, *argv);
- ::gflags::ParseCommandLineFlags(argc, argv, true);
+ ::absl::ParseCommandLine(*argc, *argv);
// Always mask SIGPIPE as it's common and tests aren't expected to handle it.
struct sigaction sa = {};
diff --git a/test/util/test_util.h b/test/util/test_util.h
index cdbe8bfd1..b9d2dc2ba 100644
--- a/test/util/test_util.h
+++ b/test/util/test_util.h
@@ -185,7 +185,6 @@
#include <utility>
#include <vector>
-#include <gflags/gflags.h>
#include "gmock/gmock.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
diff --git a/test/util/thread_util.h b/test/util/thread_util.h
index 860e77531..923c4fe10 100644
--- a/test/util/thread_util.h
+++ b/test/util/thread_util.h
@@ -16,7 +16,9 @@
#define GVISOR_TEST_UTIL_THREAD_UTIL_H_
#include <pthread.h>
+#ifdef __linux__
#include <sys/syscall.h>
+#endif
#include <unistd.h>
#include <functional>
@@ -66,13 +68,13 @@ class ScopedThread {
private:
void CreateThread() {
- TEST_PCHECK_MSG(
- pthread_create(&pt_, /* attr = */ nullptr,
- +[](void* arg) -> void* {
- return static_cast<ScopedThread*>(arg)->f_();
- },
- this) == 0,
- "thread creation failed");
+ TEST_PCHECK_MSG(pthread_create(
+ &pt_, /* attr = */ nullptr,
+ +[](void* arg) -> void* {
+ return static_cast<ScopedThread*>(arg)->f_();
+ },
+ this) == 0,
+ "thread creation failed");
}
std::function<void*()> f_;
@@ -81,7 +83,9 @@ class ScopedThread {
void* retval_ = nullptr;
};
+#ifdef __linux__
inline pid_t gettid() { return syscall(SYS_gettid); }
+#endif
} // namespace testing
} // namespace gvisor
diff --git a/test/util/uid_util.cc b/test/util/uid_util.cc
new file mode 100644
index 000000000..b131b4b99
--- /dev/null
+++ b/test/util/uid_util.cc
@@ -0,0 +1,44 @@
+// Copyright 2018 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 "test/util/posix_error.h"
+#include "test/util/save_util.h"
+
+namespace gvisor {
+namespace testing {
+
+PosixErrorOr<bool> IsRoot() {
+ uid_t ruid, euid, suid;
+ int rc = getresuid(&ruid, &euid, &suid);
+ MaybeSave();
+ if (rc < 0) {
+ return PosixError(errno, "getresuid");
+ }
+ if (ruid != 0 || euid != 0 || suid != 0) {
+ return false;
+ }
+ gid_t rgid, egid, sgid;
+ rc = getresgid(&rgid, &egid, &sgid);
+ MaybeSave();
+ if (rc < 0) {
+ return PosixError(errno, "getresgid");
+ }
+ if (rgid != 0 || egid != 0 || sgid != 0) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace testing
+} // namespace gvisor
diff --git a/test/util/uid_util.h b/test/util/uid_util.h
new file mode 100644
index 000000000..2cd387fb0
--- /dev/null
+++ b/test/util/uid_util.h
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#ifndef GVISOR_TEST_SYSCALLS_UID_UTIL_H_
+#define GVISOR_TEST_SYSCALLS_UID_UTIL_H_
+
+#include "test/util/posix_error.h"
+
+namespace gvisor {
+namespace testing {
+
+// Returns true if the caller's real/effective/saved user/group IDs are all 0.
+PosixErrorOr<bool> IsRoot();
+
+} // namespace testing
+} // namespace gvisor
+
+#endif // GVISOR_TEST_SYSCALLS_UID_UTIL_H_