Capabilities(7) Miscellaneous Information Manual Capabilities(7) NAZWA capabilities - przeglad przywilejow linuksowych OPIS Ze wzgledu na sprawdzanie uprawnien, tradycyjna uniksowa implementacja rozroznia dwie kategorie procesow: procesy uprzywilejowane (ktorych efektywny identyfikator uzytkownika wynosi 0, zwane superuzytkownikiem lub rootem, rzadziej administratorem), oraz procesy nieuprzywilejowane (z niezerowym efektywnym ID uzytkownika). Procesy uprzywilejowane moga pominac wszelka kontrole uprawnien jadra, natomiast procesy nieuprzywilejowane sa przedmiotem pelnej kontroli uprawnien w oparciu o referencje procesu (zwykle: efektywne identyfikatory uzytkownika oraz grupy, oraz uzupelniajaca liste grup). Poczawszy od Linuksa 2.2, Linux dzieli uprawnienia tradycyjnie wlasciwe superuzytkownikowi na odrebne jednostki, zwane przywilejami (ang. capabilities), ktore mozna niezaleznie wlaczac i wylaczac. Przywileje sa atrybutem przypisanym watkowi. Lista przywilejow Ponizej przedstawiono liste ukazujaca przywileje zaimplementowane w Linuksie oraz operacje lub zachowania, na ktore pozwala kazdy z przywilejow: CAP_AUDIT_CONTROL (od Linuksa 2.6.11) Wlaczanie i wylaczanie audytu jadra; zmiana regul filtrowania audytu; pobieranie statusu audytu i regul filtrowania. CAP_AUDIT_READ (od Linuksa 3.16) Zezwala na odczyt dziennika audytu za pomoca gniazda multicastowego netlink. CAP_AUDIT_WRITE (od Linuksa 2.6.11) Zapisywanie rekordu do dziennika audytu jadra CAP_BLOCK_SUSPEND (od Linuksa 3.5) Wlaczanie funkcji zdolnych powstrzymac wstrzymanie systemu (EPOLLWAKEUP epoll(7), /proc/sys/wake_lock). CAP_BPF (od Linuksa 5.8) Wykorzystywanie uprzywilejowanych operacji BPF (filtrowania pakietow Berkeley - przyp. tlum.), zob. bpf(2) i bpf-helpers(7). Ten przywilej dodano w Linuksie 5.8, aby wydzielic funkcjonalnosc BPF z przeladowanego przywileju CAP_SYS_ADMIN. CAP_CHECKPOINT_RESTORE (od Linuksa 5.9) o Aktualizowanie /proc/sys/kernel/ns_last_pid (zob. pid_namespaces(7)); o wykorzystywanie funkcji set_tid clone3(2); o odczytywanie zawartosci dowiazan symbolicznych /proc/pid/map_files w przypadku innych procesow. Ten przywilej dodano w Linuksie 5.9, aby wydzielic funkcjonalnosc punktow kontrolnych/przywracania z przeladowanego przywileju CAP_SYS_ADMIN. CAP_CHOWN Czynienie dowolnych zmian w stosunku do identyfikatorow uzytkownika i grupy (zob. chown(2)). CAP_DAC_OVERRIDE Pomijanie sprawdzen uprawnien odczytu, zapisu i wykonania. (DAC jest skrotem od ang. ,,discretionary access control" - tj. uznaniowa kontrola dostepu.) CAP_DAC_READ_SEARCH o Pomijanie sprawdzenia uprawnien odczytu pliku oraz sprawdzenia uprawnien odczytu i wykonania (a wlasciwie przeszukania - przyp. tlum.) katalogu; o wywolywanie open_by_handle_at(2); o uzywanie znacznika AT_EMPTY_PATH linkat(2) do utworzenia linku do pliku opisanego deskryptorem pliku. CAP_FOWNER o Pomijanie sprawdzenia uprawnien w przypadku operacji wymagajacych zwykle, aby identyfikator uzytkownika procesu pasowal do identyfikatora uzytkownika pliku (np. chmod(2), utime(2)), z wylaczeniem operacji objetych przywilejami CAP_DAC_OVERRIDE i CAP_DAC_READ_SEARCH; o ustawianie znacznikow i-wezlow (zob. ioctl_iflags(2)) dla dowolnych plikow; o ustawianie list kontroli dostepu do plikow (ang. Access Control Lists - ACL) dla dowolnych plikow; o ignorowanie bitu lepkosci katalogu przy usuwaniu pliku; o modyfikowanie atrybutow rozszerzonych uzytkownika w przypadku katalogu z bitem lepkosci, bedacego wlasnoscia dowolnego uzytkownika; o okreslanie O_NOATIME do dowolnych plikow w open(2) i fcntl(2). CAP_FSETID o Brak czyszczenia bitow: ustawiania ID uzytkownika lub ID grupy podczas wykonania (suid/sgid), w momencie modyfikowania pliku; o ustawianie bitu ustawiania ID grupy podczas wykonania (sgid) w przypadku plikow, dla ktorych identyfikator grupy nie pasuje do systemu plikow lub do jakiegokolwiek z dodatkowych identyfikatorow grupy procesu wywolujacego. CAP_IPC_LOCK o Blokowanie pamieci (mlock(2), mlockall(2), mmap(2), shmctl(2)); o Przydzielanie pamieci za pomoca duzych (ang. huge) stron (memfd_create(2), mmap(2), shmctl(2)). CAP_IPC_OWNER Pomijanie sprawdzania uprawnien w przypadku operacji na obiektach IPC Systemu V CAP_KILL Pominiecie sprawdzenia uprawnien przy wysylaniu sygnalow (zob. kill(2)). Obejmuje to operacje KDSIGACCEPT ioctl(2). CAP_LEASE (od Linuksa 2.4) Dokonywanie dzierzaw na dowolnych plikach (zob. fcntl(2)). CAP_LINUX_IMMUTABLE Ustawianie znacznikow i-wezlow FS_APPEND_FL i FS_IMMUTABLE_FL (zob. ioctl_iflags(2)). CAP_MAC_ADMIN (od Linuksa 2.6.25) Zezwala na zmiane statusu lub konfiguracji MAC. Zaimplementowane do modulu Smack Linux Security Module (LSM). CAP_MAC_OVERRIDE (od Linuksa 2.6.25) Przeslanianie obowiazkowej kontroli dostepu (ang. Mandatory Access Control - MAC). Zaimplementowane do modulu Smack LSM. CAP_MKNOD (od Linuksa 2.4) Tworzenie plikow specjalnych za pomoca mknod(2). CAP_NET_ADMIN Przeprowadzanie wielu operacji zwiazanych z siecia: o konfigurowanie interfejsu; o administrowanie zapora sieciowa IP, maskaradowaniem oraz rozliczeniami; o modyfikowanie tabel trasowania o przypisywanie do dowolnego adresu w celu uzyskania przezroczystego proxy o ustawianie typu uslugi (ang. type-of-service - TOS); o czyszczenie statystyk sterownika o ustawianie trybu nasluchiwania; o wlaczanie multicastingu; o uzywanie setsockopt(2) do ustawiania nastepujacych opcji gniazd: SO_DEBUG, SO_MARK, SO_PRIORITY (na priorytet spoza zakresu od 0 do 6), SO_RCVBUFFORCE i SO_SNDBUFFORCE. CAP_NET_BIND_SERVICE Kojarzenie gniazda z portami z uprzywilejowanej domeny internetowej (porty o numerach ponizej 1024). CAP_NET_BROADCAST (Nieuzywane) Tworzenie gniazd rozgloszeniowych oraz nasluchiwanie multicastu. CAP_NET_RAW o Uzywanie gniazd RAW i PACKET o przypisywanie do dowolnego adresu w celu uzyskania przezroczystego proxy. CAP_PERFMON (od Linuksa 5.8) Uzywanie wielu mechanizmow monitorowania wydajnosci, w tym: o wywolywanie perf_event_open(2); o wykonywanie wielu operacji BPF (filtrowania pakietow Berkeley - przyp. tlum.), ktore wplywaja na wydajnosc. Ten przywilej dodano w Linuksie 5.8, aby wydzielic funkcjonalnosc monitorowania z przeladowanego przywileju CAP_SYS_ADMIN. Wiecej szczegolow w pliku zrodel jadra Documentation/admin-guide/perf-security.rst. CAP_SETGID o Czynienie dowolnych zmian wobec identyfikatora grupy procesu oraz listy uzupelniajacych identyfikatorow grup; o falszowanie identyfikatora grupy przy przekazywaniu referencji gniazd za pomoca gniazd domeny uniksowej; o zapisywanie przypisania identyfikatora grupy w przestrzeni nazw uzytkownika (zob. user_namespaces(7)). CAP_SETFCAP (od Linuksa 2.6.24) Ustawianie dowolnych przywilejow na pliku. Od Linuksa 5.12 przywilej ten jest konieczny do przypisania identyfikatora uzytkownika 0 w nowej przestrzeni nazw; wiecej szczegolow w podreczniku user_namespaces(7). CAP_SETPCAP Jesli obslugiwane sa przywileje pliku (tj. od Linuksa 2.6.24): dodawanie dowolnych przywilejow ze zbioru ograniczonego wywolujacego watku do jego zbioru dziedzicznego; porzucanie przywilejow ze zbioru ograniczonego (za pomoca PR_CAPBSET_DROP prctl(2)); dokonywanie zmian w znacznikach securebits. Jesli przywileje pliku nie sa obslugiwane (tj. przed Linuksem 2.6.24): przyznawanie lub usuwanie dowolnych przywilejow w zbiorze przywilejow dozwolonych wywolujacego lub z dowolnych innych procesow (ta wlasnosc CAP_SETPCAP jest niedostepna gdy jadro skonfigurowano w celu obslugi przywilejow pliku, poniewaz CAP_SETPCAP ma dla takich jader zupelnie odmienna semantyke). CAP_SETUID o Czynienie dowolnych zmian wobec identyfikatorow uzytkownika procesow (setuid(2), setreuid(2), setresuid(2), setfsuid(2)); o falszowanie identyfikatora uzytkownika przy przekazywaniu referencji gniazd za pomoca gniazd domeny uniksowej; o zapisywanie przypisania identyfikatora uzytkownika w przestrzeni nazw uzytkownika (zob. user_namespaces(7)). CAP_SYS_ADMIN Uwaga: niniejszy przywilej jest przeladowany, zob. Uwagi do deweloperow jadra ponizej. o Wykonywanie wielu operacji z zakresu administracji systemem, w tym: quotactl(2), mount(2), umount(2), pivot_root(2), swapon(2), swapoff(2), sethostname(2) i setdomainname(2); o wykonywanie uprzywilejowanych operacji syslog(2) (od Linuksa 2.6.37 do zezwolenia na takie operacje powinno sie uzywac CAP_SYSLOG); o wykonywanie polecenia vm86(2) VM86_REQUEST_IRQ; o dostep do takiej samej funkcjonalnosci punktow kontrolnych/przywracania jak ta zarzadzana przywilejem CAP_CHECKPOINT_RESTORE (jednak ten ostatni jest preferowany do uzyskiwania dostepu do tej funkcjonalnosci, poniewaz jest bardziej ograniczony). o przeprowadzanie takich samych operacji BPF (filtrowania pakietow Berkeley - przyp. tlum.) jak te zarzadzane przywilejem CAP_BPF (jednak ten ostatni jest preferowany do uzyskiwania dostepu do tej funkcjonalnosci, poniewaz jest bardziej ograniczony). o korzystanie z takich samych mechanizmow monitorowania wydajnosci, jak te zarzadzane przywilejem CAP_PERFMON (jednak ten ostatni jest preferowany do uzyskiwania dostepu do tej funkcjonalnosci, poniewaz jest bardziej ograniczony). o przeprowadzanie operacji IPC_SET i IPC_RMID na dowolnych obiektach IPC Systemu V; o przeslanianie limitu zasobow RLIMIT_NPROC; o przeprowadzanie operacji na atrybutach rozszerzonych: zaufanych i bezpieczenstwa (zob. xattr(7)); o uzywanie lookup_dcookie(2); o uzywanie ioprio_set(2) do przypisania klas harmonogramu wejscia/wyjscia IOPRIO_CLASS_RT i (przed Linuksem 2.6.25) IOPRIO_CLASS_IDLE; o falszowanie identyfikatora procesu przy przekazywaniu referencji gniazd za pomoca gniazd domeny uniksowej; o wykraczanie poza okreslony w /proc/sys/fs/file-max systemowy limit otwartych plikow, w wywolaniach systemowych otwierajacych pliki (np. accept(2), execve(2), open(2), pipe(2)); o uzywanie znacznikow CLONE_* tworzacych nowe przestrzenie nazw za pomoca clone(2) i unshare(2) (lecz, od Linuksa 3.8, tworzenie przestrzeni nazw uzytkownika nie wymaga jakiegokolwiek przywileju); o dostep do uprzywilejowanych informacji o zdarzeniach perf; o wywolywanie setns(2) (wymaga CAP_SYS_ADMIN w docelowej przestrzeni nazw); o wywolywanie fanotify_init(2); o przeprowadzanie uprzywilejowanych operacji KEYCTL_CHOWN i KEYCTL_SETPERM keyctl(2); o przeprowadzanie operacji MADV_HWPOISON madvise(2); o wykorzystywanie TIOCSTI ioctl(2) do umieszczania znakow w kolejce wejsciowej terminala innego, niz terminal kontrolujacy wywolujacego; o wykorzystywanie przestarzalego wywolania systemowego nfsservctl(2); o wykorzystywanie przestarzalego wywolania systemowego bdflush(2); o wykonywanie roznych operacji uprzywilejowanych ioctl(2) na urzadzeniu blokowym; o wykonywanie roznych operacji uprzywilejowanych ioctl(2) na systemie plikow; o wykonywanie operacji uprzywilejowanych ioctl(2) na urzadzeniu /dev/random (zob. random(4)); o instalowanie filtru seccomp(2) bez uprzedniej koniecznosci ustawienia atrybutu watku no_new_privs; o modyfikowanie regul zezwalajacych/zabraniajacych w grupach kontroli urzadzenia; o wykorzystywanie operacji PTRACE_SECCOMP_GET_FILTER ptrace(2) do zrzucania filtrow seccomp sledzacego; o wykorzystywanie operacji PTRACE_SETOPTIONS ptrace(2) do zawieszania zabezpieczen seccomp sledzacego (np. znacznik PTRACE_O_SUSPEND_SECCOMP); o dokonywanie operacji administracyjnych na wielu sterownikach urzadzen; o modyfikacja wartosci priorytetow nice autogrupy, za pomoca zapisu do /proc/pid/autogroup (zob. sched(7)). CAP_SYS_BOOT Uzywanie reboot(2) i kexec_load(2). CAP_SYS_CHROOT o Uzywanie chroot(2); o zmienianie przestrzeni nazw montowan za pomoca setns(2) CAP_SYS_MODULE o Ladowanie i usuwanie modulow jadra (zob. init_module(2) i delete_module(2)); o przed Linuksem 2.6.25: porzucanie przywilejow z systemowego, ograniczonego zbioru przywilejow. CAP_SYS_NICE o Zmniejszanie wartosci nice procesu (nice(2), setpriority(2)) oraz zmienianie wartosci nice dowolnych procesow; o ustawianie zasad planowania czasu rzeczywistego procesu wywolujacego oraz ustawianie zasad planowania i priorytetow dowolnych procesow (sched_setscheduler(2), sched_setparam(2), sched_setattr(2)); o ustawianie koligacji procesorow (ang. affinity) dla dowolnych procesow (sched_setaffinity(2)); o ustawianie klasy i priorytetu planowania wejscia/wyjscia dowolnych procesow (ioprio_set(2)); o stosowanie migrate_pages(2) do dowolnych procesow oraz mozliwosc migrowania procesow do dowolnych wezlow; o stosowanie move_pages(2) do dowolnych procesow; o uzywanie znaczniku MPOL_MF_MOVE_ALL z mbind(2) i move_pages(2). CAP_SYS_PACCT Uzywanie acct(2). CAP_SYS_PTRACE o Sledzenie dowolnych procesow za pomoca ptrace(2); o stosowanie get_robust_list(2) do dowolnych procesow; o transferowanie danych do i z pamieci, w przypadku dowolnych procesow, za pomoca process_vm_readv(2) i process_vm_writev(2); o dokonywanie inspekcji procesow za pomoca kcmp(2). CAP_SYS_RAWIO o Dokonywanie operacji wejscia/wyjscia na portach (iopl(2) i ioperm(2)); o uzyskiwanie dostepu do /proc/kcore; o wykonywanie operacji FIBMAP ioctl(2); o otwieranie urzadzen w celu dostepu do rejestrow charakterystycznych dla danego modelu x86 (ang. model-specific register - MSR, zob. msr(4)); o aktualizowanie /proc/sys/vm/mmap_min_addr; o tworzenie przypisan pamieci do adresow ponizej wartosci okreslonej przez /proc/sys/vm/mmap_min_addr; o przypisywanie plikow w /proc/bus/pci; o otwieranie /dev/mem i /dev/kmem; o wykonywanie roznych polecen w stosunku do urzadzen SCSI; o wykonywanie okreslonych operacji na urzadzeniach hpsa(4) i cciss(4); o wykonywanie wielu charakterystycznych dla urzadzenia operacji na innych urzadzeniach. CAP_SYS_RESOURCE o Uzywanie zarezerwowanej przestrzeni w systemach plikow ext2; o tworzenie wywolan ioctl(2) kontrolujacych dzialanie dziennika ext3; o przeslanianie limitow przydzialow dyskowych; o zwiekszanie limitow zasobow (zob. setrlimit(2)); o przeslanianie limitu zasobow RLIMIT_NPROC; o przeslanianie maksymalnej liczby konsol, przy przydzielaniu konsol; o przeslanianie maksymalnej liczby mapowan klawiszy; o zezwalanie na wiecej niz 64hz przerwan z zegara czasu rzeczywistego; o podnoszenie limitu msg_qbytes kolejki komunikatow Systemu V ponad limit okreslony w /proc/sys/kernel/msgmnb (zob. msgop(2) i msgctl(2)); o mozliwosc pominiecia limitu zasobow RLIMIT_NOFILE, dotyczacego deskryptorow plikow ,,w locie", przy przekazywaniu deskryptorow pliku do innego procesu za pomoca gniazd domeny uniksowej (zob. unix(7)); o przeslanianie limitu /proc/sys/fs/pipe-size-max przy ustawianiu pojemnosci potoku za pomoca polecenia F_SETPIPE_SZ fcntl(2); o korzystanie z F_SETPIPE_SZ do zwiekszania pojemnosci potoku ponad limit okreslony w /proc/sys/fs/pipe-max-size; o przeslanianie limitow /proc/sys/fs/mqueue/queues_max, /proc/sys/fs/mqueue/msg_max, i /proc/sys/fs/mqueue/msgsize_max przy tworzeniu kolejek komunikatow POSIX (zob. mq_overview(7)); o korzystanie z operacji PR_SET_MM prctl(2); o ustawianie /proc/pid/oom_score_adj na wartosc nizsza niz ostatnio ustawiona przez proces z przywilejem CAP_SYS_RESOURCE. CAP_SYS_TIME Ustawianie zegara systemowego (settimeofday(2), stime(2), adjtimex(2)); ustawianie zegara czasu rzeczywistego (sprzetowego). CAP_SYS_TTY_CONFIG Uzywanie vhangup(2); korzystanie z wielu uprzywilejowanych operacji ioctl(2) na terminalach wirtualnych. CAP_SYSLOG (od Linuksa 2.6.37) o Wykonywanie uprzywilejowanych operacji syslog(2). Opis operacji wymagajacych uprzywilejowania zawiera podrecznik systemowy syslog(2). o Przegladanie adresow ujawnionych w /proc i innych interfejsach, gdy /proc/sys/kernel/kptr_restrict ma wartosc 1 (zob. opis kptr_restrict w proc(5)). CAP_WAKE_ALARM (od Linuksa 3.0) Wyzwalanie czegos, co wybudzi system (ustawienie budzikow CLOCK_REALTIME_ALARM i CLOCK_BOOTTIME_ALARM). Przeszla i obecna implementacja Pelna implementacja przywilejow wymaga aby: o W przypadku wszystkich operacji uprzywilejowanych jadro sprawdzalo, czy watek ma odpowiedni przywilej w swoim zbiorze efektywnym. o Jadro zapewnialo wywolania systemowe pozwalajace na zmiane i pobranie przywilejow watku. o System plikow obslugiwal dolaczanie przywilejow do pliku wykonywalnego, aby proces mogl zyskiwac te przywileje przy wykonywaniu pliku. Przed Linuksem 2.6.24 jedynie dwa pierwsze warunki byly spelnione, Linux od wersji 2.6.24 wypelnia wszystkie trzy wymagania. Uwagi do deweloperow jadra Przy dodawaniu nowej funkcji, ktora powinna byc zarzadzania przywilejami, nalezy rozwazyc ponizsze punkty. o Celem przywilejow jest podzielenie uprawnien superuzytkownika na fragmenty, dzieki czemu program, ktorego jeden lub kilka przywilejow zostalo przejetych, ma mniejsze mozliwosci uczynienia szkod w systemie, niz ten sam program dzialajacy z uprawnieniami roota. o Deweloper ma wybor: utworzyc nowy przywilej dla swojej nowej funkcji lub przypisanie funkcji do jednego z istniejacych. Aby zestaw przywilejow mial rozsadny rozmiar, zaleca sie to drugie podejscie, chyba ze istnieja przekonujace powody do tworzenia nowego przywileju (istnieje rowniez limit techniczny: zestaw przywilejow jest obecnie ograniczony do 64 bitow). o Aby dowiedziec sie, ktory przywilej bedzie najlepiej pasowal do opracowywanej nowej funkcji, nalezy sprawdzic powyzsza liste przywilejow w kolejnosci, aby znalezc ,,koszyk", w ktorym nowa funkcja najlepiej sie odnajdzie. Jednym ze sposobow jest sprawdzenie, czy inne funkcje wymagajace jakiegos przywileju beda zawsze uzywane z nowa funkcja. Jesli nowa funkcja jest bezuzyteczna bez tych innych funkcji, nalezy uzyc tego samego przywileju jak one. o Nie nalezy wybierac CAP_SYS_ADMIN, jesli tylko uda sie tego uniknac! Wiele istniejacych sprawdzen przywilejow jest z nim zwiazanych (zob. czesciowa liste powyzej). Mozna go juz przekonujaco nazwac ,,nowym rootem", jako ze, z jednej strony obejmuje caly szereg uprawnien, a z drugiej ze wzgledu na szerokie spektrum wymagany jest rowniez przez wiele uprzywilejowanych programow. Nie nalezy poglebiac tego problemu. Jedynymi funkcjami, ktore nalezy wiazac z CAP_SYS_ADMIN sa te scisle pasujace do istniejacych funkcji tego koszyka. o Jesli okaze sie, ze istnieje jednak koniecznosc utworzenia nowego przywileju dla opracowywanej funkcji, nie nalezy tworzyc go lub nazywac jako przywileju ,,jednorazowego". Z tego wzgledu na przyklad, dodanie bardzo specjalistycznego przywileju CAP_SYS_PACCT bylo najprawdopodobniej bledne. Zamiast tego nalezy zidentyfikowac i nazwac swoj nowy przywilej jako szerszy koszyk, do ktorego pasowac moga w przyszlosci inne zwiazane funkcje. Zbiory przywilejow watku Kazdy watek ma nastepujacy zbior przywilejow zawierajacy zero lub wiecej z przywilejow opisanych wyzej: Dozwolony (ang. permitted) Jest to ograniczajacy nadzbior przywilejow efektywnych, jakie moze przyjac watek. Jest to rowniez ograniczajacy nadzbior przywilejow, jakie mozna dodac do zbioru dziedzicznego, w przypadku przywilejow ktore mozna dodac do zbioru dziedzicznego przez watek nieposiadajacy przywileju CAP_SETPCAP w swoim zbiorze efektywnym. Jesli watek porzuci przywilej ze swojego zbioru dozwolonego, nigdy nie moze pozyskac tego przywileju ponownie (chyba ze execve(2) wykona program z set-user-ID-root lub program, ktorego powiazane przywileje pliku daja taki przywilej). Dziedziczny (ang. inheritable) Jest to zbior przywilejow zachowywany na przestrzeni calego execve(2). Przywileje dziedziczne pozostaja dziedziczone przy wykonywaniu dowolnego programu oraz sa dodawane do zbioru dozwolonego przy wykonywaniu programu, ktory ma ustawione odpowiadajace bity w zbiorze dziedzicznym pliku. Ze wzgledu na to, ze przywileje dziedziczne nie sa zwykle zachowywane na przestrzeni execve(2) przy dzialaniu jako uzytkownik nieuprzywilejowany (nie root), programy ktore chcialyby wykonac swoje programy pomocnicze z podniesionymi przywilejami, powinny rozwazyc korzystanie z przywilejow tla, opisanych ponizej. Efektywny (ang. effective) Jest to zbior przywilejow uzywany przez jadro do sprawdzenia uprawnien watku. Ograniczajacy (ang. bounding; na watek od Linuksa 2.6.25) Zbior przywilejow ograniczajacych jest mechanizmem uzywanym do ograniczenia przywilejow pozyskiwanych w trakcie execve(2). Od Linuksa 2.6.25, jest to zbior przywilejow przypisywany do watku. W starszych jadrach, zbior przywilejow ograniczajacych byl systemowy i dzielony przez wszystkie watki systemu. Wiecej szczegolow opisano w rozdziale Zbior przywilejow ograniczajacych ponizej. Tla (ang. ambient; od Linuksa 4.3) Jest to zbior przywilejow zachowywany na przestrzeni execve(2) nieuprzywilejowanego programu. Przywileje tla przestrzegaja zasady, ze zaden przywilej nie moze zostac przywilejem tla, jesli nie jest zarowno dozwolony jak i dziedziczny. Zbior przywilejow tla mozna modyfikowac bezposrednio za pomoca prctl(2). Przywileje tla sa automatycznie zmniejszane, jesli zmniejszony zostanie odpowiadajacy przywilej dozwolony lub dziedziczny. Wykonanie programu zmieniajacego identyfikator uzytkownika lub grupy ze wzgledu na bity ustawienia ID uzytkownika lub grupy podczas wykonania (suid/sgid) albo programu, ktory ma jakiekolwiek przywileje plikowe, wyczysci zbior przywilejow tla. Przywileje tla sa dodawane do zbioru dozwolonego i przypisywane do zbioru efektywnego przy wywolaniu execve(2). Jesli przywilej tla spowoduje zwiekszenie przywilejow dozwolonych i efektywnych procesu podczas execve(2), nie wyzwoli to trybu bezpiecznego wykonania opisanego w ld.so(8). Watek potomny utworzony za pomoca fork(2) dziedziczy kopie zbioru przywilejow swojego rodzica. Szczegoly wplywu execve(2) na przywileje opisano w rozdziale Transformacja przywilejow podczas execve() ponizej. Za pomoca capset(2), watek moze zmieniac swoj zbior przywilejow, zob. rozdzial Programowe dostosowywanie zbioru przywilejow ponizej. Od Linuksa 3.2, plik /proc/sys/kernel/cap_last_cap ujawnia wartosc numeryczna najwyzszego przywileju obslugiwanego przez dzialajace jadro; mozna to wykorzystac do okreslenia najwyzszego bitu, jaki mozna ustawic w zbiorze przywilejow. Przywileje pliku Od Linuksa 2.6.24 jadro obsluguje powiazanie zbioru przywilejow z plikiem wykonywalnym za pomoca setcap(8). Zbiory przywilejow pliku sa przechowywane w atrybucie rozszerzonym (zob. setxattr(2) i xattr(7)) o nazwie security.capability. Zapis do tego atrybutu rozszerzonego wymaga przywileju CAP_SETFCAP. Zbiory przywilejow pliku, razem ze zbiorem przywilejow watku, okreslaja przywileje watku po execve(2). Istnieja trzy zbiory przywilejow pliku: Dozwolone (ang. permitted; wczesniej znane jako wymuszone - ang. forced): Te przywileje sa automatycznie dozwolone dla watku, niezaleznie od przywilejow dziedzicznych watku. Dziedziczne (ang. inheritable; wczesniej znane jako dozwolone - ang. allowed): Na tym zbiorze wykonywana jest operacja AND ze zbiorem dziedzicznym watku, w celu okreslenia ktore przywileje dziedziczne sa wlaczone w zbiorze dozwolonym watku, po execve(2). Efektywne (ang. effective) Nie jest to zbior, lecz pojedynczy bit. Jesli jest ustawiony, to podczas execve(2) wszystkie nowo dozwolone przywileje watku sa rowniez podnoszone w zbiorze efektywnym. Jesli bit jest nieustawiony, to po execve(2), zaden z nowo dozwolonych przywilejow nie trafia do nowego zbioru efektywnego. Wlaczenie efektywnego bitu przywilejow pliku wymusza sytuacje, ze przywilej dozwolony lub dziedziczny dowolnego pliku, ktory powoduje pozyskanie przez watek odpowiadajacego przywileju podczas execve(2) (zob. Transformacja przywilejow podczas execve() ponizej) pozyska rowniez ten przywilej w swoim zbiorze efektywnym. Z tego wzgledu przy przypisywaniu przywilejow do pliku (cap_set_file(3), cap_set_fd(3), setcap(8)), jesli poda sie znacznik przywileju efektywnego, jako majaca byc wlaczona dla dowolnego przywileju, to znacznik efektywny musi byc rowniez podany jako wlaczony dla wszystkich innych przywilejow, dla ktorych odpowiadajacy znacznik dozwolony lub dziedziczny jest wlaczony. Wersjonowanie atrybutu rozszerzonego przywilejow pliku W celu zachowania przyszlej rozszerzalnosci, jadro obsluguje sposob kodowania numeru wersji wewnatrz atrybutu rozszerzonego security.capability, ktory jest uzywany do implementacji przywilejow pliku. Ponizsze numery wersji sa wewnetrzne i niewidoczne wprost dla aplikacji w przestrzeni uzytkownika. Do tej pory obslugiwane sa nastepujace wersje: VFS_CAP_REVISION_1 Byla to oryginalna implementacja przywilejow pliku, obslugujaca 32-bitowe maski przywilejow pliku. VFS_CAP_REVISION_2 (od Linuksa 2.6.25) Ta wersja pozwalala na maski przywilejow pliku o rozmiarze 64 bitow oraz byla konieczna wobec przekroczenia przez przywileje liczby 32. Jadro kontynuuje obsluge plikow, ktore maja 32-bitowa maske przywilejow w wersji 1, w sposob przezroczysty, lecz przy dodawaniu przywilejow do plikow, ktore uprzednio ich nie posiadaly oraz przy modyfikacji przywilejow istniejacych plikow, automatycznie uzyje wersji 2 (lub wersji 3, zgodnie z opisem ponizej). VFS_CAP_REVISION_3 (od Linuksa 4.14) Wersja 3 przywilejow plikow zapewnia przywileje przestrzeni nazw plikow (opisanych nizej). Podobnie jak w wersji 2 przywilejow pliku, maski przywilejow w wersji 3 maja rozmiar 64 bitow. Jednak oprocz tego, w atrybucie rozszerzonym security.capability zakodowano przestrzen nazw identyfikatora uzytkownika root (jest to wartosc, ktora uzytkownik o identyfikatorze 0 wewnatrz tej przestrzeni nazw przypisuje poczatkowej przestrzeni nazw uzytkownika). Przywileje pliku w wersji 3 sa zaprojektowane do wspolnej egzystencji z przywilejami pliku w wersji 2 tj. we wspolczesnym systemie Linux czesc plikow moze miec przywileje w wersji 2, a inne w wersji 3. Przed Linuksem 4.14, jedynym rodzajem atrybutu rozszerzonego przywileju pliku, jaki mogl byc dolaczony do pliku, byl atrybut VFS_CAP_REVISION_2. Od jadra Linux 4.14, wersja atrybutu rozszerzonego security.capability dolaczonego do pliku zalezy od okolicznosci, w jakich utworzono atrybut. Od Linuksa 4.14, atrybut rozszerzony security.capability jest tworzony (lub przeksztalcany) automatycznie na atrybut w wersji 3 (VFS_CAP_REVISION_3) jesli spelnione sa oba ponizsze warunki: o Watek zapisujacy do atrybutu rezyduje w niepierwotnej przestrzeni nazw uzytkownika (scislej mowiac: watek rezydujacy w przestrzeni nazw uzytkownika innej niz ta, z ktorej zamontowano zasadniczy system plikow.) o Watek ma przywilej CAP_SETFCAP wobec i-wezla pliku, co oznacza, ze (a) watek ma przywilej CAP_SETFCAP wobec swojej przestrzeni nazw uzytkownika oraz (b) identyfikatory uzytkownika i grupy i-wezla pliku maja przypisania w przestrzeni nazw uzytkownika zapisujacego. Gdy tworzony jest atrybut rozszerzony security.capability VFS_CAP_REVISION_3, identyfikator uzytkownika root tworzacego watku w przestrzeni nazw uzytkownika jest zapisywany w atrybucie rozszerzonym. Odmiennie, przy tworzeniu lub modyfikacji atrybutu rozszerzonego security.capability z uprzywilejowanego (CAP_SETFCAP) watku rezydujacego w przestrzeni nazw, w ktorej zamontowano zasadniczy system plikow (zwykle oznacza to pierwotna przestrzen nazw uzytkownika), atrybut zostanie automatycznie utworzony w wersji 2 (VFS_CAP_REVISION_2). Prosze zauwazyc, ze utworzenie wersji 3 atrybutu rozszerzonego security.capability jest automatyczne. Oznacza to, ze jesli program w przestrzeni uzytkownika dokonuje zapisu (setxattr(2)) atrybutu security.capability w wersji 2, jadro automatycznie utworzy atrybut w wersji 3, jesli atrybut jest utworzony w okolicznosciach opisach powyzej. Odpowiednio, gdy pobierany jest atrybut security.capability w wersji 3 (getxattr(2)) przez proces rezydujacy w przestrzeni nazw uzytkownika, ktory zostal utworzony przez identyfikator uzytkownika roota (lub potomek tej przestrzeni nazw uzytkownika), zwracany atrybut jest (automatycznie) upraszczany, aby wygladal na atrybut w wersji 2 (tzn. wartosc zwracana ma rozmiar atrybutu w wersji 2 oraz nie zawiera identyfikatora uzytkownika root). To tlumaczenie w locie oznacza, ze w narzedziach przestrzeni uzytkownika (np. setcap(1) i getcap(1)) nie sa konieczne zmiany aby uzywac tych narzedzi do tworzenia i pobierania atrybutow security.capability w wersji 3. Prosze zwrocic uwage, ze plik moze posiadac powiazany z nim atrybut rozszerzony security.capability w wersji 2 albo w wersji 3, ale nie obu: utworzenie albo modyfikacja atrybutu rozszerzonego security.capability automatycznie zmodyfikuje wersje, w zaleznosci od okolicznosci, w jakich utworzono lub zmodyfikowano atrybut rozszerzony. Transformacja przywilejow podczas execve() Podczas execve(2), jadro oblicza nowe przywileje procesu za pomoca ponizszego algorytmu: P'(tla) = (plik jest uprzywilejowany) ? 0 : P(tla) P'(dozwolony) = (P(dziedziczny) & F(dziedziczny)) | (F(dozwolony) & P(ograniczajacy)) | P'(tla) P'(efektywny) = F(efektywny) ? P'(dozwolony) : P'(tla) P'(dziedziczny) = P(dziedziczny) [tzn. bez zmian] P'(ograniczajacy) = P(ograniczajacy) [tzn. bez zmian] gdzie: P() oznacza wartosc zbioru przywilejow watku przed execve(2) P'() oznacza wartosc zbioru przywilejow watku po execve(2) F() oznacza zbior przywilejow pliku Prosze zwrocic uwage na detale odnoszace sie do powyzszych regul transformacji przywilejow: o Zbior przywilejow tla jest obecny jedynie od Linuksa 4.3. Przy okreslaniu transformacji zbioru tla podczas execve(2), plikiem uprzywilejowanym jest plik posiadajacy przywileje lub ustawiony bit ustawienia ID uzytkownika lub grupy podczas wykonania (suid/sgid). o Przed Linuksem 2.6.25, zbior ograniczajacy byl atrybutem systemowym dzielonym przez wszystkie watki. Ta wartosc systemowa byla uzywana do obliczania podczas execve(2) nowego zbioru dozwolonego w ten sam sposob jak pokazano powyzej dla P(ograniczajacego). Uwaga: podczas przeksztalcen przywilejow opisanych powyzej, przywileje plikow moga zostac zignorowane (potraktowane jako puste) z tych samych powodow jak ignorowane sa bity ustawienia ID uzytkownika lub grupy podczas wykonania (suid/sgid); zob. execve(2). Przywileje pliku sa ignorowane w podobny sposob, jesli rozruch jadra nastapil z opcja no_file_caps. Uwaga: zgodnie z powyzszymi regulami, jesli proces z niezerowym identyfikatorem uzytkownika wykona execve(2), to wszystkie przywileje obecne w jego zbiorze dozwolonym i efektywnym zostana wyczyszczone. Sposob traktowania przywilejow, gdy proces z identyfikatorem uzytkownika rownym zero wykonuje execve(2), opisano w rozdziale Przywileje i wykonanie programow przez roota ponizej. Kontrola bezpieczenstwa plikow binarnych slepych na przywileje Plikiem binarnym slepym na przywileje (ang. capability-dumb) jest program oznaczony jako posiadajacy przywileje pliku, ale ktory nie zostal zmieniony w celu uzywania API libcap(3) do modyfikacji swoich przywilejow (innymi slowy jest to program korzystajacy z tradycyjnego bitu ustawienia ID roota podczas wykonania (suid), ktory zostal przelaczony do korzystania z przywilejow pliku, ale ktorego kodu nie zmodyfikowano w celu rozumienia przywilejow). W przypadku takich programow bit przywilejow efektywnych jest ustawiany na pliku, dzieki czemu przywileje dozwolone pliku sa automatycznie wlaczone w zbiorze efektywnym procesu, gdy plik jest wykonywany. Jadro rozpoznaje plik, ktory posiada ustawiony bit efektywnych przywilejow, jako slepego na przywileje, do celu opisywanej tu kontroli. Przy wykonywaniu pliku binarnego slepego na przywileje, jadro sprawdza, czy proces pozyskal wszelkie przywileje dozwolone, ktore zostaly podane w zbiorze dozwolonym pliku, po transformacji przywilejow opisanej wyzej (typowym powodem, dla ktorego moze to nie nastapic, jest zamaskowanie przez zbior ograniczajacy przywilejow niektorych przywilejow ze zbioru dozwolonego pliku). Jesli proces nie pobierze pelnego zbioru przywilejow dozwolonych, to execve(2) nie powiedzie sie z bledem EPERM. Zapobiega sie w ten sposob potencjalnemu zagrozeniu bezpieczenstwa, ktore mogloby wystapic, gdyby aplikacja slepa na przywileje zostala wykonana z mniejszymi przywilejami niz jest to wymagane. Prosze zauwazyc, ze z definicji, aplikacja nie moze sama rozpoznac tego problemu, poniewaz nie korzysta z API libcap(3). Przywileje i wykonanie programow przez roota Aby odtworzyc tradycyjna semantyke uniksowa, jadro w sposob specjalny traktuje przywileje pliku, gdy program jest wykonywany przez proces z UID 0 (tj. roota) lub gdy wykonywany jest program z bitem ustawienia ID roota (suid). Po przeprowadzeniu zmian wobec efektywnego identyfikatora procesu wyzwolonych przez bit ustawienia ID uzytkownika (suid) pliku binarnego -- jak np. przelaczenie efektywnego identyfikatora uzytkownika na 0 (tj. root), poniewaz wykonano program z ustawieniem ID uzytkownika (suid) -- jadro oblicza zbior przywilejow pliku zgodnie z ponizszymi zasadami: (1) Jesli rzeczywistym lub efektywnym identyfikatorem uzytkownika jest 0 (tj. root), to zbiory dziedziczne i dozwolone pliku sa ignorowane; zamiast tego sa one rozwazane jako wszystkie (tzn. wszystkie przywileje wlaczone). Wobec tego zachowania istnieje jeden wyjatek, opisany ponizej w rozdziale Programy z ustawieniem ID uzytkownika (suid), ktore posiadaja przywileje pliku. (2) Jesli proces ma identyfikator efektywny uzytkownika rowny 0 (tj. root) lub wlaczono bit efektywny pliku, to rozwazany jest bit efektywny pliku (jako wlaczony). Te rozwazane wartosci zbioru przywilejow pliku sa nastepnie uzywane zgodnie z opisem powyzej, do obliczenia transformacji przywilejow procesu podczas execve(2). Dlatego, gdy proces z niezerowym UID wykonuje execve(2) na programie z ustawieniem ID roota podczas wykonania (suid), ktory nie posiada dolaczonych przywilejow albo gdy proces, ktorego rzeczywiste i efektywne identyfikatory uzytkownika wynosza 0 i wykonuje execve(2) na programie, obliczenie nowych dozwolonych przywilejow procesu upraszcza sie do: P'(dozwolony) = P(dziedziczny) | P(ograniczajacy) P'(efektywny) = P'(dozwolony) W efekcie, proces zyskuje wszystkie przywileje ze swojego zbioru dozwolonego i efektywnego, z wyjatkiem tych wylaczonych zbiorem przywilejow ograniczajacych (w obliczeniu P'(dozwolonego), wyrazenie P'(tla) mozna uproscic i wykreslic, poniewaz jest to z definicji prawidlowy podzbior P(dziedzicznych)). Specjalne traktowanie uzytkownika o identyfikatorze rownym 0 (tj. roota) opisane w niniejszym podrozdziale, mozna wylaczyc za pomoca mechanizmu securebits opisanego ponizej. Programy z ustawieniem ID roota podczas wykonania (suid), ktore posiadaja przywileje pliku Istnieje jeden wyjatek wobec zachowania opisanego powyzej w rozdziale Przywileje i wykonanie programow przez roota. Jesli (a) wykonywany plik binarny ma dolaczone przywileje oraz (b) proces ma rzeczywisty identyfikator uzytkownika, ktory nie jest rowny 0 (tj. nie jest rootem) oraz (c) proces ma efektywny identyfikator uzytkownika rowny 0 (tj. root), to bity przywilejow pliku sa honorowane (tzn. nie sa rozwazane jako wszystkie wlaczone). Standardowa sytuacja, w ktorej moze to nastapic, jest wykonywanie programu z ustawieniem ID roota podczas wykonania (suid), ktory ma rowniez przywileje pliku. Gdy taki program jest wykonywany, to proces zyskuje wylacznie przywileje nadane przez program (tzn. nie wszystkie przywileje, jak staloby sie przy wykonaniu programu z ustawieniem ID roota podczas wykonania (suid), ktory nie ma przypisanych zadnych przywilejow pliku). Prosze zauwazyc, ze mozna przypisac zbior pusty przywilejow do pliku programu, zatem mozliwe jest utworzenie programu z ustawieniem ID roota podczas wykonania (suid), ktory zmienia efektywny i zapisany suid procesu wykonujacego program na 0, ale nie przyznaje mu zadnych przywilejow. Zbior przywilejow ograniczajacych Zbior przywilejow ograniczajacych jest mechanizmem bezpieczenstwa, ktorego mozna uzyc do ograniczenia przywilejow, ktore mozna zyskac podczas execve(2). Zbior ograniczajacy jest uzywany na nastepujace sposoby: o Podczas execve(2), zbior przywilejow ograniczajacych jest sumowany ze zbiorem przywilejow dozwolonych, a wynik tej operacji jest przypisywany do zbioru przywilejow dozwolonych watku. Zbior przywilejow ograniczajacych ogranicza zatem przywileje dozwolone, ktore moga byc przyznane plikowi wykonywalnemu. o (Od Linuksa 2.6.25) Zbior przywilejow ograniczajacych dziala jako nadzbior ograniczajacy wobec przywilejow, ktore moga byc dodane przez watek do swojego zbioru dziedzicznego za pomoca capset(2). Oznacza to, ze jesli przywilej nie wystepuje w zbiorze ograniczajacym, to watek nie moze dodac go do swoich przywilejow dozwolonych, tym samym nie moze zachowac tego przywileju swoim zbiorze dopuszczalnym, gdy wykona execve(2) na pliku, ktory posiada ten przywilej w swoim zbiorze dziedzicznym. Prosze zauwazyc, ze zbior ograniczajacy ogranicza przywileje dozwolone, ale nie ogranicza przywilejow dziedzicznych. Jesli watek zachowa przywilej, niebedacy w jego zbiorze ograniczajacym, w swoim zbiorze dziedzicznym, to moze wciaz zyskac ten przywilej w swoim zbiorze dozwolonym, wykonujac plik, posiadajacy ten przywilej w swoim zbiorze dziedzicznym. W zaleznosci od wersji jadra, zbior przywilejow ograniczajacych jest atrybutem albo systemowym, albo przypisanym watkowi. Zbior przywilejow ograniczajacych od Linuksa 2.6.25 Od Linuksa 2.6.25, zbior przywilejow ograniczajacych jest przypisany watkowi (opisany nizej systemowy zbior przywilejow ograniczajacych juz nie istnieje). Zbior ograniczajacy jest dziedziczony w momencie wykonania fork(2) od watku rodzicielskiego i jest zachowywany przy execve(2). Watek moze usunac przywileje ze swojego zbioru ograniczajacego za pomoca operacji PR_CAPBSET_DROP prctl(2), zakladajac ze ma przywilej CAP_SETPCAP. Po usunieciu przywileju ze zbioru ograniczajacego, nie da sie go tam przywrocic. Watek moze sprawdzic czy przywilej znajduje sie w jego zbiorze ograniczajacym, za pomoca operacji PR_CAPBSET_READ prctl(2). Usuwanie przywilejow ze zbioru ograniczajacego jest obslugiwane wylacznie, jesli w jadro wkompilowano przywileje pliku. Przed Linuksem 2.6.33, przywileje pliku byly opcjonalne i konfigurowalo sie je opcja CONFIG_SECURITY_FILE_CAPABILITIES. Od Linuksa 2.6.33 opcje te usunieto, a przywileje pliku sa zawsze czescia jadra. Gdy przywileje pliku wkompilowano w jadro, proces init (przodek wszystkich procesow) zaczyna dzialanie z pelnym zbiorem ograniczajacym. Jesli przywileje pliku nie sa wkompilowane w jadro, to init rozpocznie z pelnym zbiorem ograniczajacym minus CAP_SETPCAP, poniewaz przywilej ten zmienia znaczenie, gdy nie wystepuja przywileje pliku. Usuniecie przywileju ze zbioru ograniczajacego nie usuwa go ze zbioru dziedzicznego watku. Uniemozliwia jednak ponowne dodanie przywileju do zbioru dziedzicznego watku w przyszlosci. Zbior przywilejow ograniczajacych przed Linuksem 2.6.25 Przed Linuksem 2.6.25 zbior przywilejow ograniczajacych jest atrybutem systemowym, dotyczacym wszystkich watkow w systemie. Zbior ograniczajacy jest dostepny za posrednictwem pliku /proc/sys/kernel/cap-bound (co mylace, ten parametr maski bitowej jest w /proc/sys/kernel/cap-bound prezentowany jako liczba dziesietna ze znakiem). Tylko proces init moze ustawic przywileje w zbiorze przywilejow ograniczajacych, natomiast superuzytkownik (precyzyjniej: proces z przywilejem CAP_SYS_MODULE) moze jedynie usunac przywileje z tego zbioru. W standardowym systemie, maska zbioru przywilejow ograniczajacych zawsze prowadzi do usuniecia przywileju CAP_SETPCAP. Aby usunac to ograniczenie (niebezpieczne!), nalezy zmodyfikowac definicje CAP_INIT_EFF_SET w include/linux/capability.h i przebudowac jadro. Funkcje systemowego zbioru przywilejow ograniczajacych dodano w jadrze Linux 2.2.11. Wplyw zmian identyfikatora uzytkownika na przywileje Aby zachowac tradycyjna semantyke przejscia pomiedzy identyfikatorami uzytkownikow rownymi i roznymi od 0, jadro dokonuje nastepujacych zmian w zbiorach przywilejow watku przy zmianach nastepujacych identyfikatorow uzytkownika (za pomoca setuid(2), setresuid(2) lub podobnych): rzeczywistego, efektywnego, zbioru zapisanego oraz systemu plikow: o Jesli jeden lub kilka z identyfikatorow: rzeczywistego, efektywnego lub zbioru zapisanego wynosil uprzednio 0, a wynikiem zmian identyfikatorow uzytkownikow jest wartosc niezerowa wszystkich tych identyfikatorow, to ze zbioru przywilejow: dozwolonego, efektywnego i tla usuwane sa wszystkie przywileje. o Jesli efektywny identyfikator uzytkownika zmienil sie z 0 na wartosc niezerowa, to ze zbioru efektywnego usuwane sa wszystkie przywileje. o Jesli efektywny identyfikator uzytkownika zmienil sie z wartosci niezerowej na 0, to zbior dozwolony jest kopiowany do zbioru efektywnego. o Jesli identyfikator uzytkownika systemu plikow zmienil sie z 0 na wartosc niezerowa (zob. setfsuid(2)), to nastepujace przywileje sa usuwane ze zbioru efektywnego: CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_LINUX_IMMUTABLE (od Linuksa 2.6.30), CAP_MAC_OVERRIDE i CAP_MKNOD (od Linuksa 2.6.30). Jesli UID systemu plikow zmieni sie z wartosci niezerowej na 0, to przywileje wlaczone w zbiorze dozwolonym sa wlaczane w zbiorze efektywnym. Jesli watek posiadajacy wartosc rowna 0 dla jednego lub kilku swoich identyfikatorow uzytkownika chce zapobiec usunieciu swojego zbioru przywilejow dozwolonych przy zresetowaniu wszystkich swoich wartosci identyfikatorow uzytkownika na wartosci niezerowe, moze to uczynic za pomoca znacznika securebits SECBIT_KEEP_CAPS opisanego nizej. Programowe dostosowywanie zbioru przywilejow Watek moze pobierac i zmieniac swoje zbiory przywilejow: dozwolonych, efektywnych i dziedzicznych za pomoca wywolan systemowych capget(2) i capset(2). Zaleca sie jednak stosowanie do tego celu cap_get_proc(3) i cap_set_proc(3) z pakietu libcap. Zmiany zbiorow przywilejow watku rzadza sie nastepujacymi prawami: o Jesli wywolujacy nie posiada przywileju CAP_SETPCAP, to nowy zbior dziedziczny musi byc podzbiorem kombinacji istniejacych zbiorow: dziedzicznego i dozwolonego. o (Od Linuksa 2.6.25) Nowy zbior dziedziczny musi byc podzbiorem kombinacji istniejacych zbiorow: dziedzicznego i ograniczajacego. o Nowy zbior dozwolony musi byc podzbiorem istniejacego zbioru dozwolonego (tzn. nie da sie zyskac nowych przywilejow dozwolonych, ktorych watek nie mial do tej pory). o Nowy zbior efektywny musi byc podzbiorem nowego zbioru dozwolonego. Znaczniki securebits: tworzenie srodowiska korzystajacego wylacznie z przywilejow Poczawszy od Linuksa 2.6.26 i jadra, w ktorym wlaczono przywileje pliku, Linux implementuje zbior znacznikow securebits przypisanych watkowi, ktore moga wylaczyc specjalne traktowanie przywilejow identyfikatora uzytkownika rownego 0 (tj. roota). Wystepuja znaczniki: SECBIT_KEEP_CAPS Ustawienie tego znacznika pozwala watkowi posiadajacemu jeden lub wiecej UID-ow rownych 0 na zachowanie przywilejow w swoim zbiorze dozwolonym, po przelaczeniu wszystkich swoich UID-ow na wartosci niezerowe. Jesli znacznik ten nie jest ustawiony, to takie przelaczenie powoduje utrate przez watek wszystkich przywilejow dozwolonych. Znacznik ta jest zawsze czyszczony przy wykonaniu execve(2). Prosze zauwazyc, ze nawet gdy ustawiony jest znacznik SECBIT_KEEP_CAPS, to przywileje efektywne watku sa usuwane przy przelaczeniu swojego efektywnego UID-u na wartosc niezerowa. Jednak gdy watek ma ten znacznik ustawiony, jego efektywny UID ma juz wartosc niezerowa, a watek przelaczy nastepnie wszystkie inne UID-y na wartosci niezerowe, to przywileje efektywne watku nie zostana usuniete. Ustawienie znacznika SECBIT_KEEP_CAPS jest ignorowane, gdy ustawiony jest znacznik SECBIT_NO_SETUID_FIXUP (ten ostatnia zapewnia nadzbior efektow pierwszego znacznika). Znacznik zapewnia taka sama funkcjonalnosc, jak starsza operacja PR_SET_KEEPCAPS prctl(2). SECBIT_NO_SETUID_FIXUP Ustawienie tego znacznika powstrzyma jadro przed dostosowywaniem zbiorow przywilejow procesu: dozwolonych, efektywnych i tla, w sytuacji, gdy UID-y watku: efektywne i systemu plikow, sa przelaczane miedzy wartosciami zera i niezerowymi. Wiecej informacji w rozdziale Wplyw zmian identyfikatora uzytkownika na przywileje powyzej. SECBIT_NOROOT Jesli bit ten jest ustawiony, jadro nie przydziela przywilejow gdy wykonywany jest program z ustawieniem ID roota podczas wykonania (suid), albo gdy proces z efektywnym lub rzeczywistym UID-em rownym 0 wywoluje execve(2). (zob. rozdzial Przywileje i wykonanie programow przez roota powyzej.) SECBIT_NO_CAP_AMBIENT_RAISE Ustawienie tego znacznika uniemozliwia podniesienie przywilejow tla za pomoca operacji PR_CAP_AMBIENT_RAISE prctl(2). Kazdy z powyzszych znacznikow ,,podstawowych" ma towarzyszacy mu znacznik ,,blokujacy". Ustawienie znacznika ,,blokujacego" jest nieodwracalne i zapobiega dalszym zmianom odpowiadajacemu mu znacznikowi ,,podstawowemu". Istnieja nastepujace znaczniki blokujace: SECBIT_KEEP_CAPS_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED, SECBIT_NOROOT_LOCKED i SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED. Znaczniki securebits mozna zmodyfikowac i pobrac za pomoca operacji PR_SET_SECUREBITS i PR_GET_SECUREBITS prctl(2). Do modyfikowania znacznikow potrzebny jest przywilej CAP_SETPCAP. Prosze zauwazyc, ze stale SECBIT_* sa dostepne tylko wowczas, gdy sa umieszczone w pliku naglowkowym . Znaczniki securebits sa dziedziczone przez procesy potomne. Podczas execve(2) zachowywane sa wszystkie znaczniki poza SECBIT_KEEP_CAPS, ktory jest zawsze usuwany. Aplikacja moze uzyc nastepujacego wywolania do zablokowania siebie i wszystkich swoich potomkow w srodowisku, w ktorym jedyna metoda zyskania przywilejow, jest wykonanie programu z powiazanymi przywilejami plikow: prctl(PR_SET_SECUREBITS, /* SECBIT_KEEP_CAPS wylaczone */ SECBIT_KEEP_CAPS_LOCKED | SECBIT_NO_SETUID_FIXUP | SECBIT_NO_SETUID_FIXUP_LOCKED | SECBIT_NOROOT | SECBIT_NOROOT_LOCKED); /* Ustawienie/zablokowanie SECBIT_NO_CAP_AMBIENT_RAISE nie jest wymagane */ Programy z ustawieniem ID roota podczas wykonania (suid) na przestrzen uzytkownika Programy z ustawieniem ID roota podczas wykonania (suid), ktorych identyfikatory uzytkownika pasuja do identyfikatorow uzytkownika, ktory utworzyl przestrzen nazw uzytkownika, beda mialy przyznane przywileje w zbiorach procesu: dozwolonym i efektywnym, przy wykonywaniu przez dowolny proces z tej przestrzeni nazw i z kazdej potomnej przestrzeni nazw. Reguly regulujace transformacje przywilejow procesu podczas execve(2) sa identyczne z opisanymi w Transformacja przywilejow podczas execve() oraz Przywileje i wykonanie programow przez roota powyzej, z jedyna roznica, ze w drugim z podrozdzialow ,,root" jest identyfikatorem uzytkownika tworzacego przestrzen nazw uzytkownika. Przywileje pliku w przestrzeni nazw Tradycyjne (tzn. w wersji 2) przywileje pliku wiaza jedynie zbior masek przywilejow z binarnym plikiem wykonywalnym. Gdy proces wykonuje plik binarny z takimi przywilejami, zyskuje powiazane przywileje (w swojej przestrzeni nazw) wedlug regul opisanych w rozdziale Transformacja przywilejow podczas execve() powyzej. Poniewaz przywileje pliku w wersji 2 przyznaja przywileje procesowi wykonujacemu bez wzgledu na przestrzen nazw, w ktorej on rezyduje, jedynie procesy uprzywilejowane moga przypisywac przywileje do pliku. Tu ,,uprzywilejowany" oznacza proces, ktory ma przywilej CAP_SETFCAP w przestrzeni nazw uzytkownika, w ktorej zamontowano system plikow (zwykle pierwotna przestrzen nazw uzytkownika). To ograniczenie czyni przywileje pliku bezuzytecznymi w niektorych zastosowaniach. Przykladowo, w kontenerach przestrzeni nazw uzytkownika przydatna moze sie okazac mozliwosc utworzenia pliku binarnego, ktory przyznaje przywileje jedynie procesowi wykonywanemu wewnatrz takiego kontenera, ale nie procesom wykonywanym na zewnatrz kontenera. Linux 4.14 dodal tak zwane przywileje pliku w przestrzeni nazw, w celu obslugi takich przypadkow. Sa one zapisywane jako atrybuty rozszerzone security.capability wersji 3. (tzn. VFS_CAP_REVISION_3). Takie atrybuty sa tworzone automatycznie w okolicznosciach opisanych w rozdziale Wersjonowanie atrybutu rozszerzonego przywilejow pliku powyzej. Przy tworzeniu atrybutu rozszerzonego security.capability w wersji 3., w atrybucie rozszerzonym jadro zapisze nie tylko maske przywileju, lecz takze identyfikator uzytkownika root w przestrzeni nazw. Podobnie jak z plikiem binarnym z przywilejami pliku VFS_CAP_REVISION_2, plik binarny z przywilejami pliku VFS_CAP_REVISION_3 przyznaje przywileje procesowi podczas execve(). Jednakze przywileje sa przyznawane tylko gdy plik binarny jest wykonywany przez proces rezydujacy w przestrzeni nazw uzytkownika, ktorego identyfikator uzytkownika 0 jest przypisany do identyfikatora uzytkownika root zachowywanego w atrybucie rozszerzonym lub gdy jest wykonywany przez proces rezydujacy w potomkach takiej przestrzeni nazw. Interakcja z przestrzeniami nazw uzytkownikow Wiecej informacji o interakcji przywilejow i przestrzeni nazw uzytkownika znajduje sie w podreczniku user_namespaces(7). STANDARDY Nie istnieja standardy opisujace przywileje, lecz linuksowa implementacja przywilejow powstala w oparciu o wycofany szkic standardu POSIX.1e . UWAGI Przy probie wykonania strace(1) na plikach binarnych posiadajacych przywileje (lub plikach binarnych z ustawieniem ID roota podczas wykonania (suid)) przydatna moze okazac sie opcja -u . Przyklad: $ sudo strace -o trace.log -u uzytkownik ./mojprywatnyprogram W jadrze Linux w wersjach od 2.5.27 do 2.6.26, przywileje byly opcjonalna czescia jadra i mogly byl wlaczane i wylaczane opcja konfiguracji jadra CONFIG_SECURITY_CAPABILITIES. Aby zobaczyc zbiory przywilejow watku mozna uzyc pliku /proc/pid/task/TID/status. Plik /proc/pid/status pokazuje zbiory przywilejow glownego watku procesu. Przed Linuksem 3.8 w tych zbiorach pokazywane byly jako wlaczone (1) przywileje nieistniejace. Od Linuksa 3.8, wszystkie nieistniejace przywileje (powyzej CAP_LAST_CAP) sa pokazywane jako wylaczone (0). Pakiet libcap udostepnia zestaw procedur do ustawiania i pobierania przywilejow, ktory jest bardziej komfortowy i mniej narazony na zmiany niz interfejs udostepniamy przez capset(2) i capget(2). Pakiet ten zawiera rowniez programy setcap(8) i getcap(8). Mozna go znalezc na stronie . Przed Linuksem 2.6.24, oraz w Linuksie 2.6.24 do 2.6.32 - jesli nie wlaczono przywilejow, watek z przywilejem CAP_SETPCAP moze zmieniac przywileje innego watku. Jest to jednak wylacznie mozliwosc teoretyczna, poniewaz watek nigdy nie posiada CAP_SETPCAP w zadnym z dwoch ponizszych przypadkow: o W implementacji przed wersja 2.6.25 zbior przywilejow ograniczajacych na poziomie systemu, /proc/sys/kernel/cap-bound, zawsze maskowal przywilej CAP_SETPCAP usuwajac go i nie da sie zmienic tego zachowania bez modyfikacji zrodel jadra i przebudowania jadra. o Jesli przywileje pliku sa wylaczone (tzn. opcja jadra CONFIG_SECURITY_FILE_CAPABILITIES jest wylaczona), to init uruchomi sie z przywilejem CAP_SETPCAP usunietym ze swojego zbioru ograniczajacego przypisanego do procesu, a ten zbior ograniczajacy jest nastepnie dziedziczony przez wszystkie procesy utworzone w systemie. ZOBACZ TAKZE capsh(1), setpriv(1), prctl(2), setfsuid(2), cap_clear(3), cap_copy_ext(3), cap_from_text(3), cap_get_file(3), cap_get_proc(3), cap_init(3), capgetp(3), capsetp(3), libcap(3), proc(5), credentials(7), pthreads(7), user_namespaces(7), captest(8), filecap(8), getcap(8), getpcaps(8), netcap(8), pscap(8), setcap(8) include/linux/capability.h w drzewie zrodel jadra Linux TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.06 31 pazdziernika 2023 r. Capabilities(7)