diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2021-08-11 18:18:36 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-08-11 18:21:40 -0700 |
commit | d51bc877f40d2acbf5b83895f636186c87463ab1 (patch) | |
tree | a3dcf26bcd3f05994df22cd359b2b4ac6503da55 /test/util/fuchsia_capability_util.cc | |
parent | a50596874a4971167f97a05181363e91292a2885 (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.cc | 54 |
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 |