Portál AbcLinuxu, 29. května 2024 13:42

Jaderné noviny – 8. 8. 2013: Jak to dopadá, když se patche nerevidují

26. 8. 2013 | Luboš Doležel
Články - Jaderné noviny – 8. 8. 2013: Jak to dopadá, když se patche nerevidují  

Aktuální verze jádra: 3.11-rc4. Citáty týdne: Rusty Russell, Andrew Morton. Konečně flink()? Nerevidovaný kód ve verzi 3.11: O_TMPFILE; Tajné opravy bezpečnostních chyb.

Obsah

Aktuální verze jádra: 3.11-rc4

link

Aktuální vývojová verze jádra je 3.11-rc4 vydaná 4. srpna. Doufal jsem, že se vývoj začne uklidňovat, ale -rc4 má více méně stejnou velikost jako -rc3. I tak to ale vypadá, že patche jsou trochu více rozprostřené a méně zajímavé – což je dobré. Nuda je ta správná věc. Do hlavní řady bylo během -rc4 přetaženo 339 neslučovacích sad změn. Jde hlavně o opravy, ale byla tam i záhadná sada bezpečnostních oprav v ARM (začínající zde), která se vynořila bez předchozích debat.

Stabilní aktualizace: verze 3.10.5, 3.4.56, 3.2.50 a 3.0.89 všechny vyšly 4. srpna.

Dále stojí za pozornost, že Greg Kroah-Hartman oznámil, že 3.10 bude dalším jádrem s dlouhodobou podporou. Zvolil jsem toto jádro na základě dlouhých debat o vydáních jádra a vydáních produktů a vývojových plánech spousty firem a vývojových skupin. Nemohu se zavděčit všem, ale myslím si, že verze 3.10 vyhovuje nejvíce lidem z těch, kteří na dlouhodobě udržovaných jádrech závisí.

Citáty týdne: Rusty Russell, Andrew Morton

link

No, hlavně lguest bychom mohli postrádat. Je to takový Redshirt virtualizačního týmu.

-- Rusty Russell

Neboj se toho, že bys napsal moc textu – věř mi, ještě nikdy jsem neviděl příliš dlouhý seznam změn!

-- Andrew Morton

link

Po systémovém volání flink() už je dlouho poptávka. Přebíral by popisovač souboru a název souboru jako argumenty a podle předaného názvu by se vytvořil nový pevný odkaz na soubor dle popisovače. Kvůli obavám z bezpečnostních problémů se ale toto volání do jádra dlouho nedostalo; někteří to vnímají jako cestu, jak může proces vytvořit název souboru k popisovači, který přišel odněkud zvenčí – například přes exec(). Tento proces možná neměl mít k souboru žádnou dosažitelnou cestu, takže vytvoření nového názvu by mohlo být vnímáno jako obcházení existující bezpečnostní politiky.

Tyto obavy mají ten nedostatek, jak Andy Lutomirski popsal v patchi začleněném do 3.11-rc5, a to ten, že tato funkčnost už je dostupná přes systémové volání linkat(). Stačí jen mít připojený systém souborů /proc – a najít systém bez /proc je docela problém. Akorát, že vytváření odkazu tímto způsobem je poněkud pracné:

linkat(AT_FDCWD, "/proc/self/fd/N", destdirfd, newname, AT_SYMLINK_FOLLOW);

Kde "N" je číslo daného popisovače. Bylo by mnohem hezčí umožnit použití volby AT_EMPTY_PATH, která má za následek vytvoření odkazu na soubor za původním popisovačem:

linkat(fd, "", destdirfd, newname, AT_EMPTY_PATH);

V současných jádrech je tato volba nicméně omezena na procesy s právem CAP_DAC_READ_SEARCH kvůli stejným obavám z bezpečnostních problémů, jako je popsáno výše. Ale jak Andy upozornil, toto omezení nemá smysl vzhledem k tomu, že tato funkčnost je tak či tak dostupná. Proto jeho patch omezuje tuto kontrolu a zpřístupňuje druhou variantu všem uživatelům. Tato funkčnost by měla být užitečná se soubory otevřenými s volbou O_TMPFILE, ale dají se najít i jiná využití. Bude dostupná v jádře 3.11.

Nerevidovaný kód ve verzi 3.11

link

Vývoj jádra, stejně jako vývoj ve většině projektů svobodného softwaru, je postaven na revidování kódu ostatními lidmi. Všechny patche by měly být revidovány alespoň jedním dalším vývojářem; to by mělo pomoci odchytit chyby před jejich začleněním a vést k vyšší kvalitě výsledku. Ačkoliv se v jádře kód hodně reviduje, občas se ale určitě stane to, že se do jádra dostane kód, na který se nikdo kromě původního vývojáře nepodíval. Podíváme se na dva případy z poslední doby; ukazují, proč si komunita revidování cení a nebere rizika chybějícího dohledu na lehkou váhu.

O_TMPFILE

link

Nová volba O_TMPFILE pro systémové volání open() byla do hlavní řady přetažena během začleňovacího okna 3.11; před tímto přetažením nebyla nikde zveřejněna. Není pochyb o tom, že jde o užitečnou funkci; umožňuje aplikacím otevřít soubor na zvoleném systému souborů bez viditelného názvu. Jedním šmahem se tak zbavujeme celé řady zranitelností kolem dočasných souborů, většina z nich závisí na uhodnutí názvu souboru. O_TMPFILE se dá navíc použít spolu s linkat() k vytoření souboru a jeho následnému zviditelnění se správnými oprávněními v jediném atomickém kroku. Proto není pochyb o tom, že vývojáři aplikací tuto funkčnost rádi využijí, jakmile bude široce dostupná.

Navzdory tomu to O_TMPFILE nemělo zpočátku jednoduché. Netrvalo dlouho a Linus měl k tomuto novému API výhrady; ve zkratce neměly aplikace jak zjistit, že běží na systému, kde O_TMPFILE není podporované. O několik patchů později byl tento nedostatek vyřešen. Od té doby se v implementaci našlo několik chyb; první, kterou opravil Zheng Liu, by způsobila oops jádra. Další, nahlášená Andym Lutomirskim, poškozuje systém souborů tím, že vytváří falešný inode. Poslední věcí je to, že jen málo systémů souborů tuto volbu zatím podporuje, takže ani na linuxových systémech s tím vývojáři nemohou počítat.

Mezitím Christoph Hellwig zpochybnil API zvolené pro tuto funkci:

Proč je užitečná funkčnost dočasných souborů nabalená na open, když se chová dosti odlišně od běžného open? Kromě problémů s přiznaky, co se tu diskutovaly do nekonečna, navíc vede k rozpliznutí kódu v implementaci.

Christoph navrhuje, že by bylo lepší zavést nové systémové volání tmpfile() než tuto funkci přidávat do open(). Řekl, že O_TMPFILE potřebuje více času:

Vzhledem ke všem problémům a velmi omezené podpoře v systémech souborů bych dal přednost tomu O_TMPFILE v tomto vydání zakázat. To by mu dodalo nutnou publicitu, která patchi chybí kvůli tomu, že byl začleněn bez předchozích debat.

Ani Al Viro (autor této funkčnosti) a ani Linus na Christophovy návrhy neodpověděli, což vede k závěru, že je v plánu zachovat současnou implementaci. Jakmile bude ABI O_TMPFILE ve verzi 3.11 zveřejněno, bude nutné jej navždy podporovat. V současné podobě to určitě půjde, ale kdyby před začleněním proběhla příslušná diskuze, mohlo to vypadat lépe.

Tajné opravy bezpečnostních chyb

link

Žádost o přetažení od Russella Kinga před vydáním 3.11-rc4 nevypadá, že by prošla některým z veřených mailing listů. Na základě commitu v hlavní řadě řekl Russell o tomto požadavku následující:

Dlouho jsem dumal nad tím, co k této žádosti o přetažení napsat, ale nejsem schopen přijít na nic, co by tyto patche shrnulo. Problém je to, že jde povětšinou o spoustu drobností rozprášených napříč jádrem bez nějakého jednotného odůvodnění.

Skutečnost, že 8 z 22 commitů v této žádosti jsou bezpečnostní opravy, zjevně není „jednotným odůvodněním“. Patche vypadají, že činí architekturu ARM odolnější, zjevně jde o reakci na díry z nedávného Black Hat USA 2013. Ačkoliv většina patchů má na sobě Acked-by od Nicolase Pitreho, žádný z nich nebyl předmětem veřejného revidování před začleněním do hlavní řady.

Netrvalo dlouho než Olof Johansson narazil na řadu problémů způsobených těmito změnami, což u několika systémů vedlo k nemožnosti nabootovat. Čtenář LWN kalvdans poukázal na další zjevnou chybu v kódu. Olof navrhl, že by těmto patchům neuškodilo, kdyby strávily nějakou dobu v repozitáři linux-next, na což Russell odpověděl:

Pověz mi, jak mám tyto věci dát do -next _a_ udržet je v tajnosti, protože souvisí s bezpečností. Tyto dvě věci jsou neslučitelné. Promiň.

V tomto případě není vůbec jasné, čeho bylo dosaženo tím, že tyto patche byly vyřazeny z běžného procesu revidování. Zástup distributorů, kteří budou chvátat s nasazením těchto oprav ještě před zveřejněním, bude asi hodně krátký a navíc záplata tak, jak byla začleněna do 3.11-rc4, byla horší než díra, kterou opravovala. V době psaní tohoto textu nebyla žádná z nalezených chyb opravena v hlavní řadě, i když patche už existují.

Tak či tak se ale jistě najdou situace, kdy snad dává smysl vyvíjet a začleňovat opravy mimo zraky veřejnosti. Pokud je o bezpečnostní zranitelnosti známo, že je snadno zneužitelná, tak je vhodné opravu rychle co nejvíce rozšířit, než si útočníci stihnou přichystat exploity. V mnoha případech ale zranitelnosti nebývají snadno zneužitelné nebo, což je zrovna případ většiny výrobků na bázi ARMu, není stejně jak opravu rychle rozšířit. V řadě dalších případů je daná zranitelnost útočníkům známa dlouho před tím, než se jí začne věnovat nějaký vývojář jádra.

Ve všech těchto případech vývoj patchů v utajení spíše škodí. Jak jsme viděli na tomto příkladu, tyto opravy mohou zavést vlastní chyby; někdy těmito chybami mohou být další bezpečnostní problémy. V jiných situacích, jako to bylo u O_TMPFILE, kód, jenž neprošel revidováním, může zavádět neoptimální API, které se pak musí udržovat po mnoho let. Zvyklost kód revidovat, jakou jsme si za uplynulé roky vybudovali, má svůj důvod; obcházení těchto zvyků zavádí do procesu vývoje jádra celou řadu nových rizik. Vývojový cyklus 3.11 je důkazem, jak skutečná tato rizika jsou.

Odkazy a zdroje

Kernel coverage at LWN.net: August 8, 2013

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

Jaderné noviny – přehled za duben 2024
Jaderné noviny – přehled za březen 2024
Jaderné noviny – přehled za únor 2024
Jaderné noviny – přehled za leden 2024
Jaderné noviny – přehled za prosinec 2023

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