mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Handle 0 sized writes to /dev/net/tun.
Reported-by: syzbot+f8718f94cb39f7d7e58f@syzkaller.appspotmail.com PiperOrigin-RevId: 422944054
This commit is contained in:
@@ -20,5 +20,6 @@ go_library(
|
||||
"//pkg/tcpip/link/tun",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package tundev
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
@@ -139,6 +140,9 @@ func (fd *tunFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int6
|
||||
|
||||
// Write implements vfs.FileDescriptionImpl.Write.
|
||||
func (fd *tunFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) {
|
||||
if src.NumBytes() == 0 {
|
||||
return 0, unix.EINVAL
|
||||
}
|
||||
data := make([]byte, src.NumBytes())
|
||||
if _, err := src.CopyIn(ctx, data); err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -37,5 +37,6 @@ go_library(
|
||||
"//pkg/tcpip/link/tun",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package dev
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
@@ -131,6 +132,9 @@ func (n *netTunFileOperations) Ioctl(ctx context.Context, file *fs.File, io user
|
||||
|
||||
// Write implements fs.FileOperations.Write.
|
||||
func (n *netTunFileOperations) Write(ctx context.Context, file *fs.File, src usermem.IOSequence, offset int64) (int64, error) {
|
||||
if src.NumBytes() == 0 {
|
||||
return 0, unix.EINVAL
|
||||
}
|
||||
data := make([]byte, src.NumBytes())
|
||||
if _, err := src.CopyIn(ctx, data); err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -269,6 +269,17 @@ TEST_F(TuntapTest, InvalidReadWrite) {
|
||||
EXPECT_THAT(write(fd.get(), buf, sizeof(buf)), SyscallFailsWithErrno(EBADFD));
|
||||
}
|
||||
|
||||
TEST_F(TuntapTest, ZeroWrite) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
|
||||
|
||||
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(kDevNetTun, O_RDWR));
|
||||
struct ifreq ifr_set = {};
|
||||
ifr_set.ifr_flags = IFF_TUN | IFF_NO_PI;
|
||||
strncpy(ifr_set.ifr_name, kTunName, IFNAMSIZ);
|
||||
EXPECT_THAT(ioctl(fd.get(), TUNSETIFF, &ifr_set), SyscallSucceeds());
|
||||
EXPECT_THAT(write(fd.get(), nullptr, 0), SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
TEST_F(TuntapTest, WriteToDownDevice) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user