Skip to content

Commit

Permalink
getdents size argument must fit in int32.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 632222885
  • Loading branch information
nlacasse authored and gvisor-bot committed May 13, 2024
1 parent d63c258 commit 690dd23
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
5 changes: 3 additions & 2 deletions pkg/sentry/syscalls/linux/sys_getdents.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const DirentStructBytesWithoutName = 8 + 8 + 2 + 1 + 1
func getdents(t *kernel.Task, args arch.SyscallArguments, isGetdents64 bool) (uintptr, *kernel.SyscallControl, error) {
fd := args[0].Int()
addr := args[1].Pointer()
size := int(args[2].Uint())
size := args[2].Int()

if size < DirentStructBytesWithoutName {
return 0, nil, linuxerr.EINVAL
}
Expand All @@ -64,7 +65,7 @@ func getdents(t *kernel.Task, args arch.SyscallArguments, isGetdents64 bool) (ui
return 0, nil, err
}

cb := getGetdentsCallback(t, int(allowedSize), size, isGetdents64)
cb := getGetdentsCallback(t, int(allowedSize), int(size), isGetdents64)
err = file.IterDirents(t, cb)
n, _ := t.CopyOutBytes(addr, cb.buf[:cb.copied])

Expand Down
16 changes: 16 additions & 0 deletions test/syscalls/linux/getdents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,22 @@ TYPED_TEST(GetdentsTest, ZeroLengthOutBuffer) {
SyscallFailsWithErrno(EINVAL));
}

// Tests that getdents() fails when called with too large size.
TYPED_TEST(GetdentsTest, TooLargeSize) {
auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path(), O_DIRECTORY));

typename TestFixture::DirentBufferType dirents(100);
// Try one over the limit.
EXPECT_THAT(RetryEINTR(syscall)(this->SyscallNum(), fd.get(), dirents.Data(),
static_cast<uint32_t>(INT32_MAX) + 1),
SyscallFailsWithErrno(EINVAL));
// Try way over the limit.
EXPECT_THAT(RetryEINTR(syscall)(this->SyscallNum(), fd.get(), dirents.Data(),
static_cast<uint32_t>(-1)),
SyscallFailsWithErrno(EINVAL));
}

// Some tests using the glibc readdir interface.
TEST(ReaddirTest, OpenDir) {
DIR* dev;
Expand Down

0 comments on commit 690dd23

Please sign in to comment.