getdents size argument must fit in int32.

PiperOrigin-RevId: 633251720
This commit is contained in:
Nicolas Lacasse
2024-05-13 10:20:13 -07:00
committed by gVisor bot
parent d63c258f43
commit 03b5480f8c
2 changed files with 19 additions and 2 deletions
+3 -2
View File
@@ -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
}
@@ -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])
+16
View File
@@ -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;