summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2019-02-25 12:16:44 -0800
committerShentubot <shentubot@google.com>2019-02-25 12:17:46 -0800
commit10426e0f31e427e90e69fee83f199ea521b8fe3d (patch)
tree377e4d2f38e196bcf26ee5276e3471e9c0c4da40
parentc14a1a161869804af5ae2f1f73fd8eeb135ff043 (diff)
Handle invalid offset in sendfile(2)
PiperOrigin-RevId: 235578698 Change-Id: I608ff5e25eac97f6e1bda058511c1f82b0e3b736
-rw-r--r--pkg/sentry/syscalls/linux/sys_file.go9
-rw-r--r--test/syscalls/linux/sendfile.cc19
2 files changed, 25 insertions, 3 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go
index 7ad0c9517..cf6fdc190 100644
--- a/pkg/sentry/syscalls/linux/sys_file.go
+++ b/pkg/sentry/syscalls/linux/sys_file.go
@@ -2022,7 +2022,6 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
}
// Setup for sending data.
- var offset uint64
var n int64
var err error
w := &fs.FileWriter{t, outFile}
@@ -2034,14 +2033,18 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
return 0, nil, syserror.ESPIPE
}
// Copy in the offset.
+ var offset int64
if _, err := t.CopyIn(offsetAddr, &offset); err != nil {
return 0, nil, err
}
+ if offset < 0 {
+ return 0, nil, syserror.EINVAL
+ }
// Send data using Preadv.
- r := io.NewSectionReader(&fs.FileReader{t, inFile}, int64(offset), count)
+ r := io.NewSectionReader(&fs.FileReader{t, inFile}, offset, count)
n, err = io.Copy(w, r)
// Copy out the new offset.
- if _, err := t.CopyOut(offsetAddr, n+int64(offset)); err != nil {
+ if _, err := t.CopyOut(offsetAddr, n+offset); err != nil {
return 0, nil, err
}
// If we don't have a provided offset.
diff --git a/test/syscalls/linux/sendfile.cc b/test/syscalls/linux/sendfile.cc
index 92b7b9478..15fd01ff0 100644
--- a/test/syscalls/linux/sendfile.cc
+++ b/test/syscalls/linux/sendfile.cc
@@ -46,6 +46,25 @@ TEST(SendFileTest, SendZeroBytes) {
SyscallSucceedsWithValue(0));
}
+TEST(SendFileTest, InvalidOffset) {
+ // Create temp files.
+ const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
+ const TempPath out_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
+
+ // Open the input file as read only.
+ const FileDescriptor inf =
+ ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDONLY));
+
+ // Open the output file as write only.
+ const FileDescriptor outf =
+ ASSERT_NO_ERRNO_AND_VALUE(Open(out_file.path(), O_WRONLY));
+
+ // Send data and verify that sendfile returns the correct value.
+ off_t offset = -1;
+ EXPECT_THAT(sendfile(outf.get(), inf.get(), &offset, 0),
+ SyscallFailsWithErrno(EINVAL));
+}
+
TEST(SendFileTest, SendTrivially) {
// Create temp files.
constexpr char kData[] = "To be, or not to be, that is the question:";