summaryrefslogtreecommitdiffhomepage
path: root/test/util
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2021-08-11 18:18:36 -0700
committergVisor bot <gvisor-bot@google.com>2021-08-11 18:21:40 -0700
commitd51bc877f40d2acbf5b83895f636186c87463ab1 (patch)
treea3dcf26bcd3f05994df22cd359b2b4ac6503da55 /test/util
parenta50596874a4971167f97a05181363e91292a2885 (diff)
Run packet socket tests on Fuchsia
+ Do not check for CAP_NET_RAW on Fuchsia Fuchsia does not support capabilities the same way Linux does. Instead emulate the check for CAP_NET_RAW by checking if a packet socket may be created. Bug: https://fxbug.dev/79016, https://fxbug.dev/81592 PiperOrigin-RevId: 390263666
Diffstat (limited to 'test/util')
-rw-r--r--test/util/BUILD1
-rw-r--r--test/util/capability_util.h20
-rw-r--r--test/util/fuchsia_capability_util.cc54
-rw-r--r--test/util/fuchsia_capability_util.h41
-rw-r--r--test/util/linux_capability_util.cc8
5 files changed, 68 insertions, 56 deletions
diff --git a/test/util/BUILD b/test/util/BUILD
index 3211546f5..b92af1c27 100644
--- a/test/util/BUILD
+++ b/test/util/BUILD
@@ -14,7 +14,6 @@ cc_library(
],
hdrs = [
"capability_util.h",
- "fuchsia_capability_util.h",
"linux_capability_util.h",
],
deps = [
diff --git a/test/util/capability_util.h b/test/util/capability_util.h
index f5d622e2d..318a43feb 100644
--- a/test/util/capability_util.h
+++ b/test/util/capability_util.h
@@ -18,11 +18,29 @@
#define GVISOR_TEST_UTIL_CAPABILITY_UTIL_H_
#if defined(__Fuchsia__)
-#include "test/util/fuchsia_capability_util.h"
+// Nothing to include.
#elif defined(__linux__)
#include "test/util/linux_capability_util.h"
#else
#error "Unhandled platform"
#endif
+namespace gvisor {
+namespace testing {
+
+// HaveRawIPSocketCapability returns whether or not the process has access to
+// raw IP sockets.
+//
+// Returns an error when raw IP socket access cannot be determined.
+PosixErrorOr<bool> HaveRawIPSocketCapability();
+
+// HavePacketSocketCapability returns whether or not the process has access to
+// packet sockets.
+//
+// Returns an error when packet socket access cannot be determined.
+PosixErrorOr<bool> HavePacketSocketCapability();
+
+} // namespace testing
+} // namespace gvisor
+
#endif // GVISOR_TEST_UTIL_CAPABILITY_UTIL_H_
diff --git a/test/util/fuchsia_capability_util.cc b/test/util/fuchsia_capability_util.cc
index 43f60f20f..bbe8643e7 100644
--- a/test/util/fuchsia_capability_util.cc
+++ b/test/util/fuchsia_capability_util.cc
@@ -14,8 +14,7 @@
#ifdef __Fuchsia__
-#include "test/util/fuchsia_capability_util.h"
-
+#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <sys/socket.h>
@@ -24,19 +23,48 @@
namespace gvisor {
namespace testing {
-PosixErrorOr<bool> HaveCapability(int cap) {
- if (cap == CAP_NET_RAW) {
- auto s = Socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
- if (s.ok()) {
- return true;
- }
- if (s.error().errno_value() == EPERM) {
- return false;
- }
- return s.error();
+// On Linux, access to raw IP and packet socket is controlled by a single
+// capability (CAP_NET_RAW). However on Fuchsia, access to raw IP and packet
+// sockets are controlled by separate capabilities/protocols.
+
+namespace {
+
+PosixErrorOr<bool> HaveSocketCapability(int domain, int type, int protocol) {
+ // Fuchsia does not have a platform supported way to check the protocols made
+ // available to a sandbox. As a workaround, simply try to create the specified
+ // socket and assume no access if we get a no permissions error.
+ auto s = Socket(domain, type, protocol);
+ if (s.ok()) {
+ return true;
}
+ if (s.error().errno_value() == EPERM) {
+ return false;
+ }
+ return s.error();
+}
+
+} // namespace
+
+PosixErrorOr<bool> HaveRawIPSocketCapability() {
+ static PosixErrorOr<bool> result(false);
+ static std::once_flag once;
+
+ std::call_once(once, [&]() {
+ result = HaveSocketCapability(AF_INET, SOCK_RAW, IPPROTO_UDP);
+ });
+
+ return result;
+}
+
+PosixErrorOr<bool> HavePacketSocketCapability() {
+ static PosixErrorOr<bool> result(false);
+ static std::once_flag once;
+
+ std::call_once(once, [&]() {
+ result = HaveSocketCapability(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ });
- return false;
+ return result;
}
} // namespace testing
diff --git a/test/util/fuchsia_capability_util.h b/test/util/fuchsia_capability_util.h
deleted file mode 100644
index 87657d7e8..000000000
--- a/test/util/fuchsia_capability_util.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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.
-
-// Utilities for testing capabilities on Fuchsia.
-
-#ifndef GVISOR_TEST_UTIL_FUCHSIA_CAPABILITY_UTIL_H_
-#define GVISOR_TEST_UTIL_FUCHSIA_CAPABILITY_UTIL_H_
-
-#ifdef __Fuchsia__
-
-#include "test/util/posix_error.h"
-
-#ifdef CAP_NET_RAW
-#error "Fuchsia should not define CAP_NET_RAW"
-#endif // CAP_NET_RAW
-#define CAP_NET_RAW 0
-
-namespace gvisor {
-namespace testing {
-
-// HaveCapability returns true if the process has the specified EFFECTIVE
-// capability.
-PosixErrorOr<bool> HaveCapability(int cap);
-
-} // namespace testing
-} // namespace gvisor
-
-#endif // __Fuchsia__
-
-#endif // GVISOR_TEST_UTIL_FUCHSIA_CAPABILITY_UTIL_H_
diff --git a/test/util/linux_capability_util.cc b/test/util/linux_capability_util.cc
index 958eb96f9..7218aa4ac 100644
--- a/test/util/linux_capability_util.cc
+++ b/test/util/linux_capability_util.cc
@@ -32,6 +32,14 @@
namespace gvisor {
namespace testing {
+PosixErrorOr<bool> HaveRawIPSocketCapability() {
+ return HaveCapability(CAP_NET_RAW);
+}
+
+PosixErrorOr<bool> HavePacketSocketCapability() {
+ return HaveCapability(CAP_NET_RAW);
+}
+
PosixErrorOr<bool> CanCreateUserNamespace() {
// The most reliable way to determine if userns creation is possible is by
// trying to create one; see below.