gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/util/fuchsia_capability_util.cc (about) 1 // Copyright 2021 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifdef __Fuchsia__ 16 17 #include <netinet/if_ether.h> 18 #include <netinet/in.h> 19 #include <sys/socket.h> 20 21 #include "test/util/socket_util.h" 22 23 namespace gvisor { 24 namespace testing { 25 26 // On Linux, access to raw IP and packet socket is controlled by a single 27 // capability (CAP_NET_RAW). However on Fuchsia, access to raw IP and packet 28 // sockets are controlled by separate capabilities/protocols. 29 30 namespace { 31 32 PosixErrorOr<bool> HaveSocketCapability(int domain, int type, int protocol) { 33 // Fuchsia does not have a platform supported way to check the protocols made 34 // available to a sandbox. As a workaround, simply try to create the specified 35 // socket and assume no access if we get a no permissions error. 36 auto s = Socket(domain, type, protocol); 37 if (s.ok()) { 38 return true; 39 } 40 if (s.error().errno_value() == EPERM) { 41 return false; 42 } 43 return s.error(); 44 } 45 46 } // namespace 47 48 PosixErrorOr<bool> HaveRawIPSocketCapability() { 49 static PosixErrorOr<bool> result(false); 50 static std::once_flag once; 51 52 std::call_once(once, [&]() { 53 result = HaveSocketCapability(AF_INET, SOCK_RAW, IPPROTO_UDP); 54 }); 55 56 return result; 57 } 58 59 PosixErrorOr<bool> HavePacketSocketCapability() { 60 static PosixErrorOr<bool> result(false); 61 static std::once_flag once; 62 63 std::call_once(once, [&]() { 64 result = HaveSocketCapability(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 65 }); 66 67 return result; 68 } 69 70 } // namespace testing 71 } // namespace gvisor 72 73 #endif // __Fuchsia__