Portál AbcLinuxu, 26. dubna 2024 20:36

Jaderné noviny – 5. 5. 2011: Filtrování systémových volání se seccomp

16. 5. 2011 | Jirka Bourek
Články - Jaderné noviny – 5. 5. 2011: Filtrování systémových volání se seccomp  

Aktuální verze jádra: 2.6.39-rc6. Citáty týdne: Russell King, Borislav Petkov, Linus Torvalds. Davové šílenství záznamů o adresářích. Čisté události a ABI perf. Rozšíření seccomp.

Obsah

Aktuální verze jádra: 2.6.39-rc6

link

Současné vývojové jádro je 2.6.39-rc6 vydané 3. května. Linus řekl:

Stále řešíme nějaké chyby, ale myslím si, že pro -rc6 je to ok. Poslední -rc to nebude, ale vypadá to, že není ve špatném stavu. Kdo jste posílal hlášení o regresích, zkuste, prosím, jestli byly opraveny. Kdo žádné neposlal, testujte.

Všechny detaily vizte v kompletním changelogu.

Stabilní aktualizace: 2.6.38.5 (2. května), 2.6.35.13 (28. dubna) a 2.6.27.59 (30. dubna). Každé obsahuje dlouhý seznam důležitých oprav.

Citáty týdne: Russell King, Borislav Petkov, Linus Torvalds

link

Ať ARM v hlavní řadě shnije. Mně už je to jedno.

-- Russell King

Ne, nechám to tam, aby na ně dýchl duch minulosti a oni se pak mohli chlubit na budoucím slashdotu nebo v ((LWN++)..)++, že opravili nejstarší bug v Linuxu, když ho bootovali na kvantovém x86 počítači a pokoušeli se spustit vlastního RAS démona.

-- Borislav Petkov

Ano, programování open source je týmový sport, ale skutečně důležitá je schopnost najít ty správné lidi (to samé samozřejmě platí pro jádro – myslím si, že máme opravdu skvělé správce. Možná si na ně stěžuji a jsem trochu nechvalně proslulý svými flamy, když věci nefungují, ale i tak si myslím, že na správě jádra pracují jedni z nejlepších.)

-- Linus Torvalds

Davové šílenství záznamů o adresářích

link

napsal Jonathan Corbet, 4. května 2011

Jak se ukázalo na Filesystem, storage, and memory management summitu 2011, je čím dál tím větší zájem omezit množství jaderné paměti, kterou smí skupiny procesů využívat. Jednou z oblastí, o kterou je obzvlášť zájem, je cache záznamů o adresářích [directory entry, dentry]; škodlivý program by mohl vytvořením dostatečně hluboké adresářové hierarchie vypotřebovat všechnu paměť jádra, kterou by zabrala cache dentry. Omezit velikost této cache je tedy lákavé obzvláště pro ty, kdo chtějí zajistit, aby kontejnery běžící na linuxových systémech neomezovaly jeden druhý.

Patche správy dcache pro jednotlivé kontejnery, jejichž autorem je Pavel Emelyanov, jsou prvním pokusem, jak využívání dentry omezit. Patch funguje tak, že se jednotlivé dentry organizují do „davů“ [mob], což jsou skupiny dentry, které všechny reprezentují jména ve specifickém podstromě v souborovém systému. Pokud bude kořenem davu kořen souborového systému jmenného prostoru kontejneru, všechny dentry vytvořené v tomto kontejneru by byly obsaženy v daném davu. V tu chvíli lze aplikovat jednoduché omezení využívání zdrojů: přidání dentry do davu, který má maximální velikost, vyžaduje odebrání jiné dentry. Pokud nelze žádnou odstranit, pokusy přidávat další selžou.

