From b413d78c27dba6cc7caef328583e5c7e66fcb18c Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 17 Feb 2022 22:38:23 -0800 Subject: [PATCH] sendfile: limit a buffer size When sendfile is called for two non-pipe file descriptors, we use a buffer to read data from one fd and write it to another one. The buffer size has to be limited to avoid large memory allocations and long delays. In Linux, the buffer size is limited by a size of an internl pipe. Here, we repeat this behavior. Reported-by: syzbot+d82dbadde2cbe70eb6dd@syzkaller.appspotmail.com PiperOrigin-RevId: 429484781 --- pkg/sentry/syscalls/linux/vfs2/splice.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pkg/sentry/syscalls/linux/vfs2/splice.go b/pkg/sentry/syscalls/linux/vfs2/splice.go index c14dd0f38..e7ebdbebc 100644 --- a/pkg/sentry/syscalls/linux/vfs2/splice.go +++ b/pkg/sentry/syscalls/linux/vfs2/splice.go @@ -380,8 +380,20 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc } } else { // Read inFile to buffer, then write the contents to outFile. - buf := make([]byte, count) + // + // The buffer size has to be limited to avoid large memory + // allocations and long delays. In Linux, the buffer size is + // limited by a size of an internl pipe. Here, we repeat this + // behavior. + bufSize := count + if bufSize > pipe.MaximumPipeSize { + bufSize = pipe.MaximumPipeSize + } + buf := make([]byte, bufSize) for { + if int64(len(buf)) > count-total { + buf = buf[:count-total] + } var readN int64 if offset != -1 { readN, err = inFile.PRead(t, usermem.BytesIOSequence(buf), offset, vfs.ReadOptions{}) @@ -423,7 +435,6 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc } total += readN - buf = buf[readN:] if total == count { break }