From a7da9e2be53a0fca60b531cdeb8c4d42f619a9e8 Mon Sep 17 00:00:00 2001 From: Vyron Vasileiadis Date: Sun, 9 Aug 2026 11:18:30 +0300 Subject: [PATCH] cuda.core: reject register() on a non-IPC memory resource MP_register read self._ipc_data._alloc_handle._uuid unconditionally. _ipc_data is None whenever IPC is not enabled, and Cython compiles the chained access without a none check, so the call terminated the process with a segmentation fault instead of raising. No exception reached the caller, so the crash could not be guarded with try. Check is_ipc_enabled first and raise RuntimeError, matching the wording the allocation_handle property already uses. The check runs before the registry insertion, so a rejected registration no longer leaves an entry behind. Closes #2568 Signed-off-by: Vyron Vasileiadis --- cuda_core/cuda/core/_memory/_ipc.pyx | 2 ++ cuda_core/docs/source/release/1.2.0-notes.rst | 8 ++++++++ cuda_core/tests/memory_ipc/test_errors.py | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/cuda_core/cuda/core/_memory/_ipc.pyx b/cuda_core/cuda/core/_memory/_ipc.pyx index f4194b22b0e..3d676856415 100644 --- a/cuda_core/cuda/core/_memory/_ipc.pyx +++ b/cuda_core/cuda/core/_memory/_ipc.pyx @@ -268,6 +268,8 @@ cdef _MemPool MP_register(_MemPool self, uuid): existing = registry.get(uuid) if existing is not None: return existing + if not self.is_ipc_enabled: + raise RuntimeError("Memory resource is not IPC-enabled") assert self.uuid is None or self.uuid == uuid registry[uuid] = self self._ipc_data._alloc_handle._uuid = uuid diff --git a/cuda_core/docs/source/release/1.2.0-notes.rst b/cuda_core/docs/source/release/1.2.0-notes.rst index 120d2c2a253..dd6a23a93bb 100644 --- a/cuda_core/docs/source/release/1.2.0-notes.rst +++ b/cuda_core/docs/source/release/1.2.0-notes.rst @@ -73,6 +73,14 @@ Fixes and enhancements Windows, both ``ctypes.CFUNCTYPE`` and ``ctypes.WINFUNCTYPE`` are accepted. (`#2439 `__) +- :meth:`DeviceMemoryResource.register` and + :meth:`PinnedMemoryResource.register` now raise ``RuntimeError`` when the + memory resource does not have IPC enabled. Previously they dereferenced a + ``None`` attribute and terminated the process with a segmentation fault, so + the call could not be guarded with ``try``. A rejected registration no longer + leaves an entry in the memory resource registry. + (`#2568 `__) + Deprecation Notices ------------------- diff --git a/cuda_core/tests/memory_ipc/test_errors.py b/cuda_core/tests/memory_ipc/test_errors.py index 0aac9f9a297..9a672c687fa 100644 --- a/cuda_core/tests/memory_ipc/test_errors.py +++ b/cuda_core/tests/memory_ipc/test_errors.py @@ -4,6 +4,7 @@ import multiprocessing import pickle import re +import uuid import pytest from helpers.child_processes import child_timeout_sec, kill_subprocesses @@ -51,6 +52,23 @@ def test_ipc_allocation_handle_rejects_negative_fd(): IPCAllocationHandle._init(-1, None) +@pytest.mark.human_authored +def test_register_rejects_non_ipc_memory_resource(): + """register() on a resource without IPC enabled raises instead of dereferencing None.""" + device = Device() + device.set_current() + mr = DeviceMemoryResource(device) + assert not mr.is_ipc_enabled + + key = uuid.uuid4() + with pytest.raises(RuntimeError, match="Memory resource is not IPC-enabled"): + mr.register(key) + + # The rejected registration must not leave the resource in the registry. + with pytest.raises(RuntimeError, match=r"Memory resource [a-z0-9-]+ was not found"): + DeviceMemoryResource.from_registry(key) + + class ChildErrorHarness: """Test harness for checking errors in child processes. Subclasses override PARENT_ACTION, CHILD_ACTION, and ASSERT (see below for examples)."""