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 | |
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')
-rw-r--r-- | test/util/BUILD | 1 | ||||
-rw-r--r-- | test/util/capability_util.h | 20 | ||||
-rw-r--r-- | test/util/fuchsia_capability_util.cc | 54 | ||||
-rw-r--r-- | test/util/fuchsia_capability_util.h | 41 | ||||
-rw-r--r-- | test/util/linux_capability_util.cc | 8 |
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. |