Privilegované programy Set-UID

Obsah

  1. 1. Ako funguje mechanizmus Set-UID
  2. 2. Zraniteľnosti Set-UID programov
  3. 3 Zvyšovanie bezpečnosti Set-UID programov
  4. 4 Princíp najmenších oprávnení

Lecture Notes (Syracuse University)

Hlavným zameraním tejto prednášky je diskutovať o privilegovaných programoch, prečo sú potrebné, ako fungujú a aké bezpečnostné problémy so sebou prinášajú. Privilegovaný program je taký program, ktorý dokáže používateľom udeliť dodatočné oprávnenia nad rámec tých, ktoré už majú pridelené. Napríklad webový server je privilegovaný program, pretože umožňuje vzdialeným používateľom pristupovať k zdrojom na strane servera; Set-Root-UID program je privilegovaný program, pretože počas svojho behu umožňuje používateľom získať oprávnenia roota.

V tejto prednáške sa zameriavame na mechanizmus Set-UID a používame ho ako prípadovú štúdiu. Mnohé z bezpečnostných princípov, o ktorých tu hovoríme, sa však vzťahujú aj na ostatné privilegované programy.

1. Ako funguje mechanizmus Set-UID

Motivácia

– Chcete, aby iní ľudia mohli vo vašom súbore vyhľadávať slová, no nechcete, aby si ho mohli prečítať celý. Ako to dosiahnuť?
– Heslá používateľov sú uložené v súbore /etc/shadow
– Pri Set-UID programoch je efektívne uid vlastníkom pdow, ktorý bežní používatelia nemôžu ani čítať, ani doň zapisovať. Program passwd im však umožňuje meniť si svoje heslo. Keď teda používatelia spustia passwd, môžu zrazu upraviť /etc/shadow. Navyše, používatelia môžu upraviť iba jednu položku v /etc/shadow, a nie položky iných ľudí. Ako sa to dosahuje?

Set-UID programy

  • Koncept efektívneho UID a reálneho UID.
  • Pri programoch, ktoré nie sú Set-UID, sú efektívne UID a reálne UID rovnaké.
  • Pri Set-UID programoch sa efektívne UID mení na vlastníka programu, zatiaľ čo reálne UID zostáva totožné s používateľom, ktorý program spustil.

Efektívne user UID a reálne user UID

– Pri prihlásení sa reálne user ID, efektívne user ID a uložené (saved) user ID prihlasovacieho procesu nastavia na prihlasovacie ID používateľa, ktorý proces vytvoril. To isté platí aj pre reálne, efektívne a uložené group ID; nastavia sa na group ID daného používateľa.


– Keď proces zavolá niektorú z funkcií z rodiny exec na spustenie súboru (programu), user a/alebo group identifikátory priradené k danému procesu sa môžu zmeniť. Ak je spúšťaný súbor set-user-ID súborom, efektívne a uložené user ID procesu sa nastavia na vlastníka spúšťaného súboru. Ak je spúšťaný súbor set-group-ID súborom, efektívne a uložené group ID procesu sa nastavia na skupinu spúšťaného súboru. Ak spúšťaný súbor nie je ani set-user-ID, ani set-group-ID súborom, efektívne user ID, uložené user ID, efektívne group ID a uložené group ID sa nemenia.


– Riadenie prístupu (access control) je založené na efektívnych user ID a group ID.
– Prečo musia byť programy passwd, chsh a su Set-UID programami?
– Existujú v systéme Windows NT/2000 Set-UID programy? Ak nie, ako sa tam rieši rovnaký problém?
– Windows nepozná koncept Set-UID. Rovnaký problém sa rieši iným mechanizmom: vývojár môže privilegovaný program napísal ako službu (service) a používateľ argumenty príkazového riadka posiela tejto službe pomocou Local Procedure Call (LPC).
– Službu je možné spustiť automaticky alebo na vyžiadanie.
– Každá služba má bezpečnostný deskriptor (security descriptor), ktorý určuje, ktorí používatelia ju môžu spúšťať, zastavovať a konfigurovať.
– Služby zvyčajne bežia pod účtom Local System

