[clang] [offload-arch] Fix HIP DLL discovery and loading on Windows (PR #194063)
Jacob Lambert via cfe-commits
cfe-commits at lists.llvm.org
Fri May 1 12:41:06 PDT 2026
lamb-j wrote:
**Security regression: this introduces a local privilege escalation vector on standard Windows installs.**
(H/t to @vangthao95 who flagged this.)
Tracing `getCandidateBinPaths("C:\Program Files\AMD\HIP\bin")`:
- depth 1 → `C:\Program Files\AMD\bin`
- depth 2 → `C:\Program Files\bin`
- depth 3 → `C:\bin` ← reached well before the 6-level cap
The default DACL on the root of the system drive grants `BUILTIN\Users` the `CreateDirectories` right, so any local non-admin user can `mkdir C:\bin` without UAC and drop `amdhip64_99.dll` there. Because `compareVersions` ranks by the numeric suffix, version 99 beats both the System32 copy and any colocated build copy outright (no `stable_sort` tie required). When a victim — including an elevated process — runs `offload-arch.exe`, the planted DLL is loaded and `DllMain` executes in the victim's security context. Pre-PR `getSearchPaths` never looked at `C:\bin`, so this is a regression introduced here.
**Minimal fix:** move the existing `if (GrandParent == Parent) break;` check *before* pushing the candidate, so a candidate is never produced when `Parent` is a filesystem root. That eliminates `<drive>:\bin` while keeping the walk useful for `Program Files`-style layouts.
**Defense in depth (recommended):** only accept a candidate when `<Parent>/lib/llvm` (or some marker indicating a ROCm/LLVM install root) exists. That bounds the walk to actual install roots regardless of how deep the exe is buried.
Could you also add a unit test asserting that `getCandidateBinPaths("C:\\Program Files\\AMD\\HIP\\bin")` does **not** contain `C:/bin`? That keeps the regression from coming back.
https://github.com/llvm/llvm-project/pull/194063
More information about the cfe-commits
mailing list