diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index 356b822376..2ecceec59a 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -2745,10 +2745,12 @@ func setSockOptPacket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i pme = &packetmmap.Endpoint{} } opts := ep.GetPacketMMapOpts(&req, true /* isRx */) - if err := pme.Init(t, opts); err != nil { - return syserr.FromError(err) + if opts.Req.TpFrameNr != 0 || opts.Req.TpBlockNr != 0 { + if err := pme.Init(t, opts); err != nil { + return syserr.FromError(err) + } + ep.SetPacketMMapEndpoint(pme) } - ep.SetPacketMMapEndpoint(pme) } else { return syserr.ErrNotSupported } diff --git a/test/syscalls/linux/packet_mmap.cc b/test/syscalls/linux/packet_mmap.cc index 1e336aacfa..d9ba448c15 100644 --- a/test/syscalls/linux/packet_mmap.cc +++ b/test/syscalls/linux/packet_mmap.cc @@ -257,6 +257,32 @@ TEST(PacketMmapTest, FillBlocks) { EXPECT_STREQ((char*)(hdr) + hdr->tp_net, kNewMessage.c_str()); } +TEST(PacketMmapTest, ZeroSizeRing) { + if (!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))) { + ASSERT_THAT(socket(AF_PACKET, SOCK_RAW, 0), SyscallFailsWithErrno(EPERM)); + GTEST_SKIP() << "Missing packet socket capability"; + } + sockaddr_ll bind_addr = { + .sll_family = AF_PACKET, + .sll_protocol = htons(ETH_P_IP), + .sll_ifindex = ASSERT_NO_ERRNO_AND_VALUE(GetLoopbackIndex()), + .sll_halen = ETH_ALEN, + }; + FileDescriptor mmap_sock = + ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_PACKET, SOCK_DGRAM, 0)); + + tpacket_req req = {}; + ASSERT_NO_ERRNO_AND_VALUE(MakePacketMmapRing( + mmap_sock.get(), reinterpret_cast(&bind_addr), + sizeof(bind_addr), &req)); + + std::string kMessage = "123abc"; + ASSERT_THAT( + sendto(mmap_sock.get(), kMessage.c_str(), kMessage.size(), 0 /* flags */, + reinterpret_cast(&bind_addr), sizeof(bind_addr)), + SyscallSucceeds()); +} + TEST(PacketMmapTest, ConcurrentReadWrite) { if (!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))) { ASSERT_THAT(socket(AF_PACKET, SOCK_RAW, 0), SyscallFailsWithErrno(EPERM));