SELinux: Forskjellen på unconfined og unconfined

I forbindelse med nøsting av noen (forsåvidt harmløse men irriterende) "access vector cache (AVC) denials"  fra programmer som kjøres av Cfengine-agenten var det nødvendig med litt graving i SELinux. Det viste seg å bli lærerikt. Mulig flere vil ha nytte av dette. 

 

SELinux, i den form som brukes ved UiO (dvs targeted policy), virker slik at applikasjoner som er ansett å være eksponert for buffer overflow angrep fra utsiden blir beskyttet i en egen "container". Policy-regler sørger for at applikasjonen kun har  tilgang til de ressursene den trenger for å virke. Dette gjelder i hovedsak alle applikasjoner som leverer en tjeneste på ut på nettet via en (eller flere) nettverksport(er) og som kommer fra RedHat. Slike applikasjoner er "confined" (begrenset). Alle programmer som ikke er "confined" ihht. "targeted policy" er allment kjent som unconfined (ubegrenset av SELinux). Det vil si at de kjører i en kontekst som er ubegrenset. Det er flere (prosess-)kontekster som i følge ryktet skal være "unconfined", men det viser seg at det er forskjeller på de forskjellige kontekster som er "unconfined", noe jeg oppdaget da prosesser som kjørte i forskjellige kontekster som skulle være "unconfined" likevel resulterte i AVC-denials med jevne mellomrom. Det viser seg at "unconfined" ikke betyr annet enn at policyen spesifiserer så store privilegier at det ikke skal merkes under normal bruk. I starten var dette ensbetydende med "tillat alle operasjoner på alle objekter overalt". Etterhvert har imidlertid RedHat strammet inn både konteksten unconfined_t og andre kontekster som antas å kjøre "unconfined".

Cf-execd sørger for å kjøre cf-agent hvert 5. minutt , dvs. den agenten som sjekker at konfigurasjonen på maskinen er i tråd med spesifikasjonen og fikser dersom det er avvik. Cf-agent kjører forskjellige eksterne programmer (som f.eks ifconfig, iptables og setfiles) for å finne ut opplysninger om systemet og evt. fikse ting som er feil. En del maskiner gir imidlertid mange AVC-denials når disse eksterne programmene forsøker å skrive til /var/cfengine/outputs. Det er to ting som er merkelig her, det første er at disse programmene forsøker å skrive direkte til filer under /var/cfengine/outputs. Dette er et kjent problem [1] med Cfengine som har med lekkasje av fildeskriptorer og som vanskelig ville blitt oppdaget om vi ikke hadde SElinux. Det andre er at programmer som vi antok å kjøre i en unconfined (ubegrenset) kontekst ga AVC-denials. Dder på dette tyder på at det finnes begrensninger likevel.

Prosesser som startes av andre prosesser arver moder-prosessens kontekst dersom det det ikke finnes en transition-policy som sier noe annet. Cf-execd skal kjøre i konteksten unconfined_t ifølge UiO sin egen SELinux-policy.  Men det er slik at dersom Cf-execd startes av init, noe som er relativt vanlig, får den konteksten initrc_t. Dette skal ikke ha noen praktisk betydning siden initrc_t også er en unconfined policy. Eller ? Det viste seg at om jeg drepte cf-execd og startet den på nytt slik at den fikk konteksten unconfined_t , forsvant de fleste at AVC-denial-meldingene fra sysloggen. Hvorfor det ? Fordi det viser seg at det er forskjell på privilegiene til kontekstene unconfined_t  og f.eks.    initrc_t.  I tillegg er ikke unconfined_t  så unconfined som man skulle tro i følge bloggen til Dan Walsh [2]

Man kan finne transition-regler til andre kontekster fra unconfined_t med:

sesearch -T -s unconfined_t

Det er 346 transition regler fra unconfined_t og 629 regler for initrc_t. Det er altså en god del tilfeller hvor unconfined_t ikke arves videre av barne-prosessene og at det er flere slike regler for initrc_t enn unconfined_t.

La oss se litt på hvilke allow regler som finnes for de to kontekstene.

[root@watershed ~]# sesearch --allow -s unconfined_t|wc -l 
999
[root@watershed ~]#
[root@watershed ~]# sesearch --allow -s initrc_t|wc -l 
2026
[root@watershed ~]# 

Flere for initrc_t altså. Er det mer som er tillatt for initrc_t enn unconfined_t ? Ikke nødvendigvis, men det er flere allow-regler. Regler kan f.eks. inneholde regulære uttrykk og dermed åpne mange privilgier med en og samme regel. Men initrc_t har dobbelt så mange transition regler som gjøre at prosesser tilføres nye begrensninger.

