From 6a4b34e541ef6206d483f8561966107215beb487 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Tue, 23 Jun 2026 21:41:55 +0200 Subject: [PATCH 1/2] Avoid overflow in remote read bounds checks --- cpp/src/remote_handle.cpp | 9 +++++++-- cpp/tests/test_remote_handle.cpp | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cpp/src/remote_handle.cpp b/cpp/src/remote_handle.cpp index 271bf4eb89..f6a67c3d24 100644 --- a/cpp/src/remote_handle.cpp +++ b/cpp/src/remote_handle.cpp @@ -178,6 +178,11 @@ void setup_range_request_impl(CurlHandle& curl, std::size_t file_offset, std::si curl.setopt(CURLOPT_RANGE, byte_range.c_str()); } +bool is_read_out_of_bounds(std::size_t file_offset, std::size_t size, std::size_t nbytes) noexcept +{ + return file_offset > nbytes || size > nbytes - file_offset; +} + /** * @brief Whether the given URL is compatible with the S3 endpoint (including the credential-based * access and presigned URL) which uses HTTP/HTTPS. @@ -739,7 +744,7 @@ std::size_t RemoteHandle::read(void* buf, std::size_t size, std::size_t file_off if (size == 0) { return 0; } - if (file_offset + size > _nbytes) { + if (is_read_out_of_bounds(file_offset, size, _nbytes)) { std::stringstream ss; ss << "cannot read " << file_offset << "+" << size << " bytes into a " << _nbytes << " bytes file (" << _endpoint->str() << ")"; @@ -835,7 +840,7 @@ std::future RemoteHandle::pread(void* buf, "device-memory buffers.", std::invalid_argument); KVIKIO_EXPECT(task_size > 0, "`task_size` must be positive", std::invalid_argument); - if (file_offset + size > _nbytes) { + if (is_read_out_of_bounds(file_offset, size, _nbytes)) { std::stringstream ss; ss << "cannot read " << file_offset << "+" << size << " bytes into a " << _nbytes << " bytes file (" << _endpoint->str() << ")"; diff --git a/cpp/tests/test_remote_handle.cpp b/cpp/tests/test_remote_handle.cpp index 1ecacad025..bd7720bc1a 100644 --- a/cpp/tests/test_remote_handle.cpp +++ b/cpp/tests/test_remote_handle.cpp @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -173,6 +174,21 @@ TEST_F(RemoteHandleTest, read_zero_size_returns_without_range_request) EXPECT_EQ(endpoint_ptr->range_request_calls, 0); } +TEST_F(RemoteHandleTest, read_overflowing_range_throws_without_range_request) +{ + auto endpoint = std::make_unique(); + auto* endpoint_ptr = endpoint.get(); + kvikio::RemoteHandle remote_handle(std::move(endpoint), endpoint_ptr->file_size); + + std::vector output(1); + auto constexpr file_offset = std::numeric_limits::max() - 1; + auto constexpr size = std::size_t{4}; + EXPECT_THAT([&] { remote_handle.read(output.data(), size, file_offset); }, + ThrowsMessage(HasSubstr("cannot read "))); + EXPECT_EQ(endpoint_ptr->setopt_calls, 0); + EXPECT_EQ(endpoint_ptr->range_request_calls, 0); +} + TEST_F(RemoteHandleTest, test_s3_url) { kvikio::test::EnvVarContext env_var_ctx{{"AWS_DEFAULT_REGION", "my_aws_default_region"}, From cc53351f24b68047a9531e4ab88b539a9d8dcfda Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Tue, 21 Jul 2026 06:28:17 +0200 Subject: [PATCH 2/2] Use canonical copyright notices --- cpp/src/remote_handle.cpp | 2 +- cpp/tests/test_remote_handle.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/src/remote_handle.cpp b/cpp/src/remote_handle.cpp index a0dfd5e156..02ac5aa91f 100644 --- a/cpp/src/remote_handle.cpp +++ b/cpp/src/remote_handle.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ diff --git a/cpp/tests/test_remote_handle.cpp b/cpp/tests/test_remote_handle.cpp index 72c8eaeace..a264ed4e6b 100644 --- a/cpp/tests/test_remote_handle.cpp +++ b/cpp/tests/test_remote_handle.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */