mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix EOF handling for splice.
Also, add corresponding EOF tests for splice/sendfile. Discovered by syzkaller. PiperOrigin-RevId: 328975990
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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[] =
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user