diff --git a/pkg/sentry/fsimpl/gofer/regular_file.go b/pkg/sentry/fsimpl/gofer/regular_file.go index 9fd1859b8..663464c78 100644 --- a/pkg/sentry/fsimpl/gofer/regular_file.go +++ b/pkg/sentry/fsimpl/gofer/regular_file.go @@ -648,12 +648,12 @@ func regularFileSeekLocked(ctx context.Context, d *dentry, fdOffset, offset int6 case linux.SEEK_END: offset += size case linux.SEEK_DATA: - if offset > size { + if offset >= size { return 0, linuxerr.ENXIO } // Use offset as specified. case linux.SEEK_HOLE: - if offset > size { + if offset >= size { return 0, linuxerr.ENXIO } offset = size diff --git a/test/runtimes/proctor/lib/python.go b/test/runtimes/proctor/lib/python.go index 668996e57..3be4235a4 100644 --- a/test/runtimes/proctor/lib/python.go +++ b/test/runtimes/proctor/lib/python.go @@ -58,7 +58,6 @@ var exclude = map[string][]string{ "test_fcntl": []string{"TestFcntl.test_fcntl_64_bit"}, // TODO(b/76174079): Un-exclude once this bug is fixed. "test_posix": []string{ - "PosixTester.test_fs_holes", // Fails only with --overlay=none. "PosixTester.test_sched_priority", "PosixTester.test_sched_rr_get_interval", "PosixTester.test_get_and_set_scheduler_and_param", // sched_setparam(2) is not supported. diff --git a/test/syscalls/linux/lseek.cc b/test/syscalls/linux/lseek.cc index dbc21833f..f138a20c1 100644 --- a/test/syscalls/linux/lseek.cc +++ b/test/syscalls/linux/lseek.cc @@ -195,6 +195,25 @@ TEST(LseekTest, EtcPasswdDup) { ASSERT_THAT(lseek(fd3.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(1000)); } +TEST(LseekTest, SeekDataAndSeekHole) { + auto file_name = NewTempAbsPath(); + std::string contents("DEADBEEF"); + ASSERT_NO_ERRNO(CreateWithContents(file_name, contents, 0666)); + auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file_name, O_RDWR)); + + // Not all filesystems support SEEK_DATA and SEEK_HOLE yet. + SKIP_IF(lseek(fd.get(), 0, SEEK_DATA) == -1 && errno == EINVAL); + + int mid = contents.size() / 2, end = contents.size(); + ASSERT_THAT(lseek(fd.get(), mid, SEEK_DATA), SyscallSucceedsWithValue(mid)); + ASSERT_THAT(lseek(fd.get(), mid, SEEK_HOLE), SyscallSucceedsWithValue(end)); + + // "ENXIO whence is SEEK_DATA or SEEK_HOLE, and offset is beyond the end of + // the file" - lseek(2) + ASSERT_THAT(lseek(fd.get(), end, SEEK_DATA), SyscallFailsWithErrno(ENXIO)); + ASSERT_THAT(lseek(fd.get(), end, SEEK_HOLE), SyscallFailsWithErrno(ENXIO)); +} + // TODO(magi): Add tests where we have donated in sockets. } // namespace