Skip to content

cuda_core: fix program-cache poisoning via directory permissions and symlink rejection (CWE-494, NVBUG 6268887) - #2857

Closed
lijinf2 wants to merge 4 commits into
NVIDIA:mainfrom
lijinf2:cached_code_verify
Closed

lijinf2 wants to merge 4 commits into
NVIDIA:mainfrom
lijinf2:cached_code_verify

Conversation

@lijinf2

@lijinf2 lijinf2 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a local cache-poisoning vulnerability (CWE-494, NVBUG 6268887) in FileStreamProgramCache where a local principal could plant malicious device code into the cache and have it loaded by the victim process via cuLibraryLoadData.

Root Cause

Two weaknesses combined to enable the attack:

  1. Permissive directory permissionsmkdir(exist_ok=True) without an explicit mode= left root/ and entries/ inheriting the process umask. exist_ok=True silently accepted a pre-existing world-writable directory, preserving attacker write access.

  2. No symlink check on read__getitem__ read cache entries via path.read_bytes() which follows symlinks. An attacker with write access to entries/ could pre-plant a symlink pointing to attacker-controlled content.

Changes

_file_stream.py — directory permissions

  • Create root/, entries/, and tmp/ with mode=0o700
  • On POSIX, explicitly os.chmod(d, 0o700) after creation to tighten any pre-existing permissive directory

_file_stream.py — symlink rejection

  • On POSIX, check path.is_symlink() before reading; raise FileNotFoundError (cache miss → recompile) if a symlink is detected

test_program_cache.py

  • Add test_program_cache_dirs_created_owner_only: verifies all three dirs are 0o700 on fresh creation
  • Add test_program_cache_tightens_preexisting_permissive_dirs: verifies pre-existing 0o777 directory is tightened on open
  • Update test_program_cache_preexisting_shared_root_used_as_is: reflects new tightening behavior

Security Impact

After this fix, other local users cannot write to entries/, pre-existing world-writable directories are tightened on first open, and pre-planted symlinks are rejected at read time.

@lijinf2 lijinf2 added the bug Something isn't working label Sep 14, 2026
@lijinf2 lijinf2 self-assigned this Sep 14, 2026
@copy-pr-bot

copy-pr-bot Bot commented Sep 14, 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 Sep 14, 2026
@lijinf2 lijinf2 added this to the cuda.core 1.3.0 milestone Sep 14, 2026
@lijinf2

lijinf2 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 8938d97

@github-actions

Copy link
Copy Markdown
Contributor

@leofang leofang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unfortunately these security reports don't really make sense and are getting in our way. We should just waive them and close them as not-a-bug.

self._tmp.mkdir(exist_ok=True, mode=0o700)
if os.name != "nt":
for _d in (self._root, self._entries, self._tmp):
os.chmod(_d, 0o700)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is deja vu to me (and is what caught my attention): I vividly remember that we specifically want to keep the behavior: #2399 (comment)

# FileNotFoundError so the caller treats this as a cache miss and recompiles.
if os.name != "nt" and path.is_symlink():
raise FileNotFoundError(f"Symlink not accepted as cache entry: {path}")
return path.stat(), path.read_bytes()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This breaks my usage today. I sometimes use a shared system on which I symlink a bunch of folders residing on an NFS, since it has a way bigger disk space and is portable to other compute nodes.

@leofang

leofang commented Sep 15, 2026

Copy link
Copy Markdown
Member

Sorry for wasting your time @lijinf2. I just closed nvbugs 6268887. It should have been closed back when #2399 was merged 😅

@leofang leofang closed this Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working cuda.core Everything related to the cuda.core module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants