Skip to content

fix(security): prevent symlink LPE in GPU allocation - #2605

Closed
KunwarSidhu47 wants to merge 1 commit into
Project-HAMi:masterfrom
KunwarSidhu47:fix-gpu-allocation-lpe
Closed

fix(security): prevent symlink LPE in GPU allocation#2605
KunwarSidhu47 wants to merge 1 commit into
Project-HAMi:masterfrom
KunwarSidhu47:fix-gpu-allocation-lpe

Conversation

@KunwarSidhu47

@KunwarSidhu47 KunwarSidhu47 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Title: fix(security): prevent symlink LPE and add error handling in GPU allocation

Description:

What this PR does / why we need it:
This PR fixes a critical local privilege escalation (LPE) vulnerability and missing error handling within the Nvidia device plugin's Allocate function (pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go).

Previously, the plugin blindly created directories and modified their permissions without checking for errors or verifying the file type. Because the device plugin runs as root and /tmp is world-writable, a malicious local user or unprivileged pod could pre-create a symlink at /tmp/vgpulock pointing to a sensitive file (e.g., /etc/shadow). Since Go's os.Chmod follows symlinks, allocating a GPU would silently change the permissions of /etc/shadow to 0777, granting the attacker full control over the node.

Additionally, because the return values of os.MkdirAll and os.Chmod were completely ignored, any failure to create these directories would be silently swallowed, leading to unpredictable volume mount failures downstream.

Which issue(s) this PR fixes:
Fixes #2604

Special notes for your reviewer:

  • Added strict if err != nil checks around os.MkdirAll to ensure we fail gracefully if directory creation fails.
  • Switched to using os.Lstat prior to os.Chmod to explicitly verify that the target path is an actual directory and os.ModeSymlink is NOT set. This mitigates the symlink TOCTOU attack vector while preserving the required 0777 permission enforcement.

Does this PR introduce a user-facing change?:
No, internal security and error handling improvement.

Summary by CodeRabbit

  • Bug Fixes
    • Improved vGPU allocation reliability by validating required cache and lock directories.
    • Allocation now fails clearly when lock paths are symlinks, invalid, or cannot be created.
    • Existing directories are updated only after confirming they are valid directories.

@hami-robot

hami-robot Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: KunwarSidhu47
Once this PR has been reviewed and has the lgtm label, please assign wawa0210 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hami-robot hami-robot Bot added the size/S label Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 359c20a0-d118-4bd6-977b-f58e88754b23

📥 Commits

Reviewing files that changed from the base of the PR and between 72d92bf and 13d743a.

📒 Files selected for processing (1)
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/server_test.go

📝 Walkthrough

Walkthrough

Allocate now reports directory creation errors and rejects unsafe /tmp/vgpulock paths. Tests initialize hostHookPath with the system temporary directory.

Changes

GPU allocation security

Layer / File(s) Summary
Validate allocation directories
pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go, pkg/device-plugin/nvidiadevice/nvinternal/plugin/server_test.go
Allocate returns directory setup errors, verifies /tmp/vgpulock with filesystem metadata, and rejects symlinks or non-directories before applying permissions. Tests set hostHookPath to os.TempDir().

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • Project-HAMi/HAMi#2279: This PR directly refines vGPU cache and lock directory error handling in server.go.
  • Project-HAMi/HAMi#2417: Both PRs modify the NVIDIA plugin allocation and test setup for vGPU lock-directory handling.

Suggested reviewers: mesutoezdil, ouyangluwei163, chaunceyjiang

Poem

