From ae4a34f3ea63d0795b39bcdf0e00073223f222cc Mon Sep 17 00:00:00 2001 From: Github Executorch Date: Wed, 4 Mar 2026 21:13:29 -0800 Subject: [PATCH 1/2] Fix integer overflow in data loader bounds checks Replace `offset + size <= file_size_` with overflow-safe `offset <= file_size_ && size <= file_size_ - offset` across all data loader implementations. The original pattern can silently overflow when offset and size are both large, bypassing the bounds check. Affected files: MmapDataLoader, FileDataLoader, FileDescriptorDataLoader, SharedPtrDataLoader. BufferDataLoader already uses safe overflow detection (c10::add_overflows). Addresses TOB-EXECUTORCH-22. This PR was authored with the assistance of Claude. --- extension/data_loader/file_data_loader.cpp | 4 ++-- extension/data_loader/file_descriptor_data_loader.cpp | 4 ++-- extension/data_loader/mmap_data_loader.cpp | 2 +- extension/data_loader/shared_ptr_data_loader.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extension/data_loader/file_data_loader.cpp b/extension/data_loader/file_data_loader.cpp index 997585aa9d1..f9ada6f5af9 100644 --- a/extension/data_loader/file_data_loader.cpp +++ b/extension/data_loader/file_data_loader.cpp @@ -144,7 +144,7 @@ Result FileDataLoader::load( InvalidState, "Uninitialized"); ET_CHECK_OR_RETURN_ERROR( - offset + size <= file_size_, + offset <= file_size_ && size <= file_size_ - offset, InvalidArgument, "File %s: offset %zu + size %zu > file_size_ %zu", file_name_, @@ -205,7 +205,7 @@ ET_NODISCARD Error FileDataLoader::load_into( InvalidState, "Uninitialized"); ET_CHECK_OR_RETURN_ERROR( - offset + size <= file_size_, + offset <= file_size_ && size <= file_size_ - offset, InvalidArgument, "File %s: offset %zu + size %zu > file_size_ %zu", file_name_, diff --git a/extension/data_loader/file_descriptor_data_loader.cpp b/extension/data_loader/file_descriptor_data_loader.cpp index a57f2ce3640..3732b22c896 100644 --- a/extension/data_loader/file_descriptor_data_loader.cpp +++ b/extension/data_loader/file_descriptor_data_loader.cpp @@ -158,7 +158,7 @@ Result FileDescriptorDataLoader::load( InvalidState, "Uninitialized"); ET_CHECK_OR_RETURN_ERROR( - offset + size <= file_size_, + offset <= file_size_ && size <= file_size_ - offset, InvalidArgument, "File %s: offset %zu + size %zu > file_size_ %zu", file_descriptor_uri_, @@ -219,7 +219,7 @@ ET_NODISCARD Error FileDescriptorDataLoader::load_into( InvalidState, "Uninitialized"); ET_CHECK_OR_RETURN_ERROR( - offset + size <= file_size_, + offset <= file_size_ && size <= file_size_ - offset, InvalidArgument, "File %s: offset %zu + size %zu > file_size_ %zu", file_descriptor_uri_, diff --git a/extension/data_loader/mmap_data_loader.cpp b/extension/data_loader/mmap_data_loader.cpp index 2271d5a3690..2bb0708527b 100644 --- a/extension/data_loader/mmap_data_loader.cpp +++ b/extension/data_loader/mmap_data_loader.cpp @@ -160,7 +160,7 @@ Error MmapDataLoader::validate_input(size_t offset, size_t size) const { InvalidState, "Uninitialized"); ET_CHECK_OR_RETURN_ERROR( - offset + size <= file_size_, + offset <= file_size_ && size <= file_size_ - offset, InvalidArgument, "File %s: offset %zu + size %zu > file_size_ %zu", file_name_, diff --git a/extension/data_loader/shared_ptr_data_loader.h b/extension/data_loader/shared_ptr_data_loader.h index 551ab4d498c..b5dd4142089 100644 --- a/extension/data_loader/shared_ptr_data_loader.h +++ b/extension/data_loader/shared_ptr_data_loader.h @@ -34,7 +34,7 @@ class SharedPtrDataLoader final : public executorch::runtime::DataLoader { size_t size, ET_UNUSED const DataLoader::SegmentInfo& segment_info) const override { ET_CHECK_OR_RETURN_ERROR( - offset + size <= size_, + offset <= size_ && size <= size_ - offset, InvalidArgument, "offset %zu + size %zu > size_ %zu", offset, From 6ebf6a39ae443367622bcf24b52aae1ca40855da Mon Sep 17 00:00:00 2001 From: Github Executorch Date: Thu, 2 Apr 2026 10:48:10 -0700 Subject: [PATCH 2/2] use c10::add_overflows --- extension/data_loader/buffer_data_loader.h | 2 +- extension/data_loader/file_data_loader.cpp | 13 +++++++++---- .../data_loader/file_descriptor_data_loader.cpp | 13 +++++++++---- extension/data_loader/mmap_data_loader.cpp | 7 +++++-- extension/data_loader/shared_ptr_data_loader.h | 7 +++++-- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/extension/data_loader/buffer_data_loader.h b/extension/data_loader/buffer_data_loader.h index 64e26d3dcb8..7f4211546e0 100644 --- a/extension/data_loader/buffer_data_loader.h +++ b/extension/data_loader/buffer_data_loader.h @@ -40,7 +40,7 @@ class BufferDataLoader final : public executorch::runtime::DataLoader { ET_CHECK_OR_RETURN_ERROR( !overflow && total_size <= size_, InvalidArgument, - "offset %zu + size %zu > size_ %zu", + "offset %zu + size %zu > size_ %zu, or overflow detected", offset, size, size_); diff --git a/extension/data_loader/file_data_loader.cpp b/extension/data_loader/file_data_loader.cpp index f9ada6f5af9..bc5c17ef33f 100644 --- a/extension/data_loader/file_data_loader.cpp +++ b/extension/data_loader/file_data_loader.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -143,10 +144,12 @@ Result FileDataLoader::load( fd_ >= 0, InvalidState, "Uninitialized"); + size_t total_size; + bool overflow = c10::add_overflows(offset, size, &total_size); ET_CHECK_OR_RETURN_ERROR( - offset <= file_size_ && size <= file_size_ - offset, + !overflow && total_size <= file_size_, InvalidArgument, - "File %s: offset %zu + size %zu > file_size_ %zu", + "File %s: offset %zu + size %zu > file_size_ %zu, or overflow detected", file_name_, offset, size, @@ -204,10 +207,12 @@ ET_NODISCARD Error FileDataLoader::load_into( fd_ >= 0, InvalidState, "Uninitialized"); + size_t total_size; + bool overflow = c10::add_overflows(offset, size, &total_size); ET_CHECK_OR_RETURN_ERROR( - offset <= file_size_ && size <= file_size_ - offset, + !overflow && total_size <= file_size_, InvalidArgument, - "File %s: offset %zu + size %zu > file_size_ %zu", + "File %s: offset %zu + size %zu > file_size_ %zu, or overflow detected", file_name_, offset, size, diff --git a/extension/data_loader/file_descriptor_data_loader.cpp b/extension/data_loader/file_descriptor_data_loader.cpp index 3732b22c896..3b6423d21cb 100644 --- a/extension/data_loader/file_descriptor_data_loader.cpp +++ b/extension/data_loader/file_descriptor_data_loader.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -157,10 +158,12 @@ Result FileDescriptorDataLoader::load( fd_ >= 0, InvalidState, "Uninitialized"); + size_t total_size; + bool overflow = c10::add_overflows(offset, size, &total_size); ET_CHECK_OR_RETURN_ERROR( - offset <= file_size_ && size <= file_size_ - offset, + !overflow && total_size <= file_size_, InvalidArgument, - "File %s: offset %zu + size %zu > file_size_ %zu", + "File %s: offset %zu + size %zu > file_size_ %zu, or overflow detected", file_descriptor_uri_, offset, size, @@ -218,10 +221,12 @@ ET_NODISCARD Error FileDescriptorDataLoader::load_into( fd_ >= 0, InvalidState, "Uninitialized"); + size_t total_size; + bool overflow = c10::add_overflows(offset, size, &total_size); ET_CHECK_OR_RETURN_ERROR( - offset <= file_size_ && size <= file_size_ - offset, + !overflow && total_size <= file_size_, InvalidArgument, - "File %s: offset %zu + size %zu > file_size_ %zu", + "File %s: offset %zu + size %zu > file_size_ %zu, or overflow detected", file_descriptor_uri_, offset, size, diff --git a/extension/data_loader/mmap_data_loader.cpp b/extension/data_loader/mmap_data_loader.cpp index 2bb0708527b..5d77b67cc59 100644 --- a/extension/data_loader/mmap_data_loader.cpp +++ b/extension/data_loader/mmap_data_loader.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -159,10 +160,12 @@ Error MmapDataLoader::validate_input(size_t offset, size_t size) const { fd_ >= 0, InvalidState, "Uninitialized"); + size_t total_size; + bool overflow = c10::add_overflows(offset, size, &total_size); ET_CHECK_OR_RETURN_ERROR( - offset <= file_size_ && size <= file_size_ - offset, + !overflow && total_size <= file_size_, InvalidArgument, - "File %s: offset %zu + size %zu > file_size_ %zu", + "File %s: offset %zu + size %zu > file_size_ %zu, or overflow detected", file_name_, offset, size, diff --git a/extension/data_loader/shared_ptr_data_loader.h b/extension/data_loader/shared_ptr_data_loader.h index b5dd4142089..78fdc2b7157 100644 --- a/extension/data_loader/shared_ptr_data_loader.h +++ b/extension/data_loader/shared_ptr_data_loader.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -33,10 +34,12 @@ class SharedPtrDataLoader final : public executorch::runtime::DataLoader { size_t offset, size_t size, ET_UNUSED const DataLoader::SegmentInfo& segment_info) const override { + size_t total_size; + bool overflow = c10::add_overflows(offset, size, &total_size); ET_CHECK_OR_RETURN_ERROR( - offset <= size_ && size <= size_ - offset, + !overflow && total_size <= size_, InvalidArgument, - "offset %zu + size %zu > size_ %zu", + "offset %zu + size %zu > size_ %zu, or overflow detected", offset, size, size_);