Patch přidává tři nová volání ioctl(): FIMOBROOT vytvoří nový dav v daném místě v souborovém systému, FIMOBSIZE nastaví maximální velikost davu a FIMOBSTAT se dotazuje na jeho současnou velikost. Pavel se za toto rozhraní trochu omlouval; podle všeho očekává, že se bude muset změnit, než ho bude možné začlenit do upstreamu. Prvním krokem je nicméně diskuze o konceptu; na patche zatím nikdo nereagoval.

Čisté události a ABI perf

link

napsal Jonathan Corbet, 3. května 2011

Subsystém pro události perf často vypadá, že je na cestě ovládnout jádro; velká část vývojové aktivity probíhá právě tam a stal se z něj určitý druh obecného mechanismu pro hlášení událostí. Původním účelem událostí výkonnosti [perf events] bylo poskytnout přístup k čítačům sledování výkonnosti [performace monitoring counters], které jsou k dispozici v hardware, a za tímto účelem se stále používá. Začlenění perfu bylo trochu hořkou pilulkou pro ty, kdo používali alternativní nástroje pro sledování výkonnosti, ale většina z nich ji už spolkla. Nedávná diskuze o událostech „mimo jádra“ [offcore] ukazuje, že v této oblasti stále zbývají nějaké věci, o které se lze hádat, i když každý pravděpodobně nakonec dostane to, co chce.

Jednotka pro sledování výkonnosti [performance monitoring unit, PMU] je obvykle spojena s CPU; každý proces má svojí PMU, která sleduje události specifické pro dané CPU. Některé novější procesory (jako je série Nehalem od Intelu) nicméně také mají PMU, která není spojena s žádným CPU; v případě Nehalemu je součástí „nejádra“ [uncore], které se stará o přístupy k paměti na úrovni celého pouzdra. Tato PMU mimo jádra má k dispozici úhel pohledu, který poskytuje lepší možnosti sledování celkového chování systému, co se paměti týče. Je tedy zájem získat informace o těchto událostech, současná jádra k nim ale přístup neumožňují.

Jádro 2.6.39-rc chvíli přístup k těmto událostem poskytovalo od doby, kdy byl v březnu začleněn patch od Andiho Kleena. Jeden kousek – patch, který by do nástroje perf pro uživatelský prostor přidal přístup k této funkcionalitě – ale chyběl. Koncem dubna došlo k pokusu začlenit tento kousek, ale nepřineslo to žádané výsledky; místo začleňování dalších změn správce perfu Ingo Molnár úplně odstranil možnost přistupovat k mimojaderným událostem.

Není potřeba říkat, že tato akce vedla u uživatelů perfu k nespokojenosti; někteří vývojáři tyto události již začali používat. To by normálně bylo považováno za regresi a patch by byl vzat zpět, ale protože se tato funkcionalita nikdy neobjevila ve finální verzi jádra, nelze její absenci považovat za regresi. To je samozřejmě důvod, proč byla odstraněna.

Ingova stížnost byla jasná: rozhraní pro tyto události je příliš nízkoúrovňové a těžko se používá. Odmítnutý patch obsahoval příklad, který vypadal nějak takto:

perf stat -e r1b7:20ff -a sleep 1

Nezkušeným čtenářům bude samozřejmě odpuštěno, když okamžitě neví, že tento příkaz by sledoval přístup ke vzdálené DRAM – paměti hostované v jiném socketu. Ingo tvrdil, že je potřeba, aby tuto vlastnost bylo snazší použít, například příkazem (z patche, který vlastnost odebíral):

perf record -e dram-remote ./myapp

Také řekl:

Tato úroveň použitelnosti je nicméně naprosto neakceptovatelná – od uživatelů se nedá očekávat, že budou vypisovat pro CPU a model specifická zaříkadla, aby měli přístup k užitečným funkcím hardware.

Správným řešením je zpřístupnit mimojadernou funkcionalitu zobecněnými událostmi – tak uživatele nebude muset zajímat, který model CPU používají, budou moci použít konceptuální událost a ne nějaké podivné pro model specifické hexadecimální číslo.

