Přeskočit na obsah
Bezpečnost 5 min čtení

Souběžné načtení dvou vektorů promptu obešlo ve vLLM pojistku proti loňské díře

Záznam CVE-2026-73557 popisuje, že pojistka, kterou vLLM přidal v prosinci 2025 proti chybě CVE-2025-62164, stála na přepínači společném pro celý proces. Když server načítal dva vektory promptu z jednoho požadavku naráz, první z nich přepínač po sobě vypnul dřív, než druhý dočetl. Oprava je ve vLLM 0.26.0 z 25. července, číslo CVE dostala 13. srpna a v databázi GitHubu se objevila až 4. září spolu se třemi dalšími.

Řady skříní superpočítače Huygens v serverovém sále
Nizozemský národní superpočítač Huygens. Inferenční server jako vLLM obsluhuje desítky požadavků naráz, a právě na souběhu dvou z nich stojí popisovaná chyba. Foto: Dennis van Zuijlekom, Wikimedia Commons (CC BY-SA 2.0)

Server vLLM dostal loni v listopadu záznam CVE-2025-62164 za chybu v načítání vektorů promptu. Klient může místo textu poslat rovnou vstupní vektory (prompt_embeds) serializované PyTorchem a server je načte funkcí torch.load. PyTorch od verze 2.8.0 u řídkých tenzorů nekontroluje, jestli indexy sedí do udaného tvaru, takže podstrčený tenzor mohl při převodu na hustý zapsat mimo přidělenou paměť. Hlášení dostalo známku 8,8 z deseti a mluví o pádu serveru a „potenciálně“ o spuštění cizího kódu.

Oprava přišla ve dvou krocích. Návrh 27204 z 22. října 2025 schoval celou funkci za přepínač --enable-prompt-embeds, který je vypnutý; vyšel ve verzi 0.11.1 z 19. listopadu. Commit additional protection for CVE-2025-62164 z 15. prosince pak obalil načtení tenzoru kontextem torch.sparse.check_sparse_tensor_invariants(), který kontrolu indexů zapíná. Ten vyšel ve vLLM 0.13.0 z 19. prosince 2025. O téhle druhé pojistce je nový záznam.

Přepínač platí pro celý proces, ne pro jeden požadavek

Dokumentace PyTorche popisuje kontrolu invariantů jako jeden přepínač s metodami is_enabled(), enable()disable(). Kontextový manažer si při vstupu uloží dosavadní hodnotu, kontrolu zapne a při výstupu uloženou hodnotu vrátí. Nic z toho není vázané na vlákno. Věděl to i sám vLLM: test tests/renderers/test_sparse_tensor_validation.py v dotčené revizi nese poznámku, že globální příznak není vláknově lokální a souběžní uživatelé kontextu si stav „zapnuto“ můžou prosakovat mezi testy.

Dokud se vektory promptu posílaly jen na /v1/completions, na tom nesešlo. Návrh 40720 z 1. května 2026 ale dovolil posílat prompt_embeds i jako části zprávy na /v1/chat/completions, a to víc částí v jednom požadavku. Server je načítá souběžně: sesbírá je přes asyncio.gather a každou pošle do výchozího fondu vláken smyčky událostí. Změna vyšla ve vLLM 0.21.0 z 15. května 2026.

Záznam CVE-2026-73557 popisuje pořadí, ve kterém se pojistka ztratí. Neškodná část A vstoupí do kontextu, uloží si „vypnuto“ a kontrolu zapne. Podstrčená část B vstoupí hned za ní a uloží si „zapnuto“. Část A dočte svůj tenzor, vystoupí a vrátí uloženou hodnotu, tedy kontrolu vypne. Část B je pořád uvnitř svého kontextu, jenže torch.load už běží bez kontroly a neplatný řídký tenzor s indexy [[10], [10]] pro tvar 3 × 3 projde až k převodu na hustý tenzor.

Nahlásila to firma hexcraft-labs a její hlášení je na doložení opatrné. Popsané prokládání ověřila deterministickým během nad zdrojovým kódem dotčené revize s PyTorchem 2.11.0; volání to_dense() přitom zachytila dřív, než na neplatný tenzor sáhlo. Živý server, pád procesu, poškození paměti ani spuštění kódu nikdo nepouštěl. Hlášení k tomu píše, že spolehlivé spuštění kódu netestovalo a netvrdí. Známka je proto 6,3 podle CVSS 4.0, tedy střední, proti 8,8 u původní chyby. Podmínkou je zapnutý přepínač --enable-prompt-embeds; multimodální model ani víc vláken vykreslovače potřeba nejsou a klíč k API vLLM ve výchozím nastavení nevyžaduje.

Třetí oprava je zámek kolem celého načtení

Commit 793cf79 ze 14. července 2026 (návrh 48583) přidal soubor vllm/utils/sparse_utils.py s jediným zámkem threading.Lock a obalem check_sparse_tensor_invariants_threadsafe(). Komentář v něm říká, že všechna volací místa MUSÍ používat tenhle obal. Vyměnily ho tři: načítání vektorů promptu, vektorů obrázků a vektorů zvuku. K tomu přibyl test, který popsané pořadí vstupů a výstupů vynutí bariérou mezi dvěma vlákny a ověří, že neplatný tenzor pořád spadne.

