Skip to content

fix(cuda.core): grant the current device access to PinnedMemoryResource pools - #3405

Open
saiyambharara wants to merge 1 commit into
NVIDIA:mainfrom
saiyambharara:fix-3205-pinned-pool-access
Open

saiyambharara wants to merge 1 commit into
NVIDIA:mainfrom
saiyambharara:fix-3205-pinned-pool-access

Conversation

@saiyambharara

Copy link
Copy Markdown
Contributor

Description

closes #3205

A host memory pool is accessible only from the host by default, so kernels faulted on PinnedMemoryResource buffers. The resource now grants the current device read/write access with cuMemPoolSetAccess, for both a created pool and the default host pool. Pools imported over IPC are not covered.

Checklist

  • I have read the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

…ce pools

Signed-off-by: Saiyam Bharara <saiyambharara@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the cuda.core Everything related to the cuda.core module label Nov 6, 2026
@saiyambharara

Copy link
Copy Markdown
Contributor Author

@Andy-Jost ready for review. It grants the current device read/write on both pool paths, as you described on #3205. The kernel test faults on main and passes with the fix, with and without numa_id. Could you /ok to test 036e4a0?

@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Explain Change →

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Kernels can now read from and write to pinned-memory buffers using the device that was active when the memory resource was created. This applies to resources using the driver’s current memory pool, as well as host and NUMA-specific pools.
    • Other devices do not receive access to these buffers automatically; access remains limited to the device active at creation.

PinnedMemoryResource now grants the device current at resource creation read/write access to supported host memory pools. Tests exercise kernel access for current, new, and NUMA pools. Documentation describes which device can access the buffers.

Changes: Pinned memory device access

Layer / File(s) Summary
Grant current-device access during pool initialization
cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx
Initialization checks support for the relevant host pool type. When supported, it sets read/write access for the device current at creation.
Test and document device access
cuda_core/cuda/core/_memory/_pinned_memory_resource.pyi, cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx, cuda_core/tests/test_memory.py, cuda_core/docs/source/release/1.3.0-notes.rst
The test launches a kernel that reads and writes buffers from current, new, and NUMA pools. The documentation describes the access rule and the release notes describe the fix.

Assessment against linked issues

