Handle 0 sized writes to /dev/net/tun.

Reported-by: syzbot+f8718f94cb39f7d7e58f@syzkaller.appspotmail.com
PiperOrigin-RevId: 422944054
This commit is contained in:
Ayush Ranjan
2022-01-19 17:41:04 -08:00
committed by gVisor bot
parent 2e29cfc81d
commit 5fb5276323
5 changed files with 21 additions and 0 deletions
+1
View File
@@ -20,5 +20,6 @@ go_library(
"//pkg/tcpip/link/tun",
"//pkg/usermem",
"//pkg/waiter",
"@org_golang_x_sys//unix:go_default_library",
],
)
+4
View File
@@ -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
+1
View File
@@ -37,5 +37,6 @@ go_library(
"//pkg/tcpip/link/tun",
"//pkg/usermem",
"//pkg/waiter",
"@org_golang_x_sys//unix:go_default_library",
],
)
+4
View File
@@ -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
+11
View File
@@ -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)));