Klíčové je zde volání po „zobecněné události“, která bude v jádře mapována na ten čítač, který je k dispozici na používaném hardware a ze kterého se informace získají. Uživatel se nebude muset starat o přesný typ procesoru, na kterém běží, a nebude se muset přehrabovat v datasheetu, aby zjistil, která čísla mu poskytnou správné výsledky.

Kritika tohoto přístupu měla několik podob. Zobecněné události jsou prý pěkné, ale nikdy nebudou moci reflektovat všechny podivné a pro hardware specifické čítače, které poskytují jednotlivé procesory. Tyto události by také měly být spravovány v uživatelském prostoru, kde je k dispozici větší flexibilita a není potřeba zvětšovat jádro. Objevily se nějaké stížnosti na to, že některé existující zobecněné události nebyly na všech architekturách implementovány korektně. A říká se, že vždy budou lidé, kteří chtějí vědět, co je ve specifickém hardwarovém čítači, aniž by je jádro zobecněním o tuto informaci připravilo. Jak řekl Vince Weaver:

Blokovat přístup k čistým [raw] událostem je špatný nápad. Celá tahle věc s „obecnými událostmi“ v jádře by se měla vyhodit. Občas se používají špatné události (vizte události skoků na AMD o pár verzí zpátky, teď události cachí v Nehalemu). Tohle všechno patří do uživatelského prostoru, což se říkalo už zezačátku. Jádro nemá co říkat uživatelům, které události jsou zajímavé, nebo je nějak omezovat!

Ingo odpověděl, že informace a techniky spojené se sledováním výkonnosti mají být koncentrovány na jednom místě:

No, myslím si, že uživatelům nejvíce pomůže, když přidáme užitečné vysokoúrovňové vlastnosti PMU a ne jenom neprůhledný engine pro předávání nezpracovaných událostí. Problém s nízkoúrovňovými ABI je v tom, že prostor nástrojů se fragmentuje na milion malých hacků a nikde se nehromadí know-how. Chci, aby se umění měření výkonnosti zobecnilo, jak nejlépe to půjde.

Vince mezitím pokračoval tvrzením, že perf je znovuvynalezené kolo, které ignorovalo spoustu zkušeností zabudovaných do předchůdců. Po událostech té doby, zdá se, stále zůstávají jizvy. Thomas Gleixner nesouhlasil s tvrzením, že perf znovuvynalézá kolo, ale řekl, že si myslí, že čisté události by měly být přístupné také:

Problém, který zapálil tenhle flame, je rozhodně na hranici a nesouhlasím s Ingem, že by události neměly být k dispozici v čisté podobě. Jedná se o vlastnost, která podporuje hardware a která může být užitečná, i když pro to tools/perf nemá podporu a není pro to obecná událost. Jedná se o dvě odlišné záležitosti. Perf vždy umožňoval používat čisté události a nevidím důvod, proč bychom to v tomto případě dělat neměli, když je podmnožina uživatelské základny perfu dokáže využít.

Ukazuje se, že ani Ingo nemá s čistými událostmi problém. Jenom má obavy, aby se přístup k čistým událostem nestal primárním prostředkem, jakým bude většina uživatelů tyto čítače používat. Proto je teď blokuje ze dvou důvodů: prvním z nich je, že chce, aby zobecněný kód byl k dispozici první, aby ho uživatelé považovali za normální způsob, jak k mimojaderným událostem přistupovat. Když nikdy nebude zapotřebí řešit hexadecimální zaklínadla, většina vývojářů v uživatelském prostoru to dělat nebude – jejich příkazy a kód pak nakonec budou fungovat i na dalších procesorech.

Dalším důvodem, proč byly čisté události zablokovány, je, že i když rozhraní pro tyto události je promyšlené, ABI, kterým se předávají do uživatelského prostoru, se možná bude muset změnit. Uvolnění původního ABI ve stabilním jádře by ho téměř určitě zabetonovalo obzvláště vzhledem k tomu, že lidé ho už používali. Odložením těchto události o jeden cyklus (někdo určitě přijde na způsob, jak je exportovat už v 2.6.40) se Ingo chce vyhnout tomu zaseknout se u druhořadého rozhraní, které bude nutné podporovat navždy.