A rabbit checks each directory gate,
Real folders pass; false paths wait.
Errors hop back through the call,
Symlinks cannot alter them all.
Safe allocation guards the hall.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary security fix for symlink-based privilege escalation during GPU allocation.
Linked Issues check ✅ Passed The changes handle directory creation errors and reject symlinks or non-directories before applying permissions, satisfying issue #2604.
Out of Scope Changes check ✅ Passed The changes remain within scope and include only the allocation security fix, error handling, and required test setup.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go`:
- Around line 845-857: Update the directory validation around
cacheFileHostDirectory and /tmp/vgpulock to fail closed: use an atomic no-follow
validation where supported, propagate and wrap every Lstat or Chmod failure, and
reject symlinks or non-directories before either path becomes a mount source.
Call PodAllocationFailed before each filesystem-error return so the allocation
lock is released.
- Around line 841-844: Update the cache-directory setup near MkdirAll to call
PodAllocationFailed(nodename, current, NodeLockNvidia) before every new
filesystem-error return. Make path validation fail closed when Lstat fails or
either path is not a directory, handle Chmod errors explicitly, and avoid
continuing with an unsafe path; prefer descriptor-based validation/permission
changes where needed to prevent replacement races.
- Around line 845-846: Replace the pathname-based Lstat/Chmod sequence around
cacheFileHostDirectory with an atomic no-follow directory-open and
descriptor-based chmod, preserving the directory-only and non-symlink
validation. Apply the same descriptor-based approach to both permission changes
in the surrounding plugin server logic, using the opened directory handle to
prevent replacement races.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a3ec7fb-a485-41c6-9ce2-59fa47edd9cd

📥 Commits

Reviewing files that changed from the base of the PR and between 634bf2b and 72d92bf.

📒 Files selected for processing (1)
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go

Comment on lines +841 to +844
if err := os.MkdirAll(cacheFileHostDirectory, 0777); err != nil {
klog.Errorf("Failed to create cache directory: %v", err)
return nil, err
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C 10 '\bPodAllocationFailed\b' pkg/device-plugin/nvidiadevice/nvinternal/plugin

Repository: Project-HAMi/HAMi

Length of output: 15429


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- allocation path ---'
sed -n '720,925p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go

printf '%s\n' '--- cleanup implementation and tests ---'
sed -n '350,430p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go
sed -n '280,335p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/util_test.go

printf '%s\n' '--- cache and lock path operations ---'
rg -n -C 12 'cacheFileHostDirectory|cacheFileHostPath|os\.Lstat|os\.Chmod|MkdirAll|NodeLockNvidia' pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go

Repository: Project-HAMi/HAMi

Length of output: 23105


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import os
import stat
import tempfile

def cache_check(path):
    try:
        info = os.lstat(path)
    except OSError:
        return "continue"
    if stat.S_ISDIR(info.st_mode) and not stat.S_ISLNK(info.st_mode):
        return "chmod-and-continue"
    return "continue"

def lock_check(path):
    try:
        info = os.lstat(path)
    except OSError:
        return "continue"
    if stat.S_ISDIR(info.st_mode) and not stat.S_ISLNK(info.st_mode):
        return "chmod-and-continue"
    return "return-validation-error"

with tempfile.TemporaryDirectory() as root:
    missing = os.path.join(root, "missing")
    regular = os.path.join(root, "regular")
    symlink = os.path.join(root, "symlink")
    os.mkdir(regular)
    open(os.path.join(root, "file"), "w").close()
    os.symlink(os.path.join(root, "file"), symlink)

    print("cache missing:", cache_check(missing))
    print("cache directory:", cache_check(regular))
    print("cache symlink:", cache_check(symlink))
    print("lock missing:", lock_check(missing))
    print("lock directory:", lock_check(regular))
    print("lock symlink:", lock_check(symlink))

source = open("pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go").read()
block = source[source.index("if err := os.MkdirAll(cacheFileHostDirectory"):source.index("response.Mounts = append", source.index("if err := os.MkdirAll(cacheFileHostDirectory"))]
print("cache cleanup call:", "PodAllocationFailed" in block)
print("lock cleanup call:", "PodAllocationFailed" in block)
PY

Repository: Project-HAMi/HAMi

Length of output: 386


Preserve allocation-failure cleanup and fail closed on path validation.

Call PodAllocationFailed(nodename, current, NodeLockNvidia) before each new filesystem-error return. This marks the allocation failed and releases the node lock.

Return an error when Lstat fails or either path is not a directory. Handle Chmod errors instead of ignoring them. The current checks can continue with an unsafe path, and Lstat followed by path-based Chmod remains vulnerable to replacement races.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go` around lines 841
- 844, Update the cache-directory setup near MkdirAll to call
PodAllocationFailed(nodename, current, NodeLockNvidia) before every new
filesystem-error return. Make path validation fail closed when Lstat fails or
either path is not a directory, handle Chmod errors explicitly, and avoid
continuing with an unsafe path; prefer descriptor-based validation/permission
changes where needed to prevent replacement races.

