NVIDIA / NVIDIA/cuda-python

[BUG]: LocatedHeaderDir is mutable, so callers can poison the cached header-directory lookup

Open Beginner friendly
#2,646 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
Cython
Stars
3.4k
Forks
329
Avg merge
1d 23h
Merged PRs (30d)
116

Description

Component

cuda.pathfinder

What happened?

locate_nvidia_header_directory() is @functools.cache-backed and returns LocatedHeaderDir, which is a plain (mutable) dataclass. The cache hands every caller the same object, so a write to abs_path on a returned instance changes what every later lookup of that libname returns for the rest of the process, including through the find_nvidia_header_directory() wrapper.

LocatedHeaderDir is also the only one of the three public Located* return types that behaves this way: LocatedStaticLib (_static_libs/find_static_lib.py) and LocatedBitcodeLib (_static_libs/find_bitcode_lib.py) are both @dataclass(frozen=True). As a side effect of not being frozen, LocatedHeaderDir is also unhashable, so it cannot be put in a set or used as a dict key the way its two siblings can.

Reproduction
from cuda.pathfinder import locate_nvidia_header_directory, find_nvidia_header_directory

first = locate_nvidia_header_directory("cudart")
print(first.abs_path)                                # e.g. /usr/local/cuda/include

first.abs_path = "/somewhere/else"                   # caller "normalizes" the result in place

print(locate_nvidia_header_directory("cudart").abs_path)  # /somewhere/else
print(find_nvidia_header_directory("cudart"))             # /somewhere/else
>>> LocatedHeaderDir.__dataclass_params__.frozen, LocatedHeaderDir.__hash__ is not None
(False, False)
>>> LocatedStaticLib.__dataclass_params__.frozen, LocatedStaticLib.__hash__ is not None
(True, True)
>>> LocatedBitcodeLib.__dataclass_params__.frozen, LocatedBitcodeLib.__hash__ is not None
(True, True)
Suggested fix

Make LocatedHeaderDir @dataclass(frozen=True) so it matches the other two public Located* types. The __post_init__ path normalization then needs object.__setattr__. Nothing inside cuda_pathfinder or its tests mutates a LocatedHeaderDir, so this is contained to the public type's contract.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the LocatedHeaderDir definition and the locate_nvidia_header_directory() and find_nvidia_header_directory() entry points. Compare the implementation with _static_libs/find_static_lib.py and _static_libs/find_bitcode_lib.py, then run the cuda.pathfinder tests. Done means the result is immutable and hashable without changing the lookup behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.