Objective Addressed Explanation
Test kernel reads and writes on the allocating device, with and without numa_id [#3205] ✅
If kernel access faults, grant current-device read/write access during pool creation and retain is_device_accessible as True [#3205] ✅

Possibly related issues

  • NVIDIA/cuda-python#2795: The PR uses host-pool capability checks to decide whether to grant access; the issue reports possible false negatives for supported NUMA pools.
  • NVIDIA/cuda-python#3219: The PR adds kernel-access coverage for NUMA-bound pinned-memory buffers.

Suggested reviewers: uday1o1

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: Low · up to 036e4

The pinned-memory fix works for newly created pools, but the docs promise more than the code delivers for imported pools and shared current pools. Correct the documentation before or soon after merge.

Security architecture risk: Low · up to 036e4

The change restores intended GPU access to pinned buffers. The main concern is that access granted to a shared pool can persist across resource lifetimes and accumulate across devices, so the documented exclusion of other devices is not a reliable isolation guarantee. No cross-process or privilege-escalation attack was demonstrated.

Retained concerns

  • Low · security · inferred: The documented exclusion of other devices does not hold as a general guarantee for shared pools. Creating resources under different devices against the same current/default pool can accumulate pool-wide read/write grants, and closing a resource does not revoke its grant. Applications must not treat resource creation or close as a per-device isolation boundary.
Security review details

Security Blast Radius

  • inferred — The authorization unit is the entire selected pool, not only buffers allocated through the new wrapper. On a reused current/default pool, the effective exposure includes other allocations in that pool for each device granted access.

Security Findings and Attack Paths

  • inferred — The supported concern requires application execution to create resources under multiple supported devices against the same pool. This is a misleading isolation contract, not a demonstrated unauthenticated or cross-tenant exploit. Host access predates the PR, and explicit IPC sharing remains a separate mechanism.

Trust Boundaries and Controls

  • observed — The grant uses the current CUDA device identity and is gated by host or host-NUMA capability. These are device-selection and compatibility controls, not tenant authorization or a per-resource device allowlist.

Resilience and Maintainability Implications

  • inferred — Owned-pool constructor failures are contained by the owning handle's automatic destruction when references are released. This counters a pool-leak concern after access configuration fails, but does not provide permission rollback for driver-managed shared pools.

Hardening Proposals

  • proposed — Define shared-pool access as cumulative pool policy rather than resource-local isolation. Where isolation is required, use a dedicated pool with explicit device permissions and ownership; do not automatically revoke shared permissions on wrapper close, since other users may depend on them.
- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 63efb2d and 036e4a0.

Files selected for processing: 4

  • cuda_core/cuda/core/_memory/_pinned_memory_resource.pyi
  • cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx
  • cuda_core/docs/source/release/1.3.0-notes.rst
  • cuda_core/tests/test_memory.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment on lines +106 to +108
created read and write access to the pool. Kernels on other devices cannot
access its buffers. Without options, the grant applies to the driver's
current pool, which the whole process shares.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Functional Correctness · Quick win

Supported by static analysis

Script executed:

git diff 63efb2db31f06ce4c1edc0c3fe5bcd78d8cb720a 036e4a07c8ec8d9fb32630e2d581f886f2df61a5 -- cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx cuda_core/cuda/core/_memory/_pinned_memory_resource.pyi cuda_core/cuda/core/_memory/_memory_pool.pyx
rg -n -F -e 'cuMemGetMemPool' -e 'cuMemPoolSetAccess' -e 'cuMemPoolGetAccess' -e 'Kernels on other devices' -e 'current pool' cuda_core/cuda/core/_memory cuda_core/tests
nl -ba cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx | sed -n '65,210p;260,355p'
rg -n -F -e '_initialize' -e 'cuMemGetMemPool' -e 'cuMemPoolCreate' cuda_core/cuda/core/_memory/_memory_pool.pyx

Repository: NVIDIA/cuda-python

Length of output: 20733


Web query:

CUDA driver API cuMemGetMemPool host location current pool CU_MEM_LOCATION_TYPE_HOST cuMemPoolSetAccess other device access flags independent

Result:

Sources consulted:
- 6.39. Stream Ordered Memory Allocator — CUDA Driver API Reference Manual 13.5 documentation — https://docs.nvidia.com/cuda/cuda-driver-api/cuda_driver_api/group__CUDA__MALLOC__ASYNC.html
- 4.3. Stream-Ordered Memory Allocator — CUDA Programming Guide — https://docs.nvidia.com/cuda/cuda-programming-guide/04-special-topics/stream-ordered-memory-allocation.html
- CUDA Driver API — https://docs.nvidia.com/cuda/pdf/CUDA_Driver_API.pdf
- 6.5. Data types used by CUDA driver — CUDA Driver API Reference Manual 13.5 documentation — https://docs.nvidia.com/cuda/cuda-driver-api/cuda_driver_api/group__CUDA__TYPES.html
- …and 28 more

Script executed:

nl -ba cuda_core/cuda/core/_memory/_memory_pool.pyx | sed -n '400,435p'
nl -ba cuda_core/cuda/core/_memory/_location.pyx | sed -n '1,120p'

Repository: NVIDIA/cuda-python

Length of output: 1675


Web query:

CUDA 13 driver cuMemPoolSetAccess "specified" locations "access" map allocations does not affect other locations

Result:

Sources consulted:
- CUDA Driver API :: CUDA Toolkit Documentation — https://docs.nvidia.com/cuda/archive/13.0.0/cuda-driver-api/group__CUDA__MALLOC__ASYNC.html
- 6.39. Stream Ordered Memory Allocator — CUDA Driver API Reference Manual 13.5 documentation — https://docs.nvidia.com/cuda/cuda-driver-api/cuda_driver_api/group__CUDA__MALLOC__ASYNC.html
- 4.3. Stream-Ordered Memory Allocator — CUDA Programming Guide — https://docs.nvidia.com/cuda/archive/13.2.1/cuda-programming-guide/04-special-topics/stream-ordered-memory-allocation.html
- …and 17 more

Script executed:

rg -n -F 'cumemlocation_from_id' cuda_core/cuda/core/_memory/_location.pxd cuda_core/cuda/core/_memory
nl -ba cuda_core/cuda/core/_memory/_location.pxd | sed -n '1,110p'
nl -ba cuda_core/cuda/core/_memory/_peer_access_utils.pyx | sed -n '135,175p'

Repository: NVIDIA/cuda-python

Length of output: 7737


Web query:

site:docs.nvidia.com/cuda/archive/13.0.0/cuda-driver-api/group__CUDA__MALLOC__ASYNC.html "cuMemPoolSetAccess" "The access" "locations"

Result:

Sources consulted:
- CUDA Driver API :: CUDA Toolkit Documentation — https://docs.nvidia.com/cuda/archive/13.0.0/cuda-driver-api/group__CUDA__MALLOC__ASYNC.html
- CUDA Driver API :: CUDA Toolkit Documentation — https://docs.nvidia.com/cuda/archive/13.0.0/cuda-driver-api/group__CUDA__VA.html
- CUDA Driver API — https://docs.nvidia.com/cuda/archive/13.0.0/pdf/CUDA_Driver_API.pdf
- CUDA Driver API :: CUDA Toolkit Documentation — https://docs.nvidia.com/cuda/archive/13.0.2/cuda-driver-api/group__CUDA__MALLOC__ASYNC.html
- …and 19 more

important: Qualify the other-device access claim.

Two resources created without options can share the current pool. If they are created on different supported devices, both devices can retain access to all allocations in that pool. Qualify the claim here and in _pinned_memory_resource.pyi.

@property
def is_device_accessible(self) -> bool:
"""Return True. This memory resource provides device-accessible buffers."""
"""Return True. The device that is current when the resource is created can read and write its buffers."""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Functional Correctness · Quick win

Supported by static analysis

Script executed:

git diff 63efb2db31f06ce4c1edc0c3fe5bcd78d8cb720a 036e4a07c8ec8d9fb32630e2d581f886f2df61a5 -- cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx
rg -n -F -e 'from_allocation_handle' -e '_PMR_init' -e 'is_device_accessible' -e 'cuMemPoolImport' -e 'cuMemPoolSetAccess' cuda_core/cuda/core/_memory cuda_core/docs cuda_core/tests
nl -ba cuda_core/cuda/core/_memory/_pinned_memory_resource.pyx | sed -n '1,410p'

Repository: NVIDIA/cuda-python

Length of output: 33079


Web query:

CUDA driver cuMemPoolImportFromShareableHandle imported memory pool device access cuMemPoolSetAccess access permissions importing process

Result:

Sources consulted:
- CUDA Programming Guide — https://docs.nvidia.com/cuda/cuda-programming-guide/pdf/cuda-programming-guide.pdf
- 6.39. Stream Ordered Memory Allocator — CUDA Driver API Reference Manual 13.5 documentation — https://docs.nvidia.com/cuda/cuda-driver-api/cuda_driver_api/group__CUDA__MALLOC__ASYNC.html
- 4.3. Stream-Ordered Memory Allocator — CUDA Programming Guide — https://docs.nvidia.com/cuda/cuda-programming-guide/04-special-topics/stream-ordered-memory-allocation.html
- cuda.bindings._v2.driver.mem_pool_import_from_shareable_handle — cuda.bindings — https://nvidia.github.io/cuda-python/cuda-bindings/latest/module/generated/driver_v2/cuda.bindings._v2.driver.mem_pool_import_from_shareable_handle.html
- 4.3. Stream-Ordered Memory Allocator — CUDA Programming Guide — https://docs.nvidia.com/cuda/archive/13.1.1/cuda-programming-guide/04-special-topics/stream-ordered-memory-allocation.html
- …and 14 more

Script executed:

nl -ba cuda_core/cuda/core/_memory/_ipc.pyx | sed -n '380,485p'
nl -ba cuda_core/cuda/core/_memory/_pinned_memory_resource.pyi | sed -n '60,190p'
git diff 63efb2db31f06ce4c1edc0c3fe5bcd78d8cb720a 036e4a07c8ec8d9fb32630e2d581f886f2df61a5 -- cuda_core/docs/source/release
rg -n -F -e 'memory_pool_import' -e 'mem_pool_import' -e 'cuMemPoolImportFromShareableHandle' cuda_core/cuda/core/_cpp cuda_core/cuda/core/_memory

Repository: NVIDIA/cuda-python

Length of output: 12111


Web query:

CUDA cuMemPoolCreate HOST_NUMA pool initially only accessible host cuMemPoolImportFromShareableHandle access imported host memory pool GPU access permissions

Result:

Sources consulted:
- 6.39. Stream Ordered Memory Allocator — CUDA Driver API Reference Manual 13.5 documentation — https://docs.nvidia.com/cuda/cuda-driver-api/cuda_driver_api/group__CUDA__MALLOC__ASYNC.html
- 6.38. Stream Ordered Memory Allocator — CUDA Driver API Reference Manual 13.4 documentation — https://docs.nvidia.com/cuda/archive/13.4.2/cuda-driver-api/cuda_driver_api/group__CUDA__MALLOC__ASYNC.html
- 4.3. Stream-Ordered Memory Allocator — CUDA Programming Guide — https://docs.nvidia.com/cuda/cuda-programming-guide/04-special-topics/stream-ordered-memory-allocation.html
- …and 19 more

Script executed:

nl -ba cuda_core/cuda/core/_cpp/rt/memory.cpp | sed -n '108,175p'
rg -n -F -e 'create_mempool_handle_ipc' cuda_core/cuda/core/_cpp/rt cuda_core/cuda/core/_memory/_ipc.pyx
nl -ba cuda_core/docs/source/release/1.3.0-notes.rst | sed -n '138,155p'

Repository: NVIDIA/cuda-python

Length of output: 4542


important: Qualify the device-access claims for imported pools.

from_allocation_handle() does not grant device access, and imported pools do not inherit the exporter's access grants. A kernel that uses an imported allocation can fault.

Exclude imported pools from the guarantee in the property, class documentation, stub, and release notes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cuda.core Everything related to the cuda.core module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cuda.core: PinnedMemoryResource.is_device_accessible returns True without granting device access to the pool

1 participant