summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorLi Qiang <pangpei.lq@antfin.com>2019-04-09 14:56:04 -0700
committerShentubot <shentubot@google.com>2019-04-09 14:57:05 -0700
commitb3b140ea4f9e1b632463cbf83c97f58464eceeac (patch)
tree71dbeb07f58aba6b9494ad6e67765f75f2a294bd /pkg
parent93b3c9b76c16104cbb5cc55b6f2339cb43c356b5 (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.go22
-rw-r--r--pkg/sentry/syscalls/linux/sys_file.go4
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 {