summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux/uname.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux/uname.cc')
-rw-r--r--test/syscalls/linux/uname.cc111
1 files changed, 111 insertions, 0 deletions
diff --git a/test/syscalls/linux/uname.cc b/test/syscalls/linux/uname.cc
new file mode 100644
index 000000000..d8824b171
--- /dev/null
+++ b/test/syscalls/linux/uname.cc
@@ -0,0 +1,111 @@
+// 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 <sched.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+#include "gtest/gtest.h"
+#include "absl/strings/string_view.h"
+#include "test/util/capability_util.h"
+#include "test/util/test_util.h"
+#include "test/util/thread_util.h"
+
+namespace gvisor {
+namespace testing {
+
+namespace {
+
+TEST(UnameTest, Sanity) {
+ struct utsname buf;
+ ASSERT_THAT(uname(&buf), SyscallSucceeds());
+ EXPECT_NE(strlen(buf.release), 0);
+ EXPECT_NE(strlen(buf.version), 0);
+ EXPECT_NE(strlen(buf.machine), 0);
+ EXPECT_NE(strlen(buf.sysname), 0);
+ EXPECT_NE(strlen(buf.nodename), 0);
+ EXPECT_NE(strlen(buf.domainname), 0);
+}
+
+TEST(UnameTest, SetNames) {
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
+
+ char hostname[65];
+ ASSERT_THAT(sethostname("0123456789", 3), SyscallSucceeds());
+ EXPECT_THAT(gethostname(hostname, sizeof(hostname)), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(hostname), "012");
+
+ ASSERT_THAT(sethostname("0123456789\0xxx", 11), SyscallSucceeds());
+ EXPECT_THAT(gethostname(hostname, sizeof(hostname)), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(hostname), "0123456789");
+
+ ASSERT_THAT(sethostname("0123456789\0xxx", 12), SyscallSucceeds());
+ EXPECT_THAT(gethostname(hostname, sizeof(hostname)), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(hostname), "0123456789");
+
+ constexpr char kHostname[] = "wubbalubba";
+ ASSERT_THAT(sethostname(kHostname, sizeof(kHostname)), SyscallSucceeds());
+
+ constexpr char kDomainname[] = "dubdub.com";
+ ASSERT_THAT(setdomainname(kDomainname, sizeof(kDomainname)),
+ SyscallSucceeds());
+
+ struct utsname buf;
+ EXPECT_THAT(uname(&buf), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(buf.nodename), kHostname);
+ EXPECT_EQ(absl::string_view(buf.domainname), kDomainname);
+
+ // These should just be glibc wrappers that also call uname(2).
+ EXPECT_THAT(gethostname(hostname, sizeof(hostname)), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(hostname), kHostname);
+
+ char domainname[65];
+ EXPECT_THAT(getdomainname(domainname, sizeof(domainname)), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(domainname), kDomainname);
+}
+
+TEST(UnameTest, UnprivilegedSetNames) {
+ if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN))) {
+ EXPECT_NO_ERRNO(SetCapability(CAP_SYS_ADMIN, false));
+ }
+
+ EXPECT_THAT(sethostname("", 0), SyscallFailsWithErrno(EPERM));
+ EXPECT_THAT(setdomainname("", 0), SyscallFailsWithErrno(EPERM));
+}
+
+TEST(UnameTest, UnshareUTS) {
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
+
+ struct utsname init;
+ ASSERT_THAT(uname(&init), SyscallSucceeds());
+
+ ScopedThread([&]() {
+ EXPECT_THAT(unshare(CLONE_NEWUTS), SyscallSucceeds());
+
+ constexpr char kHostname[] = "wubbalubba";
+ EXPECT_THAT(sethostname(kHostname, sizeof(kHostname)), SyscallSucceeds());
+
+ char hostname[65];
+ EXPECT_THAT(gethostname(hostname, sizeof(hostname)), SyscallSucceeds());
+ });
+
+ struct utsname after;
+ EXPECT_THAT(uname(&after), SyscallSucceeds());
+ EXPECT_EQ(absl::string_view(after.nodename), init.nodename);
+}
+
+} // namespace
+
+} // namespace testing
+} // namespace gvisor