Comment on lines +845 to +846
if info, err := os.Lstat(cacheFileHostDirectory); err == nil && info.Mode().IsDir() && info.Mode()&os.ModeSymlink == 0 {
_ = os.Chmod(cacheFileHostDirectory, 0777)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔴 Critical | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C 3 'os\.Lstat|os\.Chmod' pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go
go doc os.Lstat
go doc os.Chmod

Repository: Project-HAMi/HAMi

Length of output: 2342


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- server.go outline ---'
ast-grep outline pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go

printf '%s\n' '--- allocation context ---'
sed -n '780,875p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go

printf '%s\n' '--- applyMutex and related paths ---'
rg -n -C 5 'applyMutex|cacheFileHostDirectory|vgpulock|PodAllocationFailed' pkg/device-plugin/nvidiadevice/nvinternal/plugin

printf '%s\n' '--- module and platform context ---'
sed -n '1,120p' go.mod
find pkg/device-plugin/nvidiadevice/nvinternal/plugin -maxdepth 2 -type f -print | sort

Repository: Project-HAMi/HAMi

Length of output: 39654


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- complete Allocate tail ---'
sed -n '737,922p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go

printf '%s\n' '--- lock and allocation-failure implementation ---'
sed -n '1,240p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go
sed -n '360,425p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go

printf '%s\n' '--- hostHookPath sources ---'
rg -n -C 4 'hostHookPath\s*=|hostHookPath:|HostHook|HOST_HOOK|host-hook' pkg/device-plugin/nvidiadevice/nvinternal/plugin

printf '%s\n' '--- Go standard-library semantics and Linux flags ---'
go doc os.File.Chmod
go doc syscall.Open
go doc syscall.O_NOFOLLOW
go doc syscall.O_DIRECTORY
go env GOROOT

Repository: Project-HAMi/HAMi

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import os
import re
import subprocess

server = Path("pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go").read_text()
checks = [
    ("cache", "cacheFileHostDirectory"),
    ("lock", '"/tmp/vgpulock"'),
]

for name, path_expr in checks:
    lstat = re.search(rf'os\.Lstat\({re.escape(path_expr)}\)', server)
    chmod = re.search(rf'os\.Chmod\({re.escape(path_expr)},\s*0777\)', server)
    if name == "cache":
        lstat = re.search(r'os\.Lstat\(cacheFileHostDirectory\)', server)
        chmod = re.search(r'os\.Chmod\(cacheFileHostDirectory,\s*0777\)', server)
    assert lstat and chmod, f"missing {name} Lstat/Chmod pair"
    assert lstat.start() < chmod.start(), f"unexpected {name} call order"
    print(f"{name}: Lstat and Chmod are separate pathname operations")

assert "applyMutex                 sync.Mutex" in server
print("synchronization: applyMutex is an in-process sync.Mutex")

goroot = Path(subprocess.check_output(["go", "env", "GOROOT"], text=True).strip())
matches = []
for p in (goroot / "src/os").glob("*.go"):
    text = p.read_text(errors="replace")
    if re.search(r"func Chmod\(name string", text) and "syscall.Chmod" in text:
        matches.append((p, "Chmod", "syscall.Chmod(name"))
    if re.search(r"func Lstat\(name string", text) and "syscall.Lstat" in text:
        matches.append((p, "Lstat", "syscall.Lstat(name"))

assert {kind for _, kind, _ in matches} == {"Lstat", "Chmod"}
for p, kind, needle in matches:
    print(f"{kind}: {p.relative_to(goroot)} delegates by pathname")
PY

Repository: Project-HAMi/HAMi

Length of output: 411


🏁 Script executed:

#!/bin/bash
set -euo pipefail

GOROOT="$(go env GOROOT)"
rg -n -C 5 'func (Lstat|Chmod)|syscall\.(Lstat|Chmod)|Fchmod|fchmod' "$GOROOT/src/os" "$GOROOT/src/syscall" | head -n 160

Repository: Project-HAMi/HAMi

Length of output: 10563


Make the no-symlink check atomic with the permission change. os.Lstat and path-based os.Chmod use separate pathname lookups. Another local process can replace the checked directory with a symlink between these calls, and os.Chmod follows that symlink. Open the directory with no-follow and directory flags, then chmod the open descriptor, or use an equivalent atomic Linux primitive. Apply this to both permission changes.

🧰 Tools
🪛 ast-grep (0.45.1)

[warning] 845-845: File mode grants world-writable permission; restrict the mode so other users cannot modify the file (e.g. 0o644 / 0o600).
Context: os.Chmod(cacheFileHostDirectory, 0777)
Note: [CWE-276] Incorrect Default Permissions.

(world-writable-chmod-go)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go` around lines 845
- 846, Replace the pathname-based Lstat/Chmod sequence around
cacheFileHostDirectory with an atomic no-follow directory-open and
descriptor-based chmod, preserving the directory-only and non-symlink
validation. Apply the same descriptor-based approach to both permission changes
in the surrounding plugin server logic, using the opened directory handle to
prevent replacement races.

Comment on lines +845 to +857
if info, err := os.Lstat(cacheFileHostDirectory); err == nil && info.Mode().IsDir() && info.Mode()&os.ModeSymlink == 0 {
_ = os.Chmod(cacheFileHostDirectory, 0777)
}

if err := os.MkdirAll("/tmp/vgpulock", 0777); err != nil {
klog.Errorf("Failed to create lock directory: %v", err)
return nil, err
}
if info, err := os.Lstat("/tmp/vgpulock"); err == nil && info.Mode().IsDir() && info.Mode()&os.ModeSymlink == 0 {
_ = os.Chmod("/tmp/vgpulock", 0777)
} else if err == nil {
return nil, fmt.Errorf("/tmp/vgpulock is a symlink or not a directory")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

file='pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go'

printf '%s\n' '--- target function map ---'
ast-grep outline "$file" | sed -n '1,220p'

printf '%s\n' '--- target region ---'
sed -n '780,900p' "$file"

printf '%s\n' '--- allocation/error and cleanup references ---'
rg -n -C 4 'PodAllocationFailed|cacheFileHostDirectory|vgpulock|func \(.*\) Allocate|func .*Allocate' "$file" pkg/device-plugin/nvidiadevice/nvinternal/plugin

printf '%s\n' '--- changed-file summary ---'
git diff --stat

Repository: Project-HAMi/HAMi

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -eu

file='pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go'

printf '%s\n' '--- Allocate entry, defers, and exits ---'
sed -n '737,785p' "$file"
sed -n '890,918p' "$file"

printf '%s\n' '--- lock release implementation ---'
sed -n '340,430p' pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go
rg -n -C 6 'applyMutex|updatePodAnnotationsAndReleaseLock|DeviceBindFailed|PodAllocationTrySuccess' \
  pkg/device-plugin/nvidiadevice/nvinternal/plugin

printf '%s\n' '--- exact diff for the target file ---'
git diff --unified=30 -- "$file" | sed -n '1,260p'

Repository: Project-HAMi/HAMi

Length of output: 30940


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- pending-pod lookup and lock acquisition ---'
rg -n -C 12 'getPendingPod|func .*PendingPod|NodeLockNvidia|DeviceBind' \
  pkg/device-plugin/nvidiadevice/nvinternal/plugin \
  pkg | sed -n '1,320p'

printf '%s\n' '--- allocation tests covering filesystem setup and failure handling ---'
rg -n -C 12 'cache directory|vgpulock|MkdirAll|Chmod|RemoveAll|Allocate\(' \
  pkg/device-plugin/nvidiadevice/nvinternal/plugin/*_test.go | sed -n '1,360p'

printf '%s\n' '--- all Allocate returns in the target function ---'
python3 - <<'PY'
from pathlib import Path
p = Path('pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go')
lines = p.read_text().splitlines()
for i in range(736, 916):
    if 'return ' in lines[i]:
        print(f'{i+1}: {lines[i]}')
PY

Repository: Project-HAMi/HAMi

Length of output: 50373


Fail closed on directory validation and permission errors.

If os.Lstat or os.Chmod fails for cacheFileHostDirectory or /tmp/vgpulock, return a wrapped error before adding the path as a mount source. The current code ignores os.Chmod errors and allows os.Lstat errors to fall through.

Call PodAllocationFailed before these error returns. Otherwise, the pod allocation lock can remain held after a filesystem failure. Replace the Lstat/Chmod sequence with an atomic no-follow validation where supported.

🧰 Tools
🪛 ast-grep (0.45.1)

[warning] 845-845: File mode grants world-writable permission; restrict the mode so other users cannot modify the file (e.g. 0o644 / 0o600).
Context: os.Chmod(cacheFileHostDirectory, 0777)
Note: [CWE-276] Incorrect Default Permissions.

(world-writable-chmod-go)


[warning] 848-848: File mode grants world-writable permission; restrict the mode so other users cannot modify the file (e.g. 0o644 / 0o600).
Context: os.MkdirAll("/tmp/vgpulock", 0777)
Note: [CWE-276] Incorrect Default Permissions.

(world-writable-chmod-go)


[warning] 853-853: File mode grants world-writable permission; restrict the mode so other users cannot modify the file (e.g. 0o644 / 0o600).
Context: os.Chmod("/tmp/vgpulock", 0777)
Note: [CWE-276] Incorrect Default Permissions.

(world-writable-chmod-go)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go` around lines 845
- 857, Update the directory validation around cacheFileHostDirectory and
/tmp/vgpulock to fail closed: use an atomic no-follow validation where
supported, propagate and wrap every Lstat or Chmod failure, and reject symlinks
or non-directories before either path becomes a mount source. Call
PodAllocationFailed before each filesystem-error return so the allocation lock
is released.

@github-actions github-actions Bot added the kind/bug Something isn't working label Aug 11, 2026
Signed-off-by: KunwarSidhu47 <kunwarsidhu1947@gmail.com>
@KunwarSidhu47
KunwarSidhu47 force-pushed the fix-gpu-allocation-lpe branch from f706387 to 13d743a Compare August 11, 2026 21:02
@mesutoezdil

Copy link
Copy Markdown
Contributor

You can view the relevant rule here.
https://github.com/Project-HAMi/HAMi/blob/master/CONTRIBUTING.md#contribution-gates

@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.33333% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ce-plugin/nvidiadevice/nvinternal/plugin/server.go 33.33% 5 Missing and 3 partials ⚠️
Flag Coverage Δ
unittests 62.31% <33.33%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ce-plugin/nvidiadevice/nvinternal/plugin/server.go 35.84% <33.33%> (-0.45%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(security): add missing error handling and prevent symlink LPE in GPU allocation

2 participants