Portál AbcLinuxu, 22. říjen 2017 12:33

Jaderné noviny – 27. 7. 2017: Rychlejší ochrana před přetečením čítače referencí

7.9. | Redakce
Články - Jaderné noviny – 27. 7. 2017: Rychlejší ochrana před přetečením čítače referencí  

Stav vydání jádra. Rychlejší ochrana před přetečením čítače referencí.

Stav vydání jádra

Současné vývojové jádro je 4.13-rc2, vydané 23. července. „Změny jsou všude, i když přehledu změn vládne nový staging ovladač vboxvideo. Neměl jsem ho nechat projít, ale Greg, jak všichni víme, je ‚zvláštní.' A quod licet Iovi… a tak dále – Gregovi občas projde porušení pravidel.“

Stabilní aktualizace: 4.12.3, 4.11.12, 4.9.39, 4.4.78 a 3.18.62 byly vydány 21. července. Za zmínku stojí, že verze 4.11.12 je poslední v řadě 4.11.x.

(Velké) stabilní aktualizace 4.12.4, 4.9.40, 4.4.79 a stabilní 3.18.63 byly v době psaní toho článku v procesu revidování, vyšly 27. července.

Rychlejší ochrana před přetečením čítače referencí

Zlepšení zabezpečení systému často zahrnuje kompromisy, které se dotýkají mj. pohodlí a výkonu. Vývojáři, kteří se zaměřují na bezpečnost, ke svému zděšení často zjišťují, že tolerance k těmto kompromisům je poměrně nízká. Ochrana před přetečením čítače referencí narazila na takovouto bariéru, což výrazně zpomalilo její přijetí. Nyní se však zdá, že se povedlo najít řešení vyšší režie v oblasti výkonu, která byla způsobena tvrzením čítače referencí, a tak se otevřela cesta k jeho přijetí napříč jádrem.

Přetečení čítače referencí se obvykle objevuje jako důsledek programátorských chyb. Kód, který inkrementuje čítač referencí na daný objekt, může zanedbávat dekrementaci čítače například při ošetřování některých chybových stavů. Takové chyby mohou útočníkovi umožnit čítač opakovaně inkrementovat, dokud nedojde k jeho přetečení, načež může být daný objekt považován za nevyužitý a uvolněný, přestože je ve skutečnosti stále používán. Výsledná zranitelnost používání po uvolnění (use-after-free) se dá často využít k úplné kompromitaci systému.

Cesta k ochraně jádra před přetečením čítače referencí byla dlouhá. Začalo to kódem ze sady patchů PaX/grsecurity, ale počáteční přístup, který spočíval v přidání ochrany jaderného typu atomic_t, narazil na odpor a musel být změněn. Dalším krokem bylo uvedení nového typu refcount_t speciálně pro čítače referencí a jejich ochranu. Tento typ byl začleněn ve vývojovém cyklu 4.11 a různé jaderné subsystémy ho začaly používat, ale refcount_t rozčílil síťové vývojáře, kteří se nebyli ochotni smířit s jeho dopadem na výkon.

Právě síťová vrstva je místem, kde podobné patche často narazí na problém, ale tentokrát tato část jádra nebyla jediná. Například Andrew Morton si nedávno stěžoval na přechod na refcount_t v subsystému IPC (interprocess communication). Podle něj nemá smysl zpomalovat „jednoduchý, bezpečný, starý a dobře otestovaný kód.“ Vypadalo to, že i kdyby se napříč jádrem přidala ochrana proti přetečení čítače referencí, byla by zakázána distributory obávajícími se snížení výkonu.

Jednou ze základních pravd v oblasti vývoje bezpečného systému je ta, že zakázaná (nebo nikdy neimplementovaná) ochranná opatření jsou pozoruhodně neúčinná při zastavování útočníků. Další zní, že „bezpečný, starý, dobře testovaný“ kód, může být pouze starý, jak podotkl Ingo Molnár:

Jedná se o starý kód dobře otestovaný pro _stávající rozumné parametry_, dokud v něm někdo neobjeví deset let starou chybu s šílenými parametry, na kterou zatím nikdo nenarazil, a postaví na ní svůj exploit.

Opravdová ochrana jádra před přetečením čítače referencí vyžaduje, aby kontroly byly co nejuniverzálnější. To zase vyžaduje přesvědčit vývojáře, aby přijali vyšší režii spojenou s kontrolami, nebo přijít na to, jak režii snížit na přijatelnou úroveň. Druhá varianta je téměř jistě cestou nejmenšího odporu – pokud se řešení s menší režií podaří najít.

Zdá se, že Kees Cook se svou sadou patchů pro rychlou ochranu proti přetečení čítače referencí takové řešení opravdu našel. Pracuje tak, že přidává jedinou instrukci ke stávající (silně optimalizované) implementaci atomic_t, která ošetřuje případ, kdy čítač referencí dosáhne záporných hodnot (což se při přetečení stane). Instrukci je zvláště snadné předvídat logikou procesoru, takže výkon je dobrý, jak dokazují výsledky mikrobenchmarku, které byly zveřejněny spolu se sadou patchů. Se standardní implementací atomic_t proběhl test v 82 249 mld. cyklů, zatímco nový kód refcount_t zabral 82 211 mld. cyklů – jinými slovy úplně stejně v rámci statistické odchylky. Pro srovnání, starší implementace refcount_t vyžaduje 144,8 mld. cyklů k proběhnutí testu.

Doplnění: k autorství popsané jediné instrukce se přihlásil Pax Team. Jinak je sada patchů Keesova.

Současná sada patchů je určena pouze pro architekturu x86. Vzhledem k tomu, že je potřeba práce v jazyce symbolických adres, každá další architektura bude přidána samostatně, až se k tomu někdo dostane. Vypadá to, že nejsou žádné velké překážky, které by bránily aplikování této techniky na dalších významných architekturách.

Tahle změna nebude ve srovnání s úplnou implementací refcount_t zadarmo: již nerozeznává případ „inkrementace od nuly.“ Pokud čítač referencí objektu klesne na nulu, je tento objekt normálně uvolněn. Následná operace inkrementace naznačuje, že reference stále existovala a uvolněný objekt by mohl být stále používán. Tohle by samozřejmě bylo dobré podchytit, ale nikdo nepřišel na způsob, jak to udělat jinak než za cenu režie navíc nad rámec operací inkrementace. Cook ve své sadě patchů tvrdil, že případ přetečení, který nový refcount_t opravdu řeší, je ten nejčastější, přičemž citoval dva příklady útoků zveřejněné v roce 2016 (CVE-2014-2851 a CVE-2016-0728), které by byly zablokovány, kdyby kontrola byla bývala implementovaná už tehdy.

Někteří vývojáři z typu refcount_t pořád nejsou nadšení, viz například tuto stížnost Erica Biedermana (a Cookovu odpověď). Zbývající neshody se zdály být založeny na páru argumentů: (1) refcount_t neopravuje všechny problémy související s čítači referencí a (2) jeho použití implikuje očekávání chyby, což někteří vývojáři nesou s nelibostí, jelikož je to ve sporu s jejich hrdostí. Ale vzhledem k tomu, že se problém s výkonem zdá být vyřešen, by tyto stížnosti neměly bránit implementaci tvrzení čítače referencí ve většině jádra. To může být jen dobrá zpráva pro všechny, kdo mají starost o bezpečnost.

Odkazy a zdroje

LWN.net
Faster reference-count overflow protection

Další články z této rubriky

Jaderné noviny – 5. 10. 2017: Vylepšení v blokové vrstvě
Jaderné noviny – 28. 9. 2017: Poznámky z mikrokonference o trasování na LPC
Jaderné noviny – 21. 9. 2017: Zbytek začleňovacího okna 4.14
Jaderné noviny – 14. 9. 2017: První polovina začleňovacího okna 4.14
Jaderné noviny – 8. 9. 2017

Diskuse k tomuto článku

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.