Portál AbcLinuxu, 6. května 2025 20:45
Aktuální verze jádra: 2.6.37-rc4. Citáty týdne: Ingo Molnár, Andrew Morton. Omezení přístupu k /proc/kallsyms. Struktury a úniky informací. Jádro a C knihovna jako jediný projekt.
Současné vývojové jádro je 2.6.37-rc4 vydané 29. listopadu. Přesně jak jsem očekával. Strávil jsem většinu týdne v Japonsku a někteří vývojáři radostně zvolali 'pošleme Linusovi patche, dokud se nevzpamatoval z časového posunu, a uvidíme, jestli ho budeme schopni zmást víc než obvykle.' V důsledku toho má -rc4 přibližně dvakrát tolik commitů oproti -rc3. I tak se nicméně většinou jedná o opravy; v oznámení je zkrácený changelog, všechny detaily najdete v kompletním changelogu.
Stabilní aktualizace: během minulého týdne žádné nevyšly.
-- Ingo Molnár
napsal Jonathan Corbet, 1 prosince 2010
Během začleňovacího okna byla začleněna změna, která neprivilegovaným uživatelům ve výchozím nastavení zabrání číst /proc/kallsyms. Tato změna byla následně zrušena, protože se ukázalo, že rozbije bootování starší verze Ubuntu. Vrací se tedy nová podoba patche, která problém opravuje – ale která možná také nebude začleněna.
Nový patch je poměrně jednoduchý: jestliže proces, který soubor čte, postrádá kvalifikaci CAP_SYS_ADMIN, /proc/kallsyms bude prázdný soubor. Bylo potvrzeno, že tato verze patche uživatelský prostor již nepoškozuje, jsou tu ale stále stížnosti: místo omezení přístupu k souboru pomocí obvyklých bitů pro řízení přístupu, patch do jádra zabuduje politiku (CAP_SYS_ADMIN), kterou nelze změnit. To mnoha lidem nesedí, takže patch pravděpodobně také nebude začleněn. Místo toho mohou administrátoři (nebo distributoři) jednoduše změnit práva při bootu.
napsal Jonathan Corbet, 1 prosince 2010
Mnoho nahlášených bezpečnostních slabin v jádře jsou úniky informací – předání obsahu neinicializované jaderné paměti do uživatelského prostoru. Tyto úniky se obvykle nepovažují za vážné problémy, ale potenciál pro potíže tu existuje vždy. Útočník by mohl být schopen najít sekvenci operací, které by mohly vložit užitečné informace (například kryptografický klíč) na místo, odkud ho jádro předá. Únikům je tedy třeba se vyhýbat a jsou rutinně opravovány, když se na ně přijde.
Mnoho úniků je způsobeno neinicializovanými členy struktur. Je jednoduché zapomenout přiřadit do všech členů, postupem času se podoba struktury také může změnit. Jednou možností, jak se této možnosti vyhnout, je použít něco jako memset() a hned zezačátku celou strukturu vynulovat. Jaderný kód memset() používá na mnoha místech, ale někde je to považováno za drahé a zbytečné; proč nulovat kus paměti, když se do ní stejně bude přiřazovat?
Jeden způsob, jak kombinovat operace inicializace struktury, je tento:
struct foo { int bar, baz; } f = { .bar = 1, };
V tomto případě se baz implicitně nastaví na nulu. Tato deklarace by měla zajistit, že daná struktura se nebude podílet na žádném úniku informací. A nebo taky ne – uvažme následující:
struct holy_foo { short bar; long baz; }
Na 32bitovém systému bude tato struktura pravděpodobně obsahovat dva byty dlouhou mezeru mezi členy. Ukazuje se, že standard C nevyžaduje, aby překladač inicializoval díry; a GCC je opravdu nechává neinicializované. Takže pokud není jisté, že daná struktura nemůže mít na žádné relevantní architektuře díry, inicializace struktury není spolehlivým způsobem, jak se vyhnout neinicializovaným datům.
Mluvilo se o tom požádat vývojáře GCC o to, aby toto chování změnili a inicializovali i díry, ale jak upozornil Andrew Morton, to by přinejmenším následujících pět let nepomohlo; stále by se používaly staré překladače. Zdá se tedy, že když se inicializují struktury, které budou předány uživatelskému prostoru, žádná alternativa k memset() neexistuje.
napsal Jonathan Corbet, 30 listopadu 2010
Jádro bylo v historii vyvíjeno nezávisle na čemkoliv, co běží v uživatelském prostoru. Dobře definované jaderné ABI vybudované okolo standardu POSIX umožnilo téměř absolutní separaci jádra od zbytku systému. Linux je nicméně svým oddělením vývoje jádra a uživatelského prostoru téměř unikátní. Proprietární operační systémy byly vždy spravovány jako jediný projekt obsahující jádro i uživatelský prostor; ostatní svobodné operační systémy (například BSD) tak fungují také. Měl by Linux použít integrovanější přístup?
Patch křížového propojení paměti od Christophera Yeoha zde byl popisován v září. Christopher nedávno zaslal novou verzi patche a přitom položil otázku, jak by mohl dostat jinou odpověď než mlčení. Andrew Morton odpověděl, že nová systémová volání je čím dál tím těžší do jádra dostat:
Ingo Molnár skočil do diskuze s tím, že skutečným problémem je C knihovna (libc). Dostat do jádra novou vlastnost a tu k uživatelům trvá poměrně dlouho. Ale dostat podporu pro nová systémová volání do C knihovny podle všeho trvá mnohem déle. A mezitím se systémová volání nepoužívají. Je možné, když je vývojář dostatečně motivován, zavolat nepodporované volání pomocí syscall(), ale tento přístup je nešikovaný, specifický pro Linux a není portovatelný mezi architekturami (protože čísla systémových volání se mezi architekturami mohou měnit.) Většinou tedy syscall() používají jenom jaderní vývojáři, kteří nová systémová volání testují.
Ingo ale řekl, že tak to být nemusí:
Ingo pokračoval v popisu některých výhod, které by měla zabudovaná libc. Na seznamu je na prvním místě možnost měnit standardní funkce libc tak, aby se využívala nová systémová volání hned, když jsou k dispozici; aplikace by potom okamžitě měly přístup k novým voláním. Bylo by možné přidat sledovací nástroje, což by nakonec propojilo libc a jaderné sledování. S asynchronním I/O by možná bylo možné udělat něco lepšího, atd. Uzavřel tvrzením, že Apple a Google/Android chápou, že mentalita jediného projektu hodně pomáhá. My ještě ne.
V době psaní tohoto článku na jeho návrh nikdo neodpověděl. Buď je příliš fantastický, nebo nikdo nečte vlákno o křížovém připojení paměti. Ale je to dost zajímavý nápad, aby se mu stálo za to věnovat.
V prvních dnech vývoje linuxového jádra bylo účelem vytvořit implementaci dobře zavedeného standardu, podle kterého bylo již napsáno mnoho aplikací. Existoval prostor pro diskuzi o tom, jak by mohlo specifické systémové volání být implementováno mezi C knihovnou a jádrem, ale základní povaha úkolu byla dobře dána. Dnes Linux nechal POSIX daleko za sebou; standard je plně implementován a každá nová funkcionalita jde za něj. Nová systémová volání jsou tedy jasně mimo POSIX, takže jejich využívání bude vyžadovat změny v uživatelském prostoru, které například lepší implementace open() potřebovat nebude. Nové vlastnosti jsou ale viditelné, jenom když libc zareaguje a začne je používat a zpřístupňovat je aplikacím. V tomto ohledu knihovna, kterou většina z nás používá (glibc), není zrovna proslavená rychlou odezvou.
Změnit libc na rozšíření jádra by současného prostředníka v podobě knihovny vyřadilo. Jaderní vývojáři by mohli zapojit nová systémová volání okamžitě; ta by tak byla k dispozici aplikacím ve stejnou dobu jako jádro samo. Tyto dvě komponenty by tak postupem času společně fungovaly lépe. Libc spojená s jádrem by také umožnila zbavit se spousty kódu pro kompatibilitu, který je nutný, pokud je potřeba pracovat s mnoha verzemi jádra zároveň. Pokud by všechno šlo dobře, mohli bychom mít více integrovanou libc, která by nabízela více funkcionality a lepší výkonnost.
Taková snaha by samozřejmě vyvolala některé zajímavé otázky, počínaje „kterou libc?“ Zjevným kandidátem by byla glibc, ale to je velký kus kódu, který ne všichni mají rádi. Ať už by byla vybrána kterákoliv verze libc, její vývojáři by mohli chtít do jejích záležitostí mluvit; nemuseli by okamžitě uvítat své nové jaderné vládce. Jeden by doufal, že nebude narušena možnost používat systém s alternativní C knihovnou. Zrychlení tempa vývoje by mohlo přinést nové možnosti, ale je tu také vždy přítomná možnost zatáhnout nové regrese. A licencování by mohlo přinést další problémy; integrovaná libc by musela být dostatečně oddělena, aby mohla mít jinou licenci.
A měla by se položit otázka, kde se tento proces má zastavit. Vložit do jaderného repozitáře nethack by mohlo projít, ale dá se předpokládat, že Emacs by již narazil na odpor, a na LibreOffice pravděpodobně můžeme zapomenout rovnou.
Je tedy zapotřebí někde nakreslit čáru. Podobné nápady se v minulosti již objevily a vždycky bylo výsledkem to, že čára zůstala na svém místě: na hranici mezi jádrem a uživatelským prostorem. Tato hranice byla nicméně narušena začleněním perfu do jaderného repozitáře. Podle většiny měřítek byl experiment s perfem úspěch; během překvapivě krátké doby se vyvinul z kostrbaté utility do mocného nástroje. Možná by integrovaná C knihovna byla stejně zajímavým experimentem. Provést tento experiment nicméně znamená spoustu práce; dokud se neobjeví někdo, kdo by tuto práci chtěl odvést, nebude se jednat o nic víc než o experiment myšlenkový.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.