Studio: remove the Windows VBS launcher to clear the Kaspersky false positive (#6326)
* Studio: drop the VBS launcher to clear the Kaspersky false positive
The Windows shortcut launched Unsloth Studio through wscript.exe ->
launch-studio.vbs, and that VBS used CreateObject("WScript.Shell").Run to
start a hidden -ExecutionPolicy Bypass PowerShell. That wscript + .vbs +
bypass-powershell shape is the canonical trigger for generic VBS-dropper
heuristics (Kaspersky HEUR:Trojan.VBS.Agent.gen). The launcher is benign;
only its shape is the problem.
- install.ps1: stop generating launch-studio.vbs and point the Desktop /
Start Menu .lnk straight at powershell.exe -WindowStyle Hidden running
launch-studio.ps1. The shortcut is saved WindowStyle 7 (minimized) so the
brief console flash is muted. launch-studio.ps1 (health poll, port,
mutex, browser) is byte-for-byte unchanged.
- install.ps1: delete a pre-existing launch-studio.vbs on upgrade, so the
flagged file does not linger on machines that already installed it.
- install.ps1 / install.sh: run the heavier ie4uinit -ClearIconCache plus
StartMenuExperienceHost tile-cache rebuild only on a first install or a
real icon change, instead of on every no-op reinstall. That repeated
clear-cache plus kill cluster is itself a dropper-like behavioral pattern.
- tests: forbid VBS generation and require the legacy-VBS cleanup.
Linux, macOS and WSL install paths are unchanged. WSL already targets
wsl.exe from its .lnk and never used a VBS; its only change is the same
icon-cache gating.
* Studio: add launcher-chain smoke coverage to the Windows UI CI
The shortcut launch path was previously untested: studio-windows-ui-smoke
installed then booted `unsloth studio` directly, so a broken .lnk could ship
silently. After install the job now seeds a legacy launch-studio.vbs, asserts
the upgrade removed it, asserts the .lnk targets hidden powershell.exe (never
wscript.exe), and launches via the shortcut's stored command, waiting for
/api/health to report healthy.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
375350e0b6
commit
d50a2e2d07
4 changed files with 241 additions and 78 deletions
74
.github/workflows/studio-windows-ui-smoke.yml
vendored
74
.github/workflows/studio-windows-ui-smoke.yml
vendored
|
|
@ -136,6 +136,17 @@ jobs:
|
|||
}
|
||||
}
|
||||
|
||||
- name: Seed a legacy launch-studio.vbs (upgrade-cleanup check)
|
||||
# Simulate a pre-hardening install so the post-install assertion below
|
||||
# proves the installer DELETES an existing launch-studio.vbs (the exact
|
||||
# Kaspersky-flagged file), not merely stops generating it.
|
||||
shell: pwsh
|
||||
run: |
|
||||
$appDir = Join-Path $env:LOCALAPPDATA 'Unsloth Studio'
|
||||
New-Item -ItemType Directory -Force -Path $appDir | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $appDir 'launch-studio.vbs') -Value 'WScript.Echo "legacy"' -Encoding Unicode
|
||||
Write-Host "seeded legacy launch-studio.vbs at $appDir"
|
||||
|
||||
- name: Install Studio (--local, --no-torch)
|
||||
# install.ps1 is the supported Windows installer. install.sh
|
||||
# has no Windows branch (apt-get / brew calls). The PS1
|
||||
|
|
@ -192,6 +203,69 @@ jobs:
|
|||
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
|
||||
cat "$INFO"
|
||||
|
||||
- name: Assert Studio launcher chain (no VBS, hidden PowerShell shortcut)
|
||||
# The shortcut launch path is otherwise untested here (the steps below
|
||||
# boot `unsloth studio` directly). Guard against re-introducing the VBS
|
||||
# that tripped Kaspersky HEUR:Trojan.VBS.Agent.gen and against the .lnk
|
||||
# pointing anywhere other than hidden PowerShell over launch-studio.ps1.
|
||||
shell: pwsh
|
||||
run: |
|
||||
$appDir = Join-Path $env:LOCALAPPDATA 'Unsloth Studio'
|
||||
if (Test-Path -LiteralPath (Join-Path $appDir 'launch-studio.vbs')) {
|
||||
throw "regression: launch-studio.vbs exists (the Kaspersky VBS-FP shape)"
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $appDir 'launch-studio.ps1'))) {
|
||||
throw "missing launch-studio.ps1 in $appDir"
|
||||
}
|
||||
$lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Unsloth Studio.lnk'
|
||||
if (-not (Test-Path -LiteralPath $lnk)) {
|
||||
$lnk = Join-Path $env:APPDATA 'Microsoft\Windows\Start Menu\Programs\Unsloth Studio.lnk'
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $lnk)) { throw "no Unsloth Studio.lnk on Desktop or Start Menu" }
|
||||
$sc = (New-Object -ComObject WScript.Shell).CreateShortcut($lnk)
|
||||
Write-Host "shortcut target: $($sc.TargetPath)"
|
||||
Write-Host "shortcut args: $($sc.Arguments)"
|
||||
if ($sc.TargetPath -match 'wscript\.exe$') { throw "shortcut still targets wscript.exe (VBS host)" }
|
||||
if ($sc.TargetPath -notmatch 'powershell\.exe$') { throw "unexpected shortcut target: $($sc.TargetPath)" }
|
||||
if ($sc.Arguments -notmatch '-WindowStyle Hidden') {
|
||||
throw "shortcut must launch windowless (-WindowStyle Hidden)"
|
||||
}
|
||||
Write-Host "launcher chain OK (no VBS; hidden powershell over launch-studio.ps1)"
|
||||
|
||||
- name: Launch Studio via the shortcut and assert health
|
||||
# Run the exact command the .lnk stores (hidden PowerShell over
|
||||
# launch-studio.ps1) and confirm it brings the backend up. This is the
|
||||
# only step that proves the shortcut launch is not silently broken.
|
||||
# Default port range is 8888-8908; the later UI tests use 18896/18897, so
|
||||
# there is no conflict, and we tear this server down before they boot.
|
||||
shell: pwsh
|
||||
run: |
|
||||
$lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Unsloth Studio.lnk'
|
||||
if (-not (Test-Path -LiteralPath $lnk)) {
|
||||
$lnk = Join-Path $env:APPDATA 'Microsoft\Windows\Start Menu\Programs\Unsloth Studio.lnk'
|
||||
}
|
||||
$sc = (New-Object -ComObject WScript.Shell).CreateShortcut($lnk)
|
||||
Write-Host "launching: $($sc.TargetPath) $($sc.Arguments)"
|
||||
Start-Process -FilePath $sc.TargetPath -ArgumentList $sc.Arguments -WorkingDirectory $sc.WorkingDirectory
|
||||
$foundPort = 0
|
||||
foreach ($i in 1..180) {
|
||||
foreach ($port in 8888..8908) {
|
||||
try {
|
||||
$r = Invoke-RestMethod -Uri "http://127.0.0.1:$port/api/health" -TimeoutSec 1
|
||||
if ($r.status -eq 'healthy' -and $r.service -eq 'Unsloth UI Backend') { $foundPort = $port; break }
|
||||
} catch {}
|
||||
}
|
||||
if ($foundPort) { break }
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
# Tear down the shortcut-launched server before the main UI tests boot.
|
||||
try {
|
||||
$owner = (Get-NetTCPConnection -LocalPort $foundPort -State Listen -ErrorAction Stop | Select-Object -First 1).OwningProcess
|
||||
if ($owner) { taskkill /PID $owner /T /F 2>$null | Out-Null }
|
||||
} catch {}
|
||||
if (-not $foundPort) { throw "Studio did not become healthy when launched via the shortcut" }
|
||||
Write-Host "Studio healthy on port $foundPort (launched via the shortcut)"
|
||||
|
||||
- name: Add Studio shim to GITHUB_PATH
|
||||
# install.ps1 puts unsloth.exe at $StudioHome\bin\unsloth.exe
|
||||
# and adds that dir to the User PATH via the Windows registry.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue