diff options
author | Li Qiang <pangpei.lq@antfin.com> | 2019-04-09 14:56:04 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-04-09 14:57:05 -0700 |
commit | b3b140ea4f9e1b632463cbf83c97f58464eceeac (patch) | |
tree | 71dbeb07f58aba6b9494ad6e67765f75f2a294bd /pkg | |
parent | 93b3c9b76c16104cbb5cc55b6f2339cb43c356b5 (diff) |
syscalls: sendfile: limit the count to MAX_RW_COUNT
From sendfile spec and also the linux kernel code, we should
limit the count arg to 'MAX_RW_COUNT'. This patch export
'MAX_RW_COUNT' in kernel pkg and use it in the implementation
of sendfile syscall.
Signed-off-by: Li Qiang <pangpei.lq@antfin.com>
Change-Id: I1086fec0685587116984555abd22b07ac233fbd2
PiperOrigin-RevId: 242745831
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/sentry/kernel/task_usermem.go | 22 | ||||
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_file.go | 4 |
2 files changed, 15 insertions, 11 deletions
diff --git a/pkg/sentry/kernel/task_usermem.go b/pkg/sentry/kernel/task_usermem.go index c8e973bd5..cb68799d3 100644 --- a/pkg/sentry/kernel/task_usermem.go +++ b/pkg/sentry/kernel/task_usermem.go @@ -22,10 +22,10 @@ import ( "gvisor.googlesource.com/gvisor/pkg/syserror" ) -// _MAX_RW_COUNT is the maximum size in bytes of a single read or write. +// MAX_RW_COUNT is the maximum size in bytes of a single read or write. // Reads and writes that exceed this size may be silently truncated. // (Linux: include/linux/fs.h:MAX_RW_COUNT) -var _MAX_RW_COUNT = int(usermem.Addr(math.MaxInt32).RoundDown()) +var MAX_RW_COUNT = int(usermem.Addr(math.MaxInt32).RoundDown()) // Activate ensures that the task has an active address space. func (t *Task) Activate() { @@ -187,9 +187,9 @@ func (t *Task) CopyOutIovecs(addr usermem.Addr, src usermem.AddrRangeSeq) error // - If any AddrRange would include addresses outside the application address // range, CopyInIovecs returns EFAULT. // -// - The combined length of all AddrRanges is limited to _MAX_RW_COUNT. If the +// - The combined length of all AddrRanges is limited to MAX_RW_COUNT. If the // combined length of all AddrRanges would otherwise exceed this amount, ranges -// beyond _MAX_RW_COUNT are silently truncated. +// beyond MAX_RW_COUNT are silently truncated. // // Preconditions: As for usermem.IO.CopyIn. The caller must be running on the // task goroutine. t's AddressSpace must be active. @@ -228,7 +228,7 @@ func (t *Task) CopyInIovecs(addr usermem.Addr, numIovecs int) (usermem.AddrRange if numIovecs == 1 { // Special case to avoid allocating dst. - return usermem.AddrRangeSeqOf(ar).TakeFirst(_MAX_RW_COUNT), nil + return usermem.AddrRangeSeqOf(ar).TakeFirst(MAX_RW_COUNT), nil } dst = append(dst, ar) @@ -239,11 +239,11 @@ func (t *Task) CopyInIovecs(addr usermem.Addr, numIovecs int) (usermem.AddrRange return usermem.AddrRangeSeq{}, syserror.ENOSYS } - // Truncate to _MAX_RW_COUNT. + // Truncate to MAX_RW_COUNT. var total uint64 for i := range dst { dstlen := uint64(dst[i].Length()) - if rem := uint64(_MAX_RW_COUNT) - total; rem < dstlen { + if rem := uint64(MAX_RW_COUNT) - total; rem < dstlen { dst[i].End -= usermem.Addr(dstlen - rem) dstlen = rem } @@ -256,16 +256,16 @@ func (t *Task) CopyInIovecs(addr usermem.Addr, numIovecs int) (usermem.AddrRange // SingleIOSequence returns a usermem.IOSequence representing [addr, // addr+length) in t's address space. If this contains addresses outside the // application address range, it returns EFAULT. If length exceeds -// _MAX_RW_COUNT, the range is silently truncated. +// MAX_RW_COUNT, the range is silently truncated. // // SingleIOSequence is analogous to Linux's // lib/iov_iter.c:import_single_range(). (Note that the non-vectorized read and // write syscalls in Linux do not use import_single_range(). However they check // access_ok() in fs/read_write.c:vfs_read/vfs_write, and overflowing address -// ranges are truncated to _MAX_RW_COUNT by fs/read_write.c:rw_verify_area().) +// ranges are truncated to MAX_RW_COUNT by fs/read_write.c:rw_verify_area().) func (t *Task) SingleIOSequence(addr usermem.Addr, length int, opts usermem.IOOpts) (usermem.IOSequence, error) { - if length > _MAX_RW_COUNT { - length = _MAX_RW_COUNT + if length > MAX_RW_COUNT { + length = MAX_RW_COUNT } ar, ok := t.MemoryManager().CheckIORange(addr, int64(length)) if !ok { diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 5a874d935..d2d351449 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -2002,6 +2002,10 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc return 0, nil, syserror.EINVAL } + if count > int64(kernel.MAX_RW_COUNT) { + count = int64(kernel.MAX_RW_COUNT) + } + // Get files. outFile := t.FDMap().GetFile(outFD) if outFile == nil { |