diff options
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 5 | ||||
-rw-r--r-- | test/syscalls/linux/udp_socket.cc | 16 |
2 files changed, 21 insertions, 0 deletions
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 56bdf6c34..9bcb918bb 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -487,6 +487,11 @@ func (e *endpoint) write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-c nicID = e.BindNICID } + if to.Port == 0 { + // Port 0 is an invalid port to send to. + return 0, nil, tcpip.ErrInvalidEndpointState + } + dst, netProto, err := e.checkV4MappedLocked(*to) if err != nil { return 0, nil, err diff --git a/test/syscalls/linux/udp_socket.cc b/test/syscalls/linux/udp_socket.cc index bc5bd9218..d65275fd3 100644 --- a/test/syscalls/linux/udp_socket.cc +++ b/test/syscalls/linux/udp_socket.cc @@ -1887,6 +1887,22 @@ TEST_P(UdpSocketTest, GetSocketDetachFilter) { SyscallFailsWithErrno(ENOPROTOOPT)); } +TEST_P(UdpSocketTest, SendToZeroPort) { + char buf[8]; + struct sockaddr_storage addr = InetLoopbackAddr(); + + // Sending to an invalid port should fail. + SetPort(&addr, 0); + EXPECT_THAT(sendto(sock_.get(), buf, sizeof(buf), 0, + reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), + SyscallFailsWithErrno(EINVAL)); + + SetPort(&addr, 1234); + EXPECT_THAT(sendto(sock_.get(), buf, sizeof(buf), 0, + reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), + SyscallSucceedsWithValue(sizeof(buf))); +} + INSTANTIATE_TEST_SUITE_P(AllInetTests, UdpSocketTest, ::testing::Values(AddressFamily::kIpv4, AddressFamily::kIpv6, |