La oss se på det konkrete tilfellet med Cfengine. Først er vi interessert å finne ut om noen av de to kontekstene inneholder regler som kan medføre at cf-agent får en annen kontekst enn cf-execd (som starter cf-agent).

[root@watershed ~]# ls -Z /var/cfengine/bin/cf-agent 
-rwx------. root root system_u:object_r:cfengine_var_lib_t:s0 /var/cfengine/bin/cf-agent
[root@watershed ~]# sesearch -T -s unconfined_t|grep cfengine_var_lib_t
[root@watershed ~]# sesearch -T -s initrc_t|grep cfengine_var_lib_t

Her sjekker vi hvilken filkontekst /var/cfengine/bin/cf-agent har (kun type er relevant i targeted policy). Vi finner typen cfengine_var_lib_t. Så søker vi etter transition-regler med hhv. unconfined_t og initrc_t som kildekondekst og sjekker om filkonteksten cfengine_var_lib_t er involvert i noen regler. Det er den ikke, derfor vil cf-agent arve konteksten til cf-execd både når cf-execd kjører i unconfined_t og initrc_t . Nå vet vi hvilken kildekontekst cf-agent vil kjøre i. La oss så se på transition-regler for ifconfig_t som kjøres av cf-agent og som var en av programmene som sluttet å generere AVC-denials da cf-execd byttet kontekst fra initrc_t til unconfined_t.

[root@watershed ~]# ls -Z /sbin/ifconfig 
-rwxr-xr-x. root root system_u:object_r:ifconfig_exec_t:s0 /sbin/ifconfig
[root@watershed ~]# sesearch -T -s unconfined_t|grep ifconfig_exec_t
[root@watershed ~]# sesearch -T -s initrc_t|grep ifconfig_exec_t
   type_transition initrc_t ifconfig_exec_t : process ifconfig_t; 
[root@watershed ~]#

Vi ser at /sbin/ifconfig har filkontekst type ifconfig_exec_t. Denne er ikke involvert i noen transition regler fra unconfined_t, men fra initrc_t ser vi en regel som sier at prosessen som oppstår når ifconfig-binæren kjøres av en prosess som befinner seg i initrc_t skal den overføres til konteksten ifconfig_t. Interessant, men vi vet fortsatt ikke om dette burde resulterere i begrensinger og i så fall hvilke.

[root@watershed ~]# ls -dZ /var/cfengine/outputs
drwxr-xr-x. root root system_u:object_r:cfengine_var_log_t:s0 /var/cfengine/outputs
[root@watershed ~]# sesearch --allow -s ifconfig_t| cfengine_var_log_t
-bash: cfengine_var_log_t: command not found
[root@watershed ~]# sesearch --allow -s ifconfig_t| grep cfengine_var_log_t
   allow application_domain_type cfengine_var_log_t : file { ioctl getattr lock append } ; 
   allow systemprocess cfengine_var_log_t : file { ioctl getattr lock append } ; 
[root@watershed ~]#

Katalogen /var/cfengine/outputs har kontekst-type cfengine_var_log_t. Når vi søker etter allow-regler for kilde-kontekst ifconfig_t hvor objekter med cfengine_var_log_t er involvert finner vi to innslag. Vi ser at det dukker opp to regler i søket hvor det gis rettigheter til filkonteksten cfengine_var_log_t. Kilden er hhv, application_domain og systemprocess. Søket speifisererifconfig_t kilde-kontekst (-s ifconfig_t), likevel har reglene application_domain og systemprocess som kilde i de to treffene. Litt spekulasjon her, men jeg antar at grunnen er at application_domain og systemprocess inkluderer ifconfig_t på et eller annet vis. Uansett kan vi slutte at prosesser i kontekst ifconfig_t i beste fall har lov til

ioctl getattr lock append 

på filer med

cfengine_var_log_t

AVC-denials fra ifconfig (kjørt fra cf-agent i initrc_t kontekst) kom fordi ifconfig forsøkte å opprett filer under /var/cfengine/outputs, noe det ikke finnes allow-regler for i konteksten ifconfig_t .

Da har jeg skjønt litt mer av SELinux , forhåpentiligvis......

Publisert 26. juni 2012 13:38 - Sist endret 26. juni 2012 21:05

Huff, det var visst en del skrivefeil og rare setninger her . Fiksa litt nettopp.

Jarle Bjørgeengen - 26. juni 2012 21:06
Legg til kommentar

Logg inn for å kommentere

Ikke UiO- eller Feide-bruker?
Opprett en WebID-bruker for å kommentere