From 0f5c1f5eafb2cc67a9148bdf346b6083e5a8480c Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Thu, 17 Jun 2021 13:33:12 -0700 Subject: raw sockets: don't overwrite destination address Also makes the behavior of raw sockets WRT fragmentation clearer, and makes the ICMPv4 header-length check explicit. Fixes #3160. PiperOrigin-RevId: 380033450 --- test/syscalls/linux/raw_socket_hdrincl.cc | 16 +++++++--------- test/syscalls/linux/raw_socket_icmp.cc | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'test/syscalls/linux') diff --git a/test/syscalls/linux/raw_socket_hdrincl.cc b/test/syscalls/linux/raw_socket_hdrincl.cc index fac473114..4611b6283 100644 --- a/test/syscalls/linux/raw_socket_hdrincl.cc +++ b/test/syscalls/linux/raw_socket_hdrincl.cc @@ -281,9 +281,6 @@ TEST_F(RawHDRINCL, SendAndReceive) { // Send and receive a packet where the sendto address is not the same as the // provided destination. TEST_F(RawHDRINCL, SendAndReceiveDifferentAddress) { - // FIXME(gvisor.dev/issue/3160): Test currently flaky. - SKIP_IF(true); - int port = 40000; if (!IsRunningOnGvisor()) { port = static_cast(ASSERT_NO_ERRNO_AND_VALUE( @@ -301,18 +298,20 @@ TEST_F(RawHDRINCL, SendAndReceiveDifferentAddress) { ASSERT_TRUE( FillPacket(packet, sizeof(packet), port, kPayload, sizeof(kPayload))); // Overwrite the IP destination address with an IP we can't get to. + constexpr int32_t kUnreachable = 42; struct iphdr iphdr = {}; memcpy(&iphdr, packet, sizeof(iphdr)); - iphdr.daddr = 42; + iphdr.daddr = kUnreachable; memcpy(packet, &iphdr, sizeof(iphdr)); + // Send to localhost via loopback. socklen_t addrlen = sizeof(addr_); ASSERT_NO_FATAL_FAILURE(sendto(socket_, &packet, sizeof(packet), 0, reinterpret_cast(&addr_), addrlen)); - // Receive the payload, since sendto should replace the bad destination with - // localhost. + // Receive the payload. Despite an unreachable destination address, sendto + // should have sent the packet through loopback. char recv_buf[sizeof(packet)]; struct sockaddr_in src; socklen_t src_size = sizeof(src); @@ -330,9 +329,8 @@ TEST_F(RawHDRINCL, SendAndReceiveDifferentAddress) { struct iphdr recv_iphdr = {}; memcpy(&recv_iphdr, recv_buf, sizeof(recv_iphdr)); EXPECT_NE(recv_iphdr.id, 0); - // The destination address should be localhost, not the bad IP we set - // initially. - EXPECT_EQ(absl::gbswap_32(recv_iphdr.daddr), INADDR_LOOPBACK); + // The destination address is kUnreachable despite arriving via loopback. + EXPECT_EQ(recv_iphdr.daddr, kUnreachable); } // Send and receive a packet w/ the IP_HDRINCL option set. diff --git a/test/syscalls/linux/raw_socket_icmp.cc b/test/syscalls/linux/raw_socket_icmp.cc index bd779da92..275996bd3 100644 --- a/test/syscalls/linux/raw_socket_icmp.cc +++ b/test/syscalls/linux/raw_socket_icmp.cc @@ -262,8 +262,8 @@ TEST_F(RawSocketICMPTest, RawAndPingSockets) { } // A raw ICMP socket should be able to send a malformed short ICMP Echo Request, -// while ping socket should not. -// Neither should be able to receieve a short malformed packet. +// while a ping socket should not. Neither should be able to receieve a short +// malformed packet. TEST_F(RawSocketICMPTest, ShortEchoRawAndPingSockets) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); -- cgit v1.2.3