Oprava vyšla ve vLLM 0.26.0, na PyPI 25. července a jako vydání na GitHubu 27. července 2026. Poznámky k vydání mají oddíl Security a v něm větu o opravě souběhu, který obešel nápravu CVE, bez čísla záznamu. Hlášení na repozitáři projekt zveřejnil týž den v 9.21 UTC. Číslo CVE si GitHub jako přidělující autorita vyhradil 12. srpna a záznam na cve.org vydal 13. srpna; NVD ho k 5. září vede ve stavu „Received“, tedy bez vlastního ohodnocení. Do globální databáze hlášení GitHubu, ze které čte Dependabot, se záznam dostal až 4. září ve 21.39 UTC. Od commitu s opravou k tomu uběhlo sedm týdnů.

Rozsah dotčených verzí se mezi záznamy liší. Hlášení na repozitáři i databáze GitHubu píšou „od 0.21.0 do 0.26.0“, záznam na cve.org „od 0.20.2rc0“. Porovnání větví přes API GitHubu říká, že commit s chatovými částmi ve značce v0.20.2 není a ve v0.21.0 je; proč cve.org uvádí o jedno vydání starší hranici, z veřejných záznamů nevyčteme.

Tři další záznamy z téhož večera

GitHub zveřejnil 4. září během osmi minut čtyři záznamy k vLLM a všechny čtyři opravuje verze 0.26.0. Druhý z nich je stejného rodu jako ten první. Záznam CVE-2026-73556 (známka 5,3) popisuje, že oprava starší chyby CVE-2026-55574 z verze 0.24.0 přidala časový limit na překlad regulárního výrazu pro strukturovaný výstup jen u backendů xgrammar a outlines. Třetí backend, lm-format-enforcer, zůstal bez limitu a překlad výrazu (a{1,300}){300} podle hlášení nedoběhl ani za dvacet sekund, po které držel jedno jádro procesoru na plném výkonu. V titulku hlášení stojí „missed sibling“, tedy opomenutý sourozenec. Backend si musí správce zvolit výslovně, výchozí auto vede na xgrammar.

Záznam CVE-2026-73555 (5,3) se týká chybových hlášek: na vadný JSON odpověděl server textem výjimky včetně cesty k souboru a čísla řádku, z čehož nepřihlášený klient vyčetl uživatelské jméno, domovský adresář, verzi Pythonu i přesnou verzi vLLM. Záznam CVE-2026-71486 (4,3) míří na koncové body /derender, které dekódují seznamy identifikátorů tokenů dodané klientem bez horní meze; podle nálezce ty koncové body vydaná verze 0.23.0 ještě neměla, databáze GitHubu přesto uvádí rozsah „do 0.26.0“ bez dolní hranice.

Nejnovější vLLM je 0.28.0 z 26. srpna 2026, takže kdo aktualizuje průběžně, má všechny čtyři opravy měsíc. Vektory promptu projekt v dokumentaci určuje důvěryhodným uživatelům a přepínač nechává vypnutý. Hlášení k CVE-2026-73557 k tomu dodává větu, kterou v překladu uvádíme celou: „Není to hranice paměťové bezpečnosti: uživatel oprávněný posílat vektorové vstupy by neměl mít možnost vypnout procesní invariant pro souběžnou práci.“

Zdroje

Diskuse

Zatím tu nikdo nediskutuje. Můžete být první.

Napsat příspěvek

Diskutovat můžete i bez účtu. S registrací se ale příspěvek zveřejní hned a nemusíte pokaždé vyplňovat jméno. Účet už máte? Přihlaste se.

Nezveřejňujeme ho, slouží jen redakci.

Podporuje zápis Texy: **tučně**, *kurzíva*, odrážky, odkazy.

Dál k tématu

  1. Bezpečnost

    Tři skenery skillů pro AI agenty dostaly čísla CVE za přeskočený spustitelný kód

    AgentVerus Scanner, skill-scan z Tencent AI-Infra-Guard a claude-skill-antivirus dostaly 2. září tři čísla CVE. Všechny tři mají posoudit, jestli je cizí skill pro…

  2. Bezpečnost

    CowAgent má dvě nová CVE kvůli výstupu příkazů a sdílenému prohlížeči

    Dva záznamy CVE zveřejněné 2. září popisují odmítnutí služby v agentním nástroji CowAgent. Nástroj Bash hromadí celý výstup příkazu před jeho zkrácením, zatímco…

  3. Bezpečnost

    Záznam CVE popsal chybu FaceFusionu až dva měsíce po její opravě

    FaceFusion do verze 3.6.1 skládal cestu k souboru úlohy přímo z názvu, který přijalo rozhraní Gradio bez přihlášení. Cizí klient tak mohl zapsat JSON mimo pracovní…

  4. Bezpečnost

    Codex spouštěl program z nastavení cizího repozitáře mimo vlastní sandbox

    OpenAI zveřejnila 1. září 2026 čtyři záznamy CVE ke svému agentnímu nástroji Codex. Tři z nich stojí na témže předpokladu: repozitář si s sebou nese vlastní soubor .git…