From f7c29fa3e0cb28b7e93bee8f156644cd3365da63 Mon Sep 17 00:00:00 2001 From: Andy Jost Date: Mon, 15 Jun 2026 11:59:27 -0700 Subject: [PATCH] cuda.core: validate IPC buffer import size against mapped extent Reject peer-supplied IPCBufferDescriptor sizes larger than the driver-reported allocation extent before storing buf._size, preventing oversized cuMemcpyAsync lengths on imported buffers (Glasswing V2.2). --- cuda_core/cuda/core/_memory/_ipc.pyx | 15 ++++++++++++++- cuda_core/tests/memory_ipc/test_errors.py | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/cuda_core/cuda/core/_memory/_ipc.pyx b/cuda_core/cuda/core/_memory/_ipc.pyx index 61fd8b086e..94611b590d 100644 --- a/cuda_core/cuda/core/_memory/_ipc.pyx +++ b/cuda_core/cuda/core/_memory/_ipc.pyx @@ -179,7 +179,20 @@ cdef Buffer Buffer_from_ipc_descriptor( ) if not h_ptr: HANDLE_RETURN(get_last_error()) - return Buffer_from_deviceptr_handle(h_ptr, ipc_descriptor.size, mr, ipc_descriptor) + cdef size_t mapped_size = 0 + cdef size_t claimed_size = ipc_descriptor.size + with nogil: + HANDLE_RETURN(cydriver.cuPointerGetAttribute( + &mapped_size, + cydriver.CU_POINTER_ATTRIBUTE_RANGE_SIZE, + as_cu(h_ptr))) + if claimed_size > mapped_size: + h_ptr.reset() + raise ValueError( + f"IPC buffer descriptor size ({claimed_size}) exceeds " + f"mapped allocation extent ({mapped_size} bytes)" + ) + return Buffer_from_deviceptr_handle(h_ptr, claimed_size, mr, ipc_descriptor) # _MemPool IPC Implementation diff --git a/cuda_core/tests/memory_ipc/test_errors.py b/cuda_core/tests/memory_ipc/test_errors.py index 84fb9093e1..f400507136 100644 --- a/cuda_core/tests/memory_ipc/test_errors.py +++ b/cuda_core/tests/memory_ipc/test_errors.py @@ -9,6 +9,7 @@ from helpers.child_processes import child_timeout_sec, kill_subprocesses from cuda.core import Buffer, Device, DeviceMemoryResource, DeviceMemoryResourceOptions +from cuda.core._memory import IPCBufferDescriptor from cuda.core._utils.cuda_utils import CUDAError CHILD_TIMEOUT_SEC = child_timeout_sec() @@ -88,6 +89,25 @@ def child_main(self, pipe, device, mr): pipe[1].put(exc_info) +class TestImportOversizedBufferDescriptorSize(ChildErrorHarness): + """Reject peer-supplied sizes larger than the mapped allocation extent.""" + + def PARENT_ACTION(self, queue): + self.buffer = self.mr.allocate(NBYTES, stream=self.device.default_stream) + payload, _ = self.buffer.ipc_descriptor.__reduce__()[1] + oversized = IPCBufferDescriptor._init(payload, NBYTES * 100) + queue.put(oversized) + + def CHILD_ACTION(self, queue): + oversized = queue.get(timeout=CHILD_TIMEOUT_SEC) + Buffer.from_ipc_descriptor(self.mr, oversized, stream=self.device.default_stream) + + def ASSERT(self, exc_type, exc_msg): + assert exc_type is ValueError + assert "exceeds" in exc_msg + assert "mapped allocation extent" in exc_msg + + class TestAllocFromImportedMr(ChildErrorHarness): """Error when attempting to allocate from an import memory resource."""