mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
tun: reject packets larger MTU
Reported-by: syzbot+d82dbadde2cbe70eb6dd@syzkaller.appspotmail.com PiperOrigin-RevId: 429508995
This commit is contained in:
@@ -143,6 +143,13 @@ func (fd *tunFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.Wri
|
||||
if src.NumBytes() == 0 {
|
||||
return 0, unix.EINVAL
|
||||
}
|
||||
mtu, err := fd.device.MTU()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if int64(mtu) < src.NumBytes() {
|
||||
return 0, unix.EMSGSIZE
|
||||
}
|
||||
data := make([]byte, src.NumBytes())
|
||||
if _, err := src.CopyIn(ctx, data); err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -166,6 +166,20 @@ func attachOrCreateNIC(s *stack.Stack, name, prefix string, linkCaps stack.LinkE
|
||||
}
|
||||
}
|
||||
|
||||
// MTU returns the tun enpoint MTU (maximum transmission unit).
|
||||
func (d *Device) MTU() (uint32, error) {
|
||||
d.mu.RLock()
|
||||
endpoint := d.endpoint
|
||||
d.mu.RUnlock()
|
||||
if endpoint == nil {
|
||||
return 0, linuxerr.EBADFD
|
||||
}
|
||||
if !endpoint.IsAttached() {
|
||||
return 0, linuxerr.EIO
|
||||
}
|
||||
return endpoint.MTU(), nil
|
||||
}
|
||||
|
||||
// Write inject one inbound packet to the network interface.
|
||||
func (d *Device) Write(data []byte) (int64, error) {
|
||||
d.mu.RLock()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
@@ -414,6 +415,34 @@ TEST_F(TuntapTest, PingKernel) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TuntapTest, LargeWritesFailWithEMSGSIZE) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
|
||||
|
||||
const auto& [fd, link] = ASSERT_NO_ERRNO_AND_VALUE(OpenAndAttachTunTap(
|
||||
kTapName, kTapIPAddr, true /* tap */, false /* no_pi */));
|
||||
|
||||
ping_pkt ping_req =
|
||||
CreatePingPacket(kMacB, kTapPeerIPAddr, kMacA, kTapIPAddr);
|
||||
std::string arp_rep =
|
||||
CreateArpPacket(kMacB, kTapPeerIPAddr, kMacA, kTapIPAddr);
|
||||
|
||||
constexpr int kBufSize = 4096;
|
||||
std::vector<char> buf(kBufSize);
|
||||
struct iovec iov[2] = {
|
||||
{
|
||||
.iov_base = &ping_req,
|
||||
.iov_len = sizeof(ping_req),
|
||||
},
|
||||
{
|
||||
.iov_base = buf.data(),
|
||||
.iov_len = kBufSize,
|
||||
},
|
||||
};
|
||||
|
||||
// A packet is large than MTU which is 1500 by default..
|
||||
EXPECT_THAT(writev(fd.get(), iov, 2), SyscallFailsWithErrno(EMSGSIZE));
|
||||
}
|
||||
|
||||
TEST_F(TuntapTest, SendUdpTriggersArpResolution) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user