Není pochyby, že to některým vývojářům ztěžuje život – proces vývoje jádra může být někdy protivný. Doufá se nicméně, že když budeme věci dělat takto, povede to na jádro, za kterého budou všichni za pět let šťastnější. Jestliže věci takhle zafungují, většina z nás by měla být schopna vypořádat se s trochou frustrace ze zdržení o jeden cyklus.

Rozšíření seccomp

link

napsal Jake Edge, 4. května 2011

Mít možnost vložit procesy na pískoviště [sandbox], odkud by nesměly volat „nebezpečná“ systémová volání, je atraktivní vlastnost, která již v omezené míře byla v Linuxu implementována pomocí seccomp. Před dvěma roky jsme se dívali na návrh, jak seccomp rozšířit a umožnit jemnější kontrolu nad tím, která systémová volání povolit. Návrh od té doby víceméně ležel v klidu, ale nedávno byl vzkříšen zpracováním některých tehdejších návrhů. Reakce na současný návrh vypadají kladně a možná uvidíme tah na bránu, který předchozí sada patchů postrádala.

Seccomp (z „secure computing“ – bezpečné zpracování) se zapne voláním prctl() a když je zapnut, proces již nemůže používat žádná systémová volání kromě read(), write(), exit() a sigreturn() – všechna ostatní proces ukončí.

Tím vznikne poměrně bezpečné pískoviště, které je ale také extrémně omezené, protože někteří vývojáři by v něm chtěli dělat i další věci. Webový prohlížeč Chromium dokonce věnoval spoustu snahy vlastní implementaci seccomp, která rozšiřuje povolená systémová volání pomocí různých obezliček.

To vedlo Adama Langleyho z týmu Chromia k návrhu přidat bitovou masku povolených systémových volání pro nový režim seccomp. To by procesům umožnilo binární volbu (povoleno/zakázáno) pro každé systémové volání. V dané době Ingo Molnár navrhl použít kód filtrů v Ftrace, aby rozhraní bylo ještě flexibilnější a umožnilo filtrovat parametry systémových volání. V podstatě by tak pro každé systémové volání byly tři možnosti: povoleno, zakázáno nebo filtrováno.

Rychlý přesun do současnosti a přesně to sada patchů, jejíž autorem je Will Drewry, implementuje. Nemělo by být překvapením, že Ingo byl potěšen tím, že z jeho nápadu vzešel funkční kód: Ok, jsem ohromen – AFAICS jsi implementoval moje návrhy [...] a funguje to v praxi!. Na Erica Parise kód také udělal dojem, Eric poznamenal, že rozšířený seccomp by bylo možné použít pro QEMU. Ingo a Eric se neshodli o tom, jestli nahradit přístup s LSM pomocí filtrů, ale to byla postranní diskuze. Serge E. Hallyn upozornil na to, že nová vlastnost by mohla být užitečná pro kontejnery: mohla by zmírnit důsledky faktu, že v hostiteli sdílí stejné jádro.

Navržené rozhraní, které se podle komentářů v diskuzi pravděpodobně změní, vypadá takto.

const char *filters[] =
  "sys_read: (fd == 1) || (fd == 2)\n"
  "sys_write: (fd == 0)\n"
  "sys_exit: 1\n"
  "sys_exit_group: 1\n"
  "on_next_syscall: 1";
prctl(PR_SET_SECCOMP, 2, filters);

Příklad pochází z Willovy dokumentace, která je součástí patchů. Umožní číst ze dvou popisovačů souboru (1 a 2) a zapisovat do jednoho (0), dále povolí jakékoliv použití dalších dvou vyjmenovaných systémových volání. on_next_syscall znamená, že pravidla nebudou vynucována, dokud neproběhne ještě jedno systémové volání. To rodiči umožní zavolat fork(), nastavit v procesu potomka seccomp pískoviště a poté pomocí exec spustit další program, pro který již budou platit nová pravidla.

Ten kousek s on_next_syscall přitáhl několik komentářů. Ukázalo se, že je ve skutečnosti potřeba vypořádat se pouze se dvěma případy – pravidla je buď potřeba uplatnit okamžitě (pro proces, který se chce omezit před zpracováním nedůvěryhodného vstupu), nebo se mají uplatnit po exec (pro rodiče, který spouští nedůvěryhodného potomka). Věci pravděpodobně míří ke změně, po které bude výchozí „po exec“ s možností vyžádat si okamžitý vstup pravidel v platnost.

Také padly otázky ohledně jmen vnitřních jaderných symbolů jako sys_read. Exportovat je jako jaderné ABI pravděpodobně neprojde, protože by to do budoucna mohlo omezit možnost změn jmen těchto funkcí – nebo vynutit zaneřáděnou vrstvu kompatibility, pokud by změna byla nutná. Will se narozdíl od Adamových patchů chtěl vyhnout používání čísel systémových volání, ale jak upozornil Frederic Weisbecker, tato čísla jsou již součástí jaderného ABI. Will tedy plánuje začít je používat také a uživatelé rozhraní budou muset použít hlavičkový soubor unistd.h nebo knihovnu, která bude mapovat jména systémových volání na jejich čísla.

Patche také modifikují soubor /proc/PID/status, aby vypsal existující filtry, které jsou na proces aplikovány. Vzhledem k tomu, že většina aplikací, která tento soubor čte, tyto informace nepotřebuje, navrhl Motohiro Kosaki, aby seccomp dostal svůj vlastní soubor. Will plánuje dané informace poskytnout v /proc/PID/seccomp_filter a ze status je odstranit.

Vzhledem k tomu, že patche používají háčky a infrastrukturu Ftrace, nový režim seccomp funguje jenom pro ta systémová volání, se kterými jsou spojeny události Ftrace. Použití některého z neosazených systémových volání povede na návratovou hodnotu EINVALprctl(). Povolení CONFIG_SECCOMP_FILTER (což závisí na CONFIG_FTRACE_SYSCALLS) umožní nový režim používat.

Celkově byl Will velmi vstřícný, co se návrhů na změny týče, a odezva na daný koncept byla jednotná a kladná. Ingo navrhl rozdělit filtrovací engine Ftrace na menší kusy – za minimální změny, které dělají Willovy patche – aby ho bylo možné šířeji používat v celém jádře. Položil nicméně otázku, jestli by Linus Torvalds nebo Andrew Morton měli námitky k širšímu používání filtrovacích mechanismů: máte chlapi koncepčně něco proti těmto flexibilním a dynamickým filtrům? Myslím si, že bychom se měli hodně zamyslet nad ABI, protože by se to mohlo snadno rozšířit i na další aplikace kromě Chrome/Chromia. Na otázku nicméně zatím neodpověděl ani jeden.

V současnosti se zdá, že Will pracuje na další revizi sady patchů a rozhodně to nevypadá jako něco, co by mohlo být začleněno v blížícím se cyklu 2.6.40. Jak poznamenal Ingo, ABI je potřeba promyslet pečlivě a stále jsou tu nějaké záležitosti okolo RCU, které jsou diskutovány. Pravděpodobně bude také potřeba nějaký čas ve stromě -next, ale pokud nevyraší nějaké významné stížnosti, najde si tato vlastnost nejspíš relativně rychlou cestu do hlavní řady. I když to Chromiu neumožní okamžitě zahodit to komplikované uspořádání, které používá nyní, za pár let to tak možná bude. A další aplikace budou mít z rozšířeného seccomp prospěch také.

Související články

Kernel coverage at LWN.net: May 5, 2011

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

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
Jaderné noviny – přehled za listopad 2023

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