Fix EOF handling for splice.

Also, add corresponding EOF tests for splice/sendfile.

Discovered by syzkaller.

PiperOrigin-RevId: 328975990
This commit is contained in:
Dean Deng
2020-08-28 11:28:28 -07:00
committed by gVisor bot
parent b3ff31d041
commit 8b9cb36d1c
3 changed files with 39 additions and 1 deletions
+6 -1
View File
@@ -141,9 +141,14 @@ func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
inOffset += n
}
default:
panic("not possible")
panic("at least one end of splice must be a pipe")
}
if n == 0 && err == io.EOF {
// We reached the end of the file. Eat the error and exit the loop.
err = nil
break
}
if n != 0 || err != syserror.ErrWouldBlock || nonBlock {
break
}
+16
View File
@@ -533,6 +533,22 @@ TEST(SendFileTest, SendPipeWouldBlock) {
SyscallFailsWithErrno(EWOULDBLOCK));
}
TEST(SendFileTest, SendPipeEOF) {
// Create and open an empty input file.
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
const FileDescriptor inf =
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDONLY));
// Setup the output named pipe.
int fds[2];
ASSERT_THAT(pipe2(fds, O_NONBLOCK), SyscallSucceeds());
const FileDescriptor rfd(fds[0]);
const FileDescriptor wfd(fds[1]);
EXPECT_THAT(sendfile(wfd.get(), inf.get(), nullptr, 123),
SyscallSucceedsWithValue(0));
}
TEST(SendFileTest, SendPipeBlocks) {
// Create temp file.
constexpr char kData[] =
+17
View File
@@ -298,6 +298,23 @@ TEST(SpliceTest, ToPipe) {
EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0);
}
TEST(SpliceTest, ToPipeEOF) {
// Create and open an empty input file.
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
const FileDescriptor in_fd =
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDONLY));
// Create a new pipe.
int fds[2];
ASSERT_THAT(pipe(fds), SyscallSucceeds());
const FileDescriptor rfd(fds[0]);
const FileDescriptor wfd(fds[1]);
// Splice from the empty file to the pipe.
EXPECT_THAT(splice(in_fd.get(), nullptr, wfd.get(), nullptr, 123, 0),
SyscallSucceedsWithValue(0));
}
TEST(SpliceTest, ToPipeOffset) {
// Open the input file.
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());