diff options
author | Andrei Vagin <avagin@google.com> | 2020-10-31 01:17:29 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-10-31 01:19:40 -0700 |
commit | df88f223bb5474a462da65ede6f266eb52f1b2ef (patch) | |
tree | e01ce7b4c4a27ff498f8b5ce96bf30d0ee2b3bee /test/syscalls/linux | |
parent | 4eb1c87e8033520981cce19dea7cde5f85f07737 (diff) |
net/tcpip: connect to unset loopback address has to return EADDRNOTAVAIL
In the docker container, the ipv6 loopback address is not set,
and connect("::1") has to return ENEADDRNOTAVAIL in this case.
Without this fix, it returns EHOSTUNREACH.
PiperOrigin-RevId: 340002915
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r-- | test/syscalls/linux/BUILD | 18 | ||||
-rw-r--r-- | test/syscalls/linux/socket_ip_unbound.cc | 18 | ||||
-rw-r--r-- | test/syscalls/linux/socket_ip_unbound_netlink.cc | 104 |
3 files changed, 127 insertions, 13 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 88899589d..99f286bfc 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -2884,6 +2884,24 @@ cc_binary( ) cc_binary( + name = "socket_ip_unbound_netlink_test", + testonly = 1, + srcs = [ + "socket_ip_unbound_netlink.cc", + ], + linkstatic = 1, + deps = [ + ":ip_socket_test_util", + ":socket_netlink_route_util", + ":socket_test_util", + "//test/util:capability_util", + gtest, + "//test/util:test_main", + "//test/util:test_util", + ], +) + +cc_binary( name = "socket_domain_test", testonly = 1, srcs = [ diff --git a/test/syscalls/linux/socket_ip_unbound.cc b/test/syscalls/linux/socket_ip_unbound.cc index 8f7ccc868..029f1e872 100644 --- a/test/syscalls/linux/socket_ip_unbound.cc +++ b/test/syscalls/linux/socket_ip_unbound.cc @@ -454,23 +454,15 @@ TEST_P(IPUnboundSocketTest, SetReuseAddr) { INSTANTIATE_TEST_SUITE_P( IPUnboundSockets, IPUnboundSocketTest, - ::testing::ValuesIn(VecCat<SocketKind>(VecCat<SocketKind>( + ::testing::ValuesIn(VecCat<SocketKind>( ApplyVec<SocketKind>(IPv4UDPUnboundSocket, - AllBitwiseCombinations(List<int>{SOCK_DGRAM}, - List<int>{0, - SOCK_NONBLOCK})), + std::vector<int>{0, SOCK_NONBLOCK}), ApplyVec<SocketKind>(IPv6UDPUnboundSocket, - AllBitwiseCombinations(List<int>{SOCK_DGRAM}, - List<int>{0, - SOCK_NONBLOCK})), + std::vector<int>{0, SOCK_NONBLOCK}), ApplyVec<SocketKind>(IPv4TCPUnboundSocket, - AllBitwiseCombinations(List<int>{SOCK_STREAM}, - List<int>{0, - SOCK_NONBLOCK})), + std::vector{0, SOCK_NONBLOCK}), ApplyVec<SocketKind>(IPv6TCPUnboundSocket, - AllBitwiseCombinations(List<int>{SOCK_STREAM}, - List<int>{ - 0, SOCK_NONBLOCK})))))); + std::vector{0, SOCK_NONBLOCK})))); } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ip_unbound_netlink.cc b/test/syscalls/linux/socket_ip_unbound_netlink.cc new file mode 100644 index 000000000..6036bfcaf --- /dev/null +++ b/test/syscalls/linux/socket_ip_unbound_netlink.cc @@ -0,0 +1,104 @@ +// Copyright 2019 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. + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> + +#include <cstdio> +#include <cstring> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_netlink_route_util.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/capability_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +// Test fixture for tests that apply to pairs of IP sockets. +using IPv6UnboundSocketTest = SimpleSocketTest; + +TEST_P(IPv6UnboundSocketTest, ConnectToBadLocalAddress_NoRandomSave) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); + + // TODO(gvisor.dev/issue/4595): Addresses on net devices are not saved + // across save/restore. + DisableSave ds; + + // Delete the loopback address from the loopback interface. + Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink()); + EXPECT_NO_ERRNO(LinkDelLocalAddr(loopback_link.index, AF_INET6, + /*prefixlen=*/128, &in6addr_loopback, + sizeof(in6addr_loopback))); + Cleanup defer_addr_removal = + Cleanup([loopback_link = std::move(loopback_link)] { + EXPECT_NO_ERRNO(LinkAddLocalAddr(loopback_link.index, AF_INET6, + /*prefixlen=*/128, &in6addr_loopback, + sizeof(in6addr_loopback))); + }); + + TestAddress addr = V6Loopback(); + reinterpret_cast<sockaddr_in6*>(&addr.addr)->sin6_port = 65535; + auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + EXPECT_THAT(connect(sock->get(), reinterpret_cast<sockaddr*>(&addr.addr), + addr.addr_len), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +INSTANTIATE_TEST_SUITE_P(IPUnboundSockets, IPv6UnboundSocketTest, + ::testing::ValuesIn(std::vector<SocketKind>{ + IPv6UDPUnboundSocket(0), + IPv6TCPUnboundSocket(0)})); + +using IPv4UnboundSocketTest = SimpleSocketTest; + +TEST_P(IPv4UnboundSocketTest, ConnectToBadLocalAddress_NoRandomSave) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); + + // TODO(gvisor.dev/issue/4595): Addresses on net devices are not saved + // across save/restore. + DisableSave ds; + + // Delete the loopback address from the loopback interface. + Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink()); + struct in_addr laddr; + laddr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_NO_ERRNO(LinkDelLocalAddr(loopback_link.index, AF_INET, + /*prefixlen=*/8, &laddr, sizeof(laddr))); + Cleanup defer_addr_removal = Cleanup( + [loopback_link = std::move(loopback_link), addr = std::move(laddr)] { + EXPECT_NO_ERRNO(LinkAddLocalAddr(loopback_link.index, AF_INET, + /*prefixlen=*/8, &addr, sizeof(addr))); + }); + TestAddress addr = V4Loopback(); + reinterpret_cast<sockaddr_in*>(&addr.addr)->sin_port = 65535; + auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + EXPECT_THAT(connect(sock->get(), reinterpret_cast<sockaddr*>(&addr.addr), + addr.addr_len), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +INSTANTIATE_TEST_SUITE_P(IPUnboundSockets, IPv4UnboundSocketTest, + ::testing::ValuesIn(std::vector<SocketKind>{ + IPv4UDPUnboundSocket(0), + IPv4TCPUnboundSocket(0)})); + +} // namespace testing +} // namespace gvisor |