Ako zapnúť Set-UID bit?

% chmod 4755 file ---> -rwsr-xr-x

Ako je Set-UID implementovaný v Minixe?

/* This is the per-process information */ 
EXTERN struct fproc { 
uid_t fp_realuid; /* real user id */ 
uid_t fp_effuid; /* effective user id */ 
gid_t fp_realgid; /* real group id */ 
gid_t fp_effgid; /* effective group id */ 
... 
}

– Škodlivé použitie mechanizmu Set-UID:
– Útočník dostane na 10 sekúnd prístup k vášmu účtu. Dokáže si nainštalovať zadné vrátka (backdoor), aby sa neskôr mohol vrátiť do vášho účtu?

% cp /bin/sh /tmp 
% chmod 4777 /tmp/sh

– Vykonaním vyššie uvedeného útočník vytvorí Set-UID shell program, ktorého vlastníkom ste vy. Keď teda útočník tento shell program neskôr spustí, pobeží s vašimi oprávneniami.

Otázky:

– Môže bežný používateľ debugovať Set-Root-UID program?
– Môže bežný používateľ pomocou chown zmeniť vlastníka súboru na ľubovoľného iného používateľa?

2. Zraniteľnosti Set-UID programov

2.1 Skryté vstupy: premenné prostredia

Privilegovaný program musí vykonávať kontrolu zdravého rozumu (sanity check) na všetkých vstupoch. Validácia vstupov je v skutočnosti súčasťou riadenia prístupu, ktoré musí privilegovaný program vykonávať, aby zaistil svoju bezpečnosť. Veľa bezpečnostných problémov je spôsobených chybami práve pri validácii vstupov.

Ak sú vstupy v programe explicitné, programátori si na validáciu vstupov spomenú; ak sú vstupy implicitné, na validáciu vstupov sa môže zabudnúť, pretože si programátori nemusia byť vedomí ich existencie. Premenné prostredia (environment variables) sú práve takýmto typom vstupov.

Každý UNIXový proces beží v určitom prostredí. Prostredie pozostáva z tabuľky premenných prostredia, z ktorých má každá priradenú hodnotu. Niektoré programy tieto premenné prostredia interne využívajú; príkladom takýchto programov sú shell programy. Inými slovami, hodnota niektorých premenných prostredia môže ovplyvniť správanie shell programu.

Keďže premenné prostredia riadi používateľ, ak sa program o tieto premenné opiera, používatelia môžu nepriamo ovplyvniť správanie takéhoto programu zmenou hodnôt niektorých premenných prostredia. Preto je veľmi dôležité pochopiť, či sa daný privilegovaný program spolieha na hodnoty niektorých premenných prostredia. Jedným zo spôsobov, ako môžu premenné prostredia program ovplyvniť, je explicitné použitie ich hodnôt priamo v programe. V jazyku C môže program pristupovať k hodnotám premenných prostredia pomocou funkcie getenv(). Existuje však aj mnoho prípadov, keď program používa premenné prostredia implicitne; a práve tam sme videli mnohé zraniteľnosti v Set-UID programoch. V tejto časti uvedieme niekoľko príkladov.

Premenná prostredia PATH

– Pri spúšťaní príkazu v shelli shell vyhľadá daný príkaz pomocou premennej prostredia PATH, ktorá obsahuje zoznam adresárov. Shell program prehľadá tento zoznam adresárov (v rovnakom poradí, v akom sú uvedené v PATH). Spustí sa prvý program, ktorého názov sa zhoduje s daným príkazom.

– Čo by sa stalo v nasledujúcom prípade? Všimnite si, že knižničná funkcia system (const char *cmd) najprv spustí program /bin/sh a následne nechá shell program vykonať cmd.
system ("mail");

– Útočník môže zmeniť PATH nasledovne, a tým spôsobiť, že sa namiesto očakávaného programu spustí „mail“ nachádzajúci sa v aktuálnom adresári.
PATH=".:$PATH"; export PATH

– V analógii so supermanom: ak inštrukcia supermanovi hovorí „odboč doľava“ (zlí chlapi sú vľavo a dobrí vpravo, a vy máte zaútočiť na zlých chlapov). Ak útočníci vedia presne, kedy a kde sa táto inštrukcia „odboč doľava“ vykoná, môžu vykonať útok podobný tomu vyššie, pretože „vľavo“ je relatívny smer, nie absolútny. Ak útočníci vopred na miesto, kde máte odbočiť doľava, umiestnia rotačné zariadenie, ktoré vás po nastúpení naň otočí o 180 stupňov, odbočenie „doľava“ sa v skutočnosti stane odbočením tam, kde stoja dobrí chlapi. Ak sa budete riadiť inštrukciami, skončíte útokom na dobrých chlapov.

Premenná prostredia IFS

– Premenná IFS určuje znaky, ktoré sa majú interpretovať ako medzery. Je to skratka pre
Internal Field Separators (interné oddeľovače polí). Predpokladajme, že ju nastavíme tak, aby
zahŕňala znak lomky:

IFS="/ \t\n"; export IFS
PATH=".:$PATH"; export PATH

– Teraz zavolajte akýkoľvek program, ktorý z Bourne shellu používa absolútnu cestu PATH
(napr. system()). Toto sa teraz interpretuje nasledovne, čo by sa pokúsilo spustiť príkaz s
názvom bin v aktuálnom adresári používateľa.

system("/bin/mail root"); ---> system(" bin mail root");

– Chyba súvisiaca s IFS je v dnešných shelloch už do veľkej miery zablokovaná: novo spustený
shell proces premennú IFS už nededí.
– V príbehu o supermanovi: superman si je vedomý rizika používania „odboč doľava“ v
inštrukcii, preto ju zmení na „odboč na sever“, čo je teraz absolútny smer. Aj to je však stále
zraniteľné, pretože „sever“ určuje magnetické pole, ktoré môže byť bohužiaľ narušené
magnetom, ktorý útočníci umiestnia nablízko.

Premenná prostredia LD_LIBRARY_PATH

– V Linuxe sú, pokiaľ nie je explicitne pri kompilácii použitá voľba -static, všetky programy
neúplné a pri behu vyžadujú ďalšie prepojenie s dynamickými knižnicami. Dynamický
linker/loader ld.so/ld-linux.so načíta zdieľané knižnice, ktoré program potrebuje, pripraví
program na spustenie a následne ho spustí. Pomocou nasledujúceho príkazu môžete zistiť, od
akých zdieľaných knižníc daný program závisí:

% ldd /bin/ls

– LD_LIBRARY_PATH je premenná prostredia, ktorú používa dynamický linker/loader (ld.so a
ld-linux.so). Obsahuje zoznam adresárov, v ktorých má linker/loader hľadať pri vyhľadávaní
zdieľaných knižníc. Je možné uviesť viacero adresárov oddelených dvojbodkou (:). Tento
zoznam sa pripojí pred existujúci zoznam vopred nakompilovaných ciest loadera pre daný
spustiteľný súbor a pred systémové predvolené cesty loadera.

– Prakticky každý Unixový program závisí od libc.so a prakticky každý Windows program závisí
od DLL knižníc. Ak by tieto knižnice bolo možné nahradiť škodlivými kópiami, škodlivý kód by
sa mohol spustiť pri volaní funkcií z týchto knižníc.

– Keďže LD_LIBRARY_PATH môže používateľ ľubovoľne nastaviť, útočníci môžu túto premennú
upraviť a prinútiť tak knižničný loader, aby knižnice vyhľadával v útočníkovom adresári, a tým
načítal jeho škodlivú knižnicu.

% setenv LD_LIBRARY_PATH .:$LD_LIBRARY_PATH

– Aby boli Set-UID programy chránené pred manipuláciou s premennou LD_LIBRARY_PATH,
runtime linker/loader (ld.so) túto premennú prostredia ignoruje, ak ide o Set-UID program.

– Bezpečné aplikácie môžu byť tiež staticky prelinkované s dôveryhodnou knižnicou, aby sa
tomuto problému vyhli.

– Vo Windows sa pri načítavaní DLL knižníc vo všeobecnosti najprv prehľadáva aktuálny
adresár, až potom systémové adresáre. Ak kliknete na dokument Microsoft Word, aby ste
spustili Office, ako prvý sa na DLL knižnice prehľadá adresár, v ktorom sa daný dokument
nachádza

Premenná prostredia LD_PRELOAD

– Mnohé Unixové systémy umožňujú „predbežne načítať“ (preload) zdieľané knižnice
nastavením premennej prostredia LD_PRELOAD. Tieto používateľom určené knižnice sa
načítajú skôr ako všetky ostatné. Dá sa to využiť na selektívne prepísanie funkcií z iných
knižníc. Ak ste si napríklad už zostavili vlastnú knižnicu, môžete ju predbežne načítať pomocou
nasledujúceho príkazu:

% export LD_PRELOAD=./libmylib.so.1.0.1

Ak libmylib.so.1.0.1 obsahuje funkciu sleep, čo je štandardná funkcia knižnice libc, pri spustení
programu, ktorý zavolá sleep, sa namiesto nej zavolá funkcia z libmylib.so.1.0.1.
– Tu je program, ktorý prepisuje funkciu sleep() z libc:

	#include <stdio.h>
	void sleep (int s)
		{
		printf("I am not sleeping!\n");
		}

Program môžeme skompilovať pomocou nasledujúcich príkazov (za predpokladu, že vyššie
uvedený program sa nazýva a.c):

	% gcc -fPIC -g -c a.c
	% gcc -shared -o libmylib.so.1.0.1 a.o -lc

Teraz spustíme nasledujúci program:

int main()
	{
		sleep(1);
		return 0;
	}

Ak je premenná prostredia LD_PRELOAD nastavená na libmylib.so.1.0.1, nezavolá sa funkcia
sleep() zo štandardnej knižnice libc; namiesto toho sa zavolá funkcia sleep() z našej knižnice a
vypíše sa „I am not sleeping!“.

– Aby boli Set-UID programy chránené pred manipuláciou s premennou LD_PRELOAD, runtime
linker/loader (ld.so) túto premennú prostredia ignoruje, ak ide o Set-UID root program, pokiaľ
nie je aj reálne UID rovné nule.

2.2 Volanie iných programov

Keď privilegovaný program spúšťa iné programy, treba dbať na to, či sa náhodou nespustia
nezamýšľané programy. Vieme, že premenné prostredia sú miestom, ktorému treba venovať
pozornosť; existujú však aj ďalšie miesta, na ktoré by sme sa mali zamerať.

– Aké potenciálne problémy vznikajú, ak Set-UID program vykoná nasledovné?

	// The contents of User_Input are provided by users.
	sprintf(command, "/bin/mail %s", User_Input);
	system(command);

– Používateľský vstup (User_Input) môže obsahovať špeciálne znaky pre shell (napr. |, &, <, >).
Nezabúdajte, že volanie system() v skutočnosti najprv spustí shell a následne požiada shell
program, aby vykonal „/bin/mail“. Ak nebudeme opatrní, útočníci môžu spôsobiť vykonanie
ďalších príkazov tým, že User_Input bude nasledovný reťazec:

xyz@example.com ; rm -f /* ; /bin/sh

2.3 Ďalšie známe vzory zraniteľností

Okrem vyššie uvedených zraniteľností súvisiacich s validáciou vstupov existuje niekoľko ďalších
dobre známych vzorov zraniteľností. Každému z nich sa budeme venovať v samostatných
prednáškach. Tu je ich zhrnutie.

• Zraniteľnosť typu Bufferoverflow (pretečenie zásobníka)
• Zraniteľnosť typu Race Condition (súbeh procesov)
• Zraniteľnosť typu Format-String

2.4 Rôzne ďalšie zraniteľnosti

Existuje mnoho ďalších zraniteľností, ktoré nie je jednoduché zaradiť do žiadnej z vyššie
uvedených kategórií. Niektoré by sa dali široko zaradiť ako „zraniteľnosť pri validácii vstupov“, no
vzhľadom na ich jedinečné vlastnosti ich tu rozoberáme samostatne. Nie je možné vymenovať
všetky zraniteľnosti. Uvádzame len niekoľko príkladov, ktoré ukazujú rôzne chyby, ktorých sa
programátori dopustili v logike svojich programov, a ako sa takéto chyby môžu zmeniť na
zraniteľnosti.

• Zraniteľnosť lpr: Program generuje dočasné súbory v adresári /tmp. Názvy súborov majú byť
náhodné; kvôli chybe v generovaní pseudonáhodných čísel sa však názvy súborov opakujú
každých 1000 volaní. Program je Set-UID program. Vytvorením odkazu s predvídateľným
názvom súboru smerujúceho na /etc/password spôsobí, že lpr tento súbor prepíše.

• Zraniteľnosť chsh: Program chsh vyzve používateľa na zadanie názvu shell programu a tento
vstup uloží do /etc/passwd; chsh pritom nevykonáva kontrolu zdravého rozumu. Program
predpokladá, že vstup používateľa pozostáva iba z jedného riadku. Bohužiaľ, tento predpoklad
možno vyvrátiť: používateľ môže zadať dva riadky vstupu, pričom druhý riadok bude vyzerať
napríklad ako „xyz::0:0::“, teda používateľ tak môže vložiť nový superuser účet (uid: 0) bez
hesla.

• Zraniteľnosti sendmail

  • sendmail: (1) prichádzajúce e-maily sa pripájajú do /var/mail/wedu. (2) Ak vlastníkom
    /var/mail/wedu nie je wedu, sendmail zmení vlastníka na wedu pomocou chown.
  • Dokážete to zneužiť na čítanie e-mailov používateľa wedu?
  • Dokážete to zneužiť na spôsobenie ešte vážnejšej škody používateľovi wedu?

3 Zvyšovanie bezpečnosti Set-UID programov

Funkcie exec

– Rodina funkcií exec spúšťa proces (child process) tak, že nahradí obraz aktuálneho
procesu novým. Existuje mnoho verzií funkcie exec, ktoré fungujú rôznymi spôsobmi. Dajú sa
rozdeliť do skupín, ktoré
∗ Používajú/nepoužívajú shell na spustenie child programov.
∗ Spracúvajú argumenty príkazového riadka prostredníctvom shellu (shell môže priniesť
viac funkcionality, než očakávame. Pamätajte, že shell je mocný program).

– Spúšťanie podprocesov (sub-processes) prináša otázky závislosti a dedenia atribútov, o
ktorých sme videli, že sú problematické. Funkcie execlp a execvp na spustenie programov
používajú shell. Vykonanie programu tak závisí od nastavenia shellu aktuálneho používateľa,
napr. od hodnoty PATH a iných premenných prostredia. Funkcia execv() je bezpečnejšia,
pretože do kódu takúto závislosť nevnáša.

– Volanie system (cmd) odovzdá reťazec shellu na vykonanie ako podproces (t.j. ako
samostatne forknutý proces). Je to pohodlné rozhranie (front-end) k exec funkciám.

– Podobne je na tom aj štandardná implementácia popen(). Táto funkcia otvorí rúru (pipe) k
novému procesu, aby vykonala príkaz a späť prečítala prípadný výstup ako súborový stream.
Aj táto funkcia na interpretáciu reťazcov s príkazmi spúšťa shell.

Ako bezpečne spustiť program?

– Vyhýbajte sa čomukoľvek, čo spúšťa shell. Namiesto system() použite execve(): execve()
shell nespúšťa, system() áno.

– Vyhýbajte sa execlp (file, …) a execvp(file,…), pretože sa správajú podobne ako shell. Ak
daný súbor nie je platný spustiteľný objektový súbor, jeho obsah použijú ako štandardný vstup
pre shell.

– Dávajte pozor na funkcie, ktoré môžu byť implementované pomocou shellu.
∗ Funkcia open() v Perli dokáže spúšťať príkazy, a zvyčajne to robí prostredníctvom shellu.

Zlepšenie bezpečnosti system()

– Pripomeňme, že system() najprv spustí /bin/sh. V Ubuntu vykoná execv /bin/sh s argumentmi
„sh“, „-c“ a reťazcom zadaným používateľom.

– V niektorých starších verziách Ubuntu (napr. Ubuntu 9.11) /bin/sh (v skutočnosti bash)
ignoruje voľbu Set-UID bitu. Preto pri volaní system (cmd) v Set-UID programe sa cmd
nevykoná s oprávneniami roota, pokiaľ samotný cmd nie je Set-UID program. Nasledujúci kód v
bashi zruší Set-UID bit.

if (running_setuid && privileged_mode == 0)
disable_priv_mode ();
...
void disable_priv_mode ()
	{
		setuid (current_user.uid);
		setgid (current_user.gid);
		current_user.euid = current_user.uid;
		current_user.egid = current_user.gid;
	}

– Táto ochrana však zrejme narúšala fungovanie niektorých Set-UID programov, ktoré
potrebovali použiť system(). Preto bola táto ochrana od istej verzie odstránená pridaním ďalšej
podmienky (platí to pre Ubuntu 11.04 aj 12.04):

if (running_setuid && privileged_mode == 0 && act_like_sh ==0)
disable_priv_mode ();

Premenná act_like_sh sa nastaví na 1, ak je bash spustený prostredníctvom symbolického odkazu
/bin/sh, a v takom prípade sa oprávnenia nezrušia. Ak však bash premeníte priamo na set-UID
program a pokúsite sa ho spustiť, táto ochrana bude naďalej účinná a oprávnenia sa zrušia.

4 Princíp najmenších oprávnení

Princíp najmenších oprávnení (Principle of Least Privilege, pôvodne sformulovaný Saltzerom a
Schroederom):

Každý program a každý používateľ systému by mal fungovať s najmenšou možnou množinou
oprávnení potrebných na dokončenie danej úlohy.

Najdôležitejším dôvodom na obmedzenie bezpečnostných oprávnení, ktoré váš kód na svoj beh
potrebuje, je zníženie škody, ktorá môže vzniknúť, ak by váš kód zneužil škodlivý používateľ. Ak
váš kód beží len so základnými oprávneniami, je pre škodlivých používateľov ťažké s ním
napáchať výraznejšiu škodu. Ak na spustenie svojho kódu vyžadujete od používateľov
administrátorské oprávnenia, akákoľvek bezpečnostná slabina vo vašom kóde môže potenciálne
spôsobiť väčšiu škodu prostredníctvom škodlivého kódu, ktorý danú slabinu zneužije.

Otázky, ktoré si treba položiť pri písaní privilegovaného programu:

– Potrebuje program tieto oprávnenia?
∗ Ak program na svoj beh nepotrebuje žiadne špeciálne oprávnenia, nemal by byť
privilegovaným programom.

– Potrebuje program všetky tieto oprávnenia?
∗ Programu udeľujeme len najmenšiu množinu oprávnení potrebných na dokončenie danej
úlohy.
∗ Mnohé operačné systémy nám neponúkajú veľký výber; môžeme si vybrať buď množinu
obsahujúcu všetky oprávnenia roota, alebo množinu bez akýchkoľvek oprávnení. Väčšina
Unixových systémov funguje takto — buď ste root, alebo nie ste. Nič medzi tým neexistuje.
∗ Väčšina moderných Unixových systémov (a Windows) ponúka viac možností. Tieto
systémy rozdeľujú oprávnenia roota na množstvo čiastkových oprávnení. Vďaka takejto
jemnejšej granularite dokážeme princíp najmenších oprávnení uplatňovať lepšie.

– Potrebuje program tieto oprávnenia práve teraz?
∗ Program určité oprávnenia zvyčajne po istý čas nepotrebuje; v danom momente sa
stávajú zbytočnými. Mali by sme ich dočasne zakázať, aby sme dodržali princíp najmenších
oprávnení. Výhodou tohto prístupu je, že v prípade, keď program urobí neúmyselnú chybu,
nemôže spôsobiť škodu na veciach, ktoré vyžadujú zakázané oprávnenia. Obrázok nižšie
túto myšlienku znázorňuje.
∗ Neskôr sa zakázané oprávnenie môže opäť stať potrebným, vtedy ho môžeme povoliť.
∗ Majte na pamäti, že zakazovanie/povoľovanie oprávnení dokáže znížiť škodu v situácii,
keď útočníci nedokážu vložiť kód do zraniteľného programu; ak útočníci dokážu vložiť kód do
zraniteľných programov, vložený kód si môže oprávnenia povoliť sám.

– Bude program tieto oprávnenia potrebovať v budúcnosti?
∗ Ak sa oprávnenie už nebude ďalej používať, stáva sa zbytočným a malo by byť natrvalo
odobraté, takže sa najmenšia množina oprávnení upravuje aj na základe budúcich potrieb.

Aké mechanizmy nám Unix poskytuje na dosiahnutie princípu najmenších oprávnení?

– Užitočné systémové volania: setuid(), seteuid(), setgid() a setegid().

– seteuid(uid): Nastaví efektívne user ID volajúceho procesu.
∗ Ak je efektívne user ID volajúceho procesu superuser, argument uid môže byť ľubovoľný.
Toto superuser často používa na dočasné vzdanie sa/opätovné získanie svojich oprávnení.
Superuser oprávnenie procesu sa však nestráca, proces ho môže znovu získať.
∗ Ak efektívne user ID volajúceho procesu nie je superuser, argument uid môže byť iba
efektívne user ID, reálne user ID alebo uložené user ID. Toto sa často používa
privilegovaným programom na opätovné získanie svojich oprávnení (pôvodné privilegované
efektívne user ID je uložené v uloženom user ID).

– setuid(uid): Nastaví efektívne user ID aktuálneho procesu. Ak je efektívne user ID volajúceho
root, nastavia sa aj reálne a uložené user ID.
∗ Ak je efektívne user ID procesu, ktorý volá setuid(), superuser, všetky reálne, efektívne a
uložené user ID sa nastavia na hodnotu argumentu uid. Potom už nie je pre program možné
znovu získať oprávnenia roota (za predpokladu, že uid nie je root). Toto sa používa na trvalé
vzdanie sa prístupu k vysokým oprávneniam.
∗ Setuid-root program, ktorý si želá dočasne sa vzdať oprávnení roota, prevziať identitu
iného, nie-root, používateľa a následne znovu získať oprávnenia roota, nemôže na tento účel
použiť setuid(). Toto možno dosiahnuť pomocou volania seteuid().
∗ Ak efektívne user ID volajúceho procesu nie je superuser, no uid je buď reálnym user ID,
alebo uloženým user ID volajúceho procesu, efektívne user ID sa nastaví na uid. Toto je
podobné funkcii seteuid().

– Príklady (vo Fedora Linuxe): Proces beží s efektívnym user ID=0 a reálnym user ID=500, aké
budú efektívne a reálne user ID po spustení
∗ setuid(500); setuid(0); Odpoveď: 500/500 (prvé volanie vytvorí 500/500 a druhé volanie
zlyhá).
∗ seteuid(500); setuid(0); Odpoveď: 0/500 (prvé volanie vytvorí 500/500 a druhé volanie
vytvorí 0/500).
∗ seteuid(600); setuid(500); Odpoveď: 500/500 (prvé volanie vytvorí 600/500 a druhé
volanie vytvorí 500/500).
∗ seteuid(600); setuid(500); setuid(0); Odpoveď: 0/500 (prvé volanie vytvorí 600/500, druhé
vytvorí 500/500 a tretie vytvorí 0/500).

Preložené z prednáškových poznámok: Set-UID Privileged Programs, Syracuse University.

TheOldOne · Miroslav Gensor ·