summaryrefslogtreecommitdiffhomepage
path: root/test/util/fuchsia_capability_util.cc
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/fuchsia_capability_util.cc
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/fuchsia_capability_util.cc')
-rw-r--r--test/util/fuchsia_capability_util.cc54
1 files changed, 41 insertions, 13 deletions
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