Capacități(7)

NUME
capacități - prezentare generală a capacităților Linux

DESCRIERE
În scopul efectuării verificării permisiunilor, implementările tradiționale UNIX disting două categorii de procese: procese privilegiate (al căror ID utilizator efectiv este 0, denumit superutilizator sau root) și procese neprivilegiate (al căror UID efectiv este diferit de zero). Procesele privilegiate ocolesc toate verificările de permisiuni ale nucleului, în timp ce procesele neprivilegiate sunt supuse unei verificări complete a permisiunilor pe baza acreditărilor procesului (de obicei: UID efectiv, GID efectiv și lista suplimentară de grupuri).

Începând cu Linux 2.2, Linux împarte privilegiile asociate în mod tradițional cu superutilizatorul în unități distincte, cunoscute sub numele de capabilities(capacități), care pot fi activate și dezactivate independent. Capacitățile sunt un atribut per-fir de execuție.

  Lista capacităților
Următoarea listă prezintă capacitățile implementate pe Linux și operațiile sau comportamentele pe care le permite fiecare capacitate:

CAP_AUDIT_CONTROL (începând cu Linux 2.6.11)
    Activează și dezactivează auditarea nucleului; modifică regulile de filtrare a auditării; recuperează starea auditării și regulile de filtrare.

CAP_AUDIT_READ (începând cu Linux 3.16)
    Permite citirea jurnalului de auditare prin intermediul unui soclu multicast netlink.

CAP_AUDIT_WRITE (începând cu Linux 2.6.11)
    Scrie înregistrări în jurnalul de auditare al nucleului.

CAP_BLOCK_SUSPEND (începând cu Linux 3.5)
    Utilizează caracteristici care pot bloca suspendarea sistemului (epoll(7) EPOLLWAKEUP, /proc/sys/wake_lock).

CAP_BPF (începând cu Linux 5.8)
    Utilizează operații BPF privilegiate; a se vedea bpf(2) și bpf-helpers(7).

    Această capacitate a fost adăugată în Linux 5.8 pentru a separa funcționalitatea BPF de capacitatea supraîncărcată CAP_SYS_ADMIN.

CAP_CHECKPOINT_RESTORE (începând cu Linux 5.9)
    •   Actualizează /proc/sys/kernel/ns_last_pid (a se vedea pid_namespaces(7));
    •   utilizează funcția set_tid din clone3(2);
    •   citește conținutul legăturilor simbolice din /proc/pid/map_files pentru alte procese.

    Această capacitate a fost adăugată în Linux 5.9 pentru a separa funcționalitatea punct de control/restaurare de capacitatea supraîncărcată CAP_SYS_ADMIN.

CAP_CHOWN
    Efectuează modificări arbitrare ale UID-urilor și GID-urilor fișierelor (consultați chown(2)).

CAP_DAC_OVERRIDE
    Ocolește verificarea permisiunilor de citire, scriere și executare a fișierelor. (DAC este o abreviere de la „discretionary access control” - control discreționar al accesului).

CAP_DAC_READ_SEARCH
    •   Ocolește verificarea permisiunilor de citire a fișierelor și verificarea permisiunilor de citire și executare a directoarelor;
    •   invocă open_by_handle_at(2);
    •   utilizează fanionul linkat(2) AT_EMPTY_PATH pentru a crea o legătură către un fișier la care se face referire printr-un descriptor de fișier.

CAP_FOWNER
    •   Ocolește verificările permisiunilor pentru operațiile care, în mod normal, necesită ca UID-ul sistemului de fișiere al procesului să coincidă cu UID-ul fișierului (de exemplu, chmod(2), utime(2)), excluzând acele operații acoperite de CAP_DAC_OVERRIDE și CAP_DAC_READ_SEARCH;
    •   definește fanioanele de nod-i (a se vedea FS_IOC_SETFLAGS(2const)) pe fișiere arbitrare;
    •   configurează listele de control al accesului (ACL) pe fișiere arbitrare;
    •   ignoră bitul lipicios al directorului la ștergerea fișierului;
    •   modifică atributele extinse ale utilizatorului pe directorul lipicios deținut de orice utilizator;
    •   specifică O_NOATIME pentru fișiere arbitrare în open(2) și fcntl(2).

CAP_FSETID
    •   Nu șterge biții de mod set-user-ID și set-group-ID atunci când un fișier este modificat;
    •   activează bitul set-group-ID pentru un fișier al cărui GID nu corespunde sistemului de fișiere sau niciunuia dintre GID-urile suplimentare ale procesului apelant.

CAP_IPC_LOCK
    •   Blochează memoria (mlock(2), mlockall(2), mmap(2), shmctl(2));
    •   Alocă memorie folosind pagini enorme (memfd_create(2), mmap(2), shmctl(2)).

CAP_IPC_OWNER
    Ocolește verificările permisiunilor pentru operațiile asupra obiectelor IPC System V.

CAP_KILL
    Ocolește verificările permisiunilor pentru trimiterea semnalelor (consultați kill(2)). Aceasta include utilizarea operației ioctl(2) KDSIGACCEPT.

CAP_LEASE (începând cu Linux 2.4)
    Stabilește închirieri(leases) pe fișiere arbitrare (consultați fcntl(2)).

CAP_LINUX_IMMUTABLE
    Definește fanioanele de nod-i FS_APPEND_FL și FS_IMMUTABLE_FL (a se vedea FS_IOC_SETFLAGS(2const)).

CAP_MAC_ADMIN (începând cu Linux 2.6.25)
    Permite modificarea configurației sau a stării MAC. Implementată pentru Smack Linux Security Module (LSM).

CAP_MAC_OVERRIDE (începând cu Linux 2.6.25)
    Suprascrie controlul accesului obligatoriu (MAC). Implementată pentru Smack LSM.

CAP_MKNOD (începând cu Linux 2.4)
    Creează fișiere speciale utilizând mknod(2).

CAP_NET_ADMIN
    Efectuează diverse operații legate de rețea:
    •   configurarea interfeței;
    •   administrarea de firewall IP, mascare și contorizare;
    •   modifică tabelele de direcționare;
    •   să se conecteze la orice adresă pentru proxing transparent;
    •   stabilește tipul de serviciu (TOS);
    •   șterge statisticile controlorului;
    •   definește modul promiscuu;
    •   activează modul de multidifuzare(multicasting);
    •   utilizează setsockopt(2) pentru a defini următoarele opțiuni de soclu: SO_DEBUG, SO_MARK, SO_PRIORITY (pentru o prioritate în afara intervalului 0-6), SO_RCVBUFFORCE și SO_SNDBUFFORCE.

CAP_NET_BIND_SERVICE
    Asociază un soclu la porturile privilegiate ale domeniului Internet (numere de porturi mai mici de 1024).

CAP_NET_BROADCAST
    (Nefolosită) Efectuează difuzări (broadcasts) de soclu și ascultă „multicasts”.

CAP_NET_RAW
    •   Utilizează socluri RAW și PACKET;
    •   să se conecteze la orice adresă pentru proxing transparent.

CAP_PERFMON (începând cu Linux 5.8)
    Utilizează diverse mecanisme de monitorizare a performanței, inclusiv:

    •   apelul perf_event_open(2);
    •   utilizează diverse operații BPF care au implicații asupra performanței.

    Această capacitate a fost adăugată în Linux 5.8 pentru a separa funcționalitatea de monitorizare a performanței de capacitatea supraîncărcată CAP_SYS_ADMIN. Consultați și fișierul sursă al nucleului Documentation/admin-guide/perf-security.rst.

CAP_SETGID
    •   Efectuează manipulări arbitrare ale GID-urilor de proces și ale listei suplimentare de GID-uri;
    •   falsifică GID atunci când pasează acreditările soclului prin intermediul soclurilor de domeniu UNIX;
    •   scrie o corespondență ID de grup într-un spațiu de nume al utilizatorului [a se vedea user_namespaces(7)].

CAP_SETFCAP (începând cu Linux 2.6.24)
    Definește capacități arbitrare pe un fișier.

    Începând cu Linux 5.12, această capacitate este de asemenea necesară pentru cartografierea ID-ului utilizatorului 0 într-un nou spațiu de nume al utilizatorului; pentru detalii, consultați user_namespaces(7).

CAP_SETPCAP
    În cazul în care sunt acceptate capacitățile de fișier (de exemplu, începând cu Linux 2.6.24): adaugă orice capacitate din setul limitator al firului apelant la setul său moștenit; renunță la capacitățile din setul limitator (prin prctl(2) PR_CAPBSET_DROP); efectuează modificări ale fanioanelor securebits.

    În cazul în care capacitățile de fișier nu sunt acceptate (de exemplu, înainte de Linux 2.6.24): acordă sau elimină orice capacitate din setul de capacități permise ale apelantului către sau de la orice alt proces; (această proprietate a CAP_SETPCAP nu este disponibilă atunci când nucleul este configurat pentru a oferi suport capacităților de fișier, deoarece CAP_SETPCAP are o semantică complet diferită pentru astfel de nuclee).

CAP_SETUID
    •   Efectuează manipulări arbitrare ale UID-urilor proceselor (setuid(2), setreuid(2), setresuid(2), setfsuid(2));
    •   falsifică UID atunci când pasează acreditările soclului prin intermediul soclurilor de domeniu UNIX;
    •   scrie o corespondență ID utilizator într-un spațiu de nume utilizator [a se vedea user_namespaces(7)].

CAP_SYS_ADMIN
    Notă: această capacitate este supraîncărcată; a se vedea mai jos secțiunea Note pentru dezvoltatorii nucleului.

    •   Efectuează o serie de operații de administrare a sistemului, inclusiv: quotactl(2), mount(2), umount(2), pivot_root(2), swapon(2), swapoff(2), sethostname(2) și setdomainname(2);
    •   efectuează operații privilegiate syslog(2) (începând cu Linux 2.6.37, CAP_SYSLOG trebuie să fie utilizată pentru a permite astfel de operații);
    •   execută comanda VM86_REQUEST_IRQ vm86(2);
    •   accesează aceeași funcționalitate de punct de control/restaurare care este reglementată de CAP_CHECKPOINT_RESTORE (dar pentru accesarea acestei funcționalități este preferată această din urmă capacitate, mai slabă).
    •   efectuează aceleași operații BPF ca și cele reglementate de CAP_BPF (dar această din urmă capacitate, mai slabă, este preferată pentru accesarea funcționalității respective).
    •   utilizează aceleași mecanisme de monitorizare a performanțelor ca și cele reglementate de CAP_PERFMON (dar pentru accesarea acestei funcționalități se preferă această din urmă capacitate, mai slabă).
    •   efectuează operații IPC_SET și IPC_RMID pe obiecte IPC System V arbitrare;
    •   suprascrie limita resurselor RLIMIT_NPROC;
    •   efectuează operații asupra atributelor extinse trusted și security [a se vedea xattr(7)];
    •   utilizează lookup_dcookie(2);
    •   utilizează ioprio_set(2) pentru a atribui clasele de planificare I/O IOPRIO_CLASS_RT și (înainte de Linux 2.6.25) IOPRIO_CLASS_IDLE;
    •   falsifică PID atunci când pasează acreditările soclului prin intermediul soclurilor de domeniu UNIX;
    •   depășește /proc/sys/fs/file-max, limita la nivel de sistem a numărului de fișiere deschise, în apelurile sistemului care deschid fișiere (de exemplu, accept(2), execve(2), open(2), pipe(2));
    •   utilizează fanioanele CLONE_* care creează noi spații de nume cu clone(2) și unshare(2) (dar, de la Linux 3.8, crearea de spații de nume de utilizator nu necesită nicio capacitate);
    •   accesează informațiile privilegiate ale evenimentului perf;
    •   apelează setns(2) (necesită CAP_SYS_ADMIN în spațiul de nume target);
    •   apelează fanotify_init(2);
    •   efectuează operații privilegiate KEYCTL_CHOWN și KEYCTL_SETPERM keyctl(2);
    •   efectuează operația madvise(2) MADV_HWPOISON;
    •   utilizează TIOCSTI ioctl(2) pentru a introduce caractere în coada de intrare a unui alt terminal decât terminalul de control al apelantului;
    •   utilizează apelul de sistem învechit nfsservctl(2);
    •   utilizează apelul de sistem învechit bdflush(2);
    •   efectuează diverse operații privilegiate ioctl(2) cu dispozitive de blocuri;
    •   efectuează diverse operații privilegiate ioctl(2) cu sistemul de fișiere;
    •   efectuează operații privilegiate ioctl(2) pe dispozitivul /dev/random (consultați random(4));
    •   instalează un filtru seccomp(2) fără a fi necesar să definească mai întâi atributul firului no_new_privs;
    •   modifică regulile de autorizare/respingere pentru grupurile de control ale dispozitivelor;
    •   utilizează operația ptrace(2) PTRACE_SECCOMP_GET_FILTER pentru a descărca filtrele seccomp ale urmei(traseului)
    •   utilizați operația ptrace(2) PTRACE_SETOPTIONS pentru a suspenda protecțiile seccomp ale traseului (de exemplu, fanionul PTRACE_O_SUSPEND_SECCOMP);
    •   efectuează operații administrative asupra mai multor controlori de dispozitive;
    •   modifică valorile de curtoazie ale autogrupului prin scrierea în /proc/pid/autogroup [a se vedea sched(7)].

CAP_SYS_BOOT
    Utilizează reboot(2) și kexec_load(2).

CAP_SYS_CHROOT
    •   Utilizează chroot(2);
    •   modifică spațiile de nume de montare utilizând setns(2).

CAP_SYS_MODULE
    •   Încarcă și descarcă module ale nucleului (a se vedea init_module(2) și delete_module(2));
    •   înainte de Linux 2.6.25: renunța la capacitățile din setul de delimitare a capacităților la nivel de sistem.

CAP_SYS_NICE
    •   Reduce valoarea de curtoazie (nice) a procesului (nice(2), setpriority(2)) și modifică valoarea de curtoazie pentru procesele arbitrare;
    •   stabilește politici de planificare în timp real pentru procesul apelant și stabilește politici de planificare și priorități pentru procese arbitrare (sched_setscheduler(2), sched_setparam(2), sched_setattr(2));
    •   stabilește afinitatea CPU pentru procese arbitrare (sched_setaffinity(2));
    •   stabilește clasa de planificare a In/Ieș și prioritatea pentru procese arbitrare (ioprio_set(2));
    •   aplică migrate_pages(2) la procese arbitrare și permite migrarea proceselor către noduri arbitrare;
    •   aplică move_pages(2) pe procese arbitrare;
    •   utilizează fanionul MPOL_MF_MOVE_ALL cu mbind(2) și move_pages(2).

CAP_SYS_PACCT
    Utilizează acct(2).

CAP_SYS_PTRACE
    •   Urmărește procese arbitrare folosind ptrace(2);
    •   aplică get_robust_list(2) pe procese arbitrare;
    •   transferă date către sau din memoria unor procese arbitrare utilizând process_vm_readv(2) și process_vm_writev(2);
    •   inspectează procesele utilizând kcmp(2).

CAP_SYS_RAWIO
    •   Efectuează operații ale portului de In/Ieș (iopl(2) și ioperm(2));
    •   accesează /proc/kcore;
    •   utilizează operația FIBMAP ioctl(2);
    •   deschide dispozitive pentru accesarea registrelor specifice modelului x86 (MSR, vezi msr(4));
    •   actualizează /proc/sys/vm/mmap_min_addr;
    •   creează corespondențe de memorie la adrese sub valoarea specificată de /proc/sys/vm/mmap_min_addr;
    •   cartografiază fișierele în /proc/bus/pci;
    •   deschide /dev/mem și /dev/kmem;
    •   efectuează diverse comenzi pentru dispozitive SCSI;
    •   efectuează anumite operații pe dispozitive hpsa(4) și cciss(4);
    •   efectuează o serie de operații specifice dispozitivelor pe alte dispozitive.

CAP_SYS_RESOURCE
    •   Utilizează spațiul rezervat pe sistemele de fișiere ext2;
    •   face apeluri ioctl(2) care controlează jurnalizarea ext3;
    •   suprascrie limitele cotelor de disc;
    •   crește limitele resurselor (a se vedea setrlimit(2));
    •   suprascrie limita resurselor RLIMIT_NPROC;
    •   suprascrie numărul maxim de console în alocarea consolelor;
    •   suprascrie numărul maxim de aranjamente de tastatură;
    •   permite întreruperi mai mari de 64hz de la ceasul în timp real;
    •   ridică limita msg_qbytes pentru o coadă de mesaje System V peste limita din /proc/sys/kernel/msgmnb (consultați msgop(2) și msgctl(2));
    •   permite ca limita de resurse RLIMIT_NOFILE privind numărul de descriptori de fișiere „în zbor” să fie ocolită atunci când se transmit descriptori de fișiere unui alt proces prin intermediul unui soclu de domeniu UNIX [a se vedea unix(7)];
    •   suprascrie limita /proc/sys/fs/pipe-size-max atunci când se stabilește capacitatea unei conducte utilizând comanda F_SETPIPE_SZ fcntl(2);
    •   utilizează F_SETPIPE_SZ pentru a crește capacitatea unei conducte peste limita specificată de /proc/sys/fs/pipe-max-size;
    •   suprascrie limitele /proc/sys/fs/mqueue/queues_max, /proc/sys/fs/mqueue/msg_max și /proc/sys/fs/mqueue/msgsize_max la crearea cozilor de mesaje POSIX (consultați mq_overview(7));
    •   utilizează operația prctl(2) PR_SET_MM;
    •   stabilește /proc/pid/oom_score_adj la o valoare mai mică decât ultima valoare stabilită de un proces cu CAP_SYS_RESOURCE.

CAP_SYS_TIME
    Reglează ceasul sistemului (settimeofday(2), stime(2), adjtimex(2)); reglează ceasul în timp real (hardware).

CAP_SYS_TTY_CONFIG
    Utilizează vhangup(2); utilizează diverse operații privilegiate ioctl(2) pe terminale virtuale.

CAP_SYSLOG (începând cu Linux 2.6.37)
    •   Efectuează operații privilegiate syslog(2). Consultați syslog(2) pentru informații privind operațiile care necesită privilegii.
    •   Vizualizează adresele nucleului expuse prin /proc și alte interfețe atunci când /proc/sys/kernel/kptr_restrict are valoarea 1. (Consultați discuția despre kptr_restrict în proc(5).)

CAP_WAKE_ALARM (începând cu Linux 3.0)
    Declanșează ceva care va trezi sistemul (definește temporizatoarele CLOCK_REALTIME_ALARM și CLOCK_BOOTTIME_ALARM).

  Implementarea trecută și actuală
O implementare completă a capacităților necesită următoarele:

•   Pentru toate operațiile privilegiate, nucleul trebuie să verifice dacă firul are capacitatea necesară în setul său efectiv.

•   Nucleul trebuie să furnizeze apeluri de sistem care să permită modificarea și recuperarea seturilor de capacități ale unui fir.

•   Sistemul de fișiere trebuie să permită atașarea de capacități la un fișier executabil, astfel încât un proces să obțină aceste capacități atunci când fișierul este executat.

Înainte de Linux 2.6.24, doar primele două dintre aceste cerințe sunt îndeplinite; începând cu Linux 2.6.24, toate cele trei cerințe sunt îndeplinite.

  Note pentru dezvoltatorii nucleului
Când adăugați o nouă caracteristică a nucleului care ar trebui să fie reglementată de o capacitate, luați în considerare următoarele puncte.

•   Scopul capacităților este de a împărți puterea superutilizatorului în părți, astfel încât, dacă un program care are una sau mai multe capacități este compromis, puterea sa de a provoca daune sistemului să fie mai mică decât a aceluiași program care rulează cu privilegii de root.

•   Puteți alege fie să creați o nouă capacitate pentru noua caracteristică, fie să asociați caracteristica cu una dintre capacitățile existente. Pentru a menține setul de capacități la o dimensiune gestionabilă, ultima opțiune este preferabilă, cu excepția cazului în care există motive imperioase pentru a alege prima opțiune; (există și o limită tehnică: dimensiunea seturilor de capacități este limitată în prezent la 64 de biți).

•   Pentru a determina ce capacitate existentă ar putea fi cel mai bine asociată cu noua caracteristică, revizuiți lista de capacități de mai sus pentru a găsi un „silo” (un grup) în care noua caracteristică se încadrează cel mai bine. O abordare de urmat este de a determina dacă există alte caracteristici care necesită capacități care vor fi întotdeauna utilizate împreună cu noua caracteristică. Dacă noua caracteristică este inutilă fără aceste alte caracteristici, ar trebui să utilizați aceeași capacitate ca și celelalte caracteristici.

•   Nu alegeți capacitatea CAP_SYS_ADMIN dacă o puteți evita! O mare parte din verificările de capacitate existente sunt asociate cu această capacitate (a se vedea lista parțială de mai sus). Aceasta poate fi numită în mod plauzibil „noua rădăcină”, deoarece, pe de o parte, conferă o gamă largă de puteri, iar pe de altă parte, domeniul său larg de aplicare înseamnă că aceasta este capacitatea care este necesară pentru multe programe privilegiate. Nu înrăutățiți problema. Singurele caracteristici noi care ar trebui asociate cu CAP_SYS_ADMIN sunt cele care aproape corespund utilizărilor existente în acel „silo” (grup).

•   Dacă ați stabilit că este cu adevărat necesar să creați o nouă capacitate pentru caracteristica dvs., nu o creați sau numiți-o ca fiind o capacitate „de unică folosință”. Astfel, de exemplu, adăugarea caracteristicii foarte specifice CAP_SYS_PACCT a fost probabil o greșeală. În schimb, încercați să identificați și să denumiți noua dvs. capacitate ca un „silo” (grup) mai larg în care s-ar putea încadra alte cazuri de utilizare viitoare conexe.

  Seturi de capacități pentru fire
Fiecare fir are următoarele seturi de capacități care conțin zero sau mai multe dintre capacitățile de mai sus:

Permitted (permis)
    Acesta este un superset limitativ pentru capacitățile efective pe care firul le poate prelua. Este, de asemenea, un superset limitativ pentru capacitățile care pot fi adăugate la setul moștenit de un fir care nu are capacitatea CAP_SETPCAP în setul său efectiv.

    În cazul în care un fir de execuție renunță la o capacitate din setul său permis, acesta nu o poate redobândi niciodată (cu excepția cazului în care execve(2)s fie un program set-user-ID-root, fie un program ale cărui capacități de fișier asociate acordă această capacitate).

Inheritable (moștenibil)
    Acesta este un set de capacități păstrate de-a lungul unui execve(2). Capacitățile moștenite rămân moștenite atunci când se execută orice program, iar capacitățile moștenite sunt adăugate la setul permis atunci când se execută un program care are biții corespunzători activați în setul moștenit al fișierului.

    Deoarece capacitățile moștenite nu sunt, în general, păstrate în execve(2) atunci când se rulează ca utilizator non-root, aplicațiile care doresc să ruleze programe ajutătoare cu capacități ridicate ar trebui să ia în considerare utilizarea capacităților ambientale, descrise mai jos.

Effective (efectiv)
    Acesta este setul de capacități utilizate de nucleu pentru a efectua verificări ale permisiunilor pentru fir.

Bounding (limitare) (per-fir începând cu Linux 2.6.25)
    Setul de limitare a capacităților este un mecanism care poate fi utilizat pentru a limita capacitățile care sunt obținute în timpul execve(2).

    Începând cu Linux 2.6.25, acesta este un set de capacități pentru fiecare fir. În nucleele mai vechi, setul de limitare a capacităților era un atribut la nivel de sistem partajat de toate firele din sistem.

    Pentru mai multe detalii, a se vedea mai jos secțiunea Setul de limitare a capacităților.

Ambient (ambiental) (începând cu Linux 4.3)
    Acesta este un set de capacități care sunt păstrate pe parcursul unei execve(2) a unui program care nu este privilegiat. Setul de capacități ambientale respectă invariantul conform căruia nicio capacitate nu poate fi ambientală dacă nu este permisă și moștenită.

    Setul de capacități ambientale poate fi modificat direct utilizând prctl(2). Capacitățile ambientale sunt reduse automat dacă oricare dintre capacitățile permise sau moștenite corespunzătoare este redusă.

    Executarea unui program care modifică UID-ul sau GID-ul datorită biților set-user-ID sau set-group-ID sau execuția unui program care are orice capacitate de fișier activată va șterge setul ambiental. Capacitățile ambientale sunt adăugate la setul permis și atribuite setului efectiv atunci când este apelat execve(2). Dacă capacitățile ambientale determină creșterea capacităților permise și efective ale unui proces în timpul unui apel execve(2), acest lucru nu declanșează modul de execuție securizat descris în ld.so(8).

Un copil creat prin fork(2) moștenește copii ale seturilor de capacități ale părintelui său. Pentru detalii privind modul în care execve(2) afectează capacitățile, consultați secțiunea Transformarea capacităților în timpul execve() de mai jos.

Folosind capset(2), un fir își poate manipula propriile seturi de capacități; a se vedea mai jos secțiunea Ajustarea programatică a seturilor de capacități.

Începând cu Linux 3.2, fișierul /proc/sys/kernel/cap_last_cap expune valoarea numerică a celei mai înalte capacități acceptate de nucleul care rulează; aceasta poate fi utilizată pentru a determina cel mai înalt bit care poate fi activat într-un set de capacități.

  Capacități de fișier
Începând cu Linux 2.6.24, nucleul acceptă asocierea seturilor de capacități cu un fișier executabil utilizând setcap(8). Seturile de capacități ale fișierului sunt stocate într-un atribut extins (a se vedea setxattr(2) și xattr(7)) numit security.capability. Seturile de capacități ale fișierului, împreună cu seturile de capacități ale firului, determină capacitățile unui fir după un execve(2).

Cele trei seturi de capacități de fișier sunt:

Permitted (cunoscut anterior ca forced (forțat)):
    Aceste capacități sunt permise automat firului, indiferent de capacitățile moștenite ale firului.

Inheritable (cunoscut anterior ca allowed (permis)):
    Acest set este combinat printr-un ȘI logic cu setul moștenit al firului pentru a determina ce capacități moștenite sunt activate în setul permis al firului după execve(2).

Effective:
    Acesta nu este un set, ci mai degrabă un singur bit. Dacă acest bit este activat, atunci în timpul unui execve(2) toate noile capacități permise pentru firul de execuție sunt, de asemenea, adăugate în setul efectiv. Dacă acest bit nu este activat, atunci după un execve(2), niciuna dintre noile capacități permise nu se află în noul set efectiv.

    Activarea bitului de capacitate efectivă a fișierului implică faptul că orice capacitate permisă sau moștenită a fișierului care determină un fir de execuție să dobândească capacitatea permisă corespunzătoare în timpul unui execve(2) (a se vedea secțiunea Transformarea capacităților în timpul execve() de mai jos) va dobândi și capacitatea respectivă în setul său efectiv. Prin urmare, atunci când se atribuie capacități unui fișier (setcap(8), cap_set_file(3), cap_set_fd(3)), dacă se specifică faptul că fanionul efectiv este activat pentru orice capacitate, atunci fanionul efectiv trebuie, de asemenea, să fie specificat ca activat pentru toate celelalte capacități pentru care este activat fanionul permis sau moștenit corespunzător.

  Versiunea extinsă a atributelor capacității fișierului
Pentru a permite extensibilitatea, nucleul acceptă o schemă de codare a unui număr de versiune în interiorul atributului extins security.capability care este utilizat pentru implementarea capacităților fișierelor. Aceste numere de versiune sunt interne implementării și nu sunt vizibile direct pentru aplicațiile din spațiul utilizatorului. Până în prezent, sunt acceptate următoarele versiuni:

VFS_CAP_REVISION_1
    Aceasta a fost implementarea originală a capacităților de fișier, care suporta măști pe 32 de biți pentru capacitățile de fișier.

VFS_CAP_REVISION_2 (începând cu Linux 2.6.25)
    Această versiune permite măștile de capacități ale fișierelor care au o dimensiune de 64 de biți și a fost necesară deoarece numărul capacităților acceptate a crescut peste 32. În mod transparent, nucleul continuă să susțină executarea fișierelor care au măști de capacități versiunea 1 pe 32 de biți, dar atunci când adaugă capacități fișierelor care nu aveau anterior capacități sau modifică capacitățile fișierelor existente, utilizează în mod automat schema versiunea 2 (sau posibil schema versiunea 3, după cum se descrie mai jos).

VFS_CAP_REVISION_3 (începând cu Linux 4.14)
    Capacitățile de fișier ale versiunii 3 sunt furnizate pentru a oferi suport capacităților de fișier cu spații de nume (descrise mai jos).

    La fel ca în cazul capacităților fișierelor din versiunea 2, măștile capacităților din versiunea 3 au o dimensiune de 64 de biți. Dar, în plus, ID-ul utilizatorului rădăcină al spațiului de nume este codificat în atributul extins security.capability; (ID-ul de utilizator rădăcină al unui spațiu de nume este valoarea la care ID-ul de utilizator 0 din interiorul acelui spațiu de nume corespunde în spațiul de nume al utilizatorului inițial).

    Capacitățile fișierelor versiunea 3 sunt concepute pentru a coexista cu capacitățile versiunii 2; adică, pe un sistem Linux modern, pot exista unele fișiere cu capacități versiunea 2, în timp ce altele au capacități versiunea 3.

Înainte de Linux 4.14, singurul tip de atribut extins de capacitate de fișier care putea fi atașat unui fișier era un atribut VFS_CAP_REVISION_2. Începând cu Linux 4.14, versiunea atributului extins security.capability care este atașată unui fișier depinde de circumstanțele în care a fost creat atributul.

Începând cu Linux 4.14, un atribut extins security.capability este creat automat ca (sau convertit în) un atribut versiunea 3 (VFS_CAP_REVISION_3) dacă ambele situații de mai jos sunt adevărate:

•   Firul care scrie atributul se află într-un spațiu de nume de utilizator neinițial; (mai precis: firul se află într-un alt spațiu de nume al utilizatorului decât cel din care a fost montat sistemul de fișiere subiacent).

•   Firul are capacitatea CAP_SETFCAP asupra nodului-i al fișierului, ceea ce înseamnă că (a) firul are capacitatea CAP_SETFCAP în propriul său spațiu de nume al utilizatorului; și (b) UID și GID ale nodului-i al fișierului au corespondențe în spațiul de nume al utilizatorului scriitorului.

Când se creează un atribut extins VFS_CAP_REVISION_3 security.capability, ID-ul de utilizator rădăcină al spațiului de nume de utilizator al firului de creare este salvat în atributul extins.

În schimb, crearea sau modificarea unui atribut extins security.capability dintr-un fir privilegiat (CAP_SETFCAP) care se află în spațiul de nume în care a fost montat sistemul de fișiere subiacent (aceasta înseamnă în mod normal spațiul de nume inițial al utilizatorului) are ca rezultat automat crearea unui atribut versiunea 2 (VFS_CAP_REVISION_2).

Rețineți că crearea unui atribut extins security.capability versiunea 3 este automată. Cu alte cuvinte, atunci când o aplicație din spațiul utilizatorului scrie (setxattr(2)) un atribut security.capability în formatul versiunea 2, nucleul va crea automat un atribut versiunea 3 dacă atributul este creat în circumstanțele descrise mai sus. În mod corespunzător, atunci când un atribut security.capability versiunea 3 este recuperat (getxattr(2)) de către un proces care se află într-un spațiu de nume al utilizatorului care a fost creat de ID-ul utilizatorului rădăcină (sau de un descendent al acestui spațiu de nume al utilizatorului), atributul returnat este (automat) simplificat pentru a apărea ca un atribut versiunea 2 (și anume, valoarea returnată are dimensiunea unui atribut versiunea 2 și nu include ID-ul utilizatorului rădăcină). Aceste conversii automate înseamnă că nu sunt necesare modificări ale instrumentelor din spațiul utilizatorului (de exemplu, setcap(1) și getcap(1)) pentru ca aceste instrumente să poată fi utilizate pentru a crea și a extrage atribute security.capability versiunea 3.

Rețineți că un fișier poate avea asociat un atribut extins security.capability versiunea 2 sau versiunea 3, dar nu ambele: crearea sau modificarea atributului extins security.capability va modifica automat versiunea în funcție de circumstanțele în care atributul extins este creat sau modificat.

  Transformarea capacităților în timpul execve()
În timpul unui execve(2), nucleul calculează noile capacități ale procesului utilizând următorul algoritm:

    P'(ambient)     = (fișierul este privilegiat) ? 0 : P(ambient)

    P'(permitted)   = (P(inheritable) & F(inheritable)) |
                      (F(permitted) & P(bounding)) | P'(ambient)

    P'(effective)   = F(effective) ? P'(permitted) : P'(ambient)

    P'(inheritable) = P(inheritable)    [adică neschimbată]

    P'(bounding)    = P(bounding)       [adică neschimbată]

unde:

    P() indică valoarea capacității unui fir de execuție stabilită înainte de execve(2)

    P'()
        indică valoarea capacității unui fir de execuție stabilită după execve(2)

    F() indică un set de capacități de fișier

Rețineți următoarele detalii referitoare la regulile de transformare a capacităților de mai sus:

•   Setul de capacități ambientale este prezent doar începând cu Linux 4.3. Atunci când se determină transformarea setului ambiental în timpul execve(2), un fișier privilegiat este unul care are capacități sau are bitul set-user-ID sau set-group-ID activat.

•   Înainte de Linux 2.6.25, setul de limitare era un atribut la nivel de sistem partajat de toate firele. Această valoare la nivel de sistem era utilizată pentru a calcula noul set permis în timpul execve(2) în același mod ca cel prezentat mai sus pentru P(bounding).

Notă: în timpul tranzițiilor de capacitate descrise mai sus, capacitățile de fișier pot fi ignorate (tratate ca fiind goale) din aceleași motive pentru care sunt ignorați biții set-user-ID și set-group-ID; a se vedea execve(2). Capacitățile de fișier sunt ignorate în mod similar dacă nucleul a fost inițiat cu opțiunea no_file_caps.

Notă: în conformitate cu regulile de mai sus, dacă un proces cu ID-uri de utilizator diferite de zero execută un execve(2), toate capacitățile care sunt prezente în seturile sale permise și efective vor fi șterse. Pentru tratamentul capacităților atunci când un proces cu un ID utilizator zero efectuează un execve(2), a se vedea secțiunea Capacități și executarea de programe de către root de mai jos.

  Verificarea siguranței pentru binarele cu capacități reduse
Un binar „capability-dumb” este o aplicație care a fost marcată pentru a avea capacități de fișier, dar care nu a fost convertită pentru a utiliza API-ul libcap(3) pentru a-și manipula capacitățile (cu alte cuvinte, acesta este un program tradițional set-user-ID-root care a fost schimbat pentru a utiliza capacitățile fișierului, dar al cărui cod nu a fost modificat pentru a înțelege capacitățile). Pentru astfel de aplicații, bitul de capacitate efectivă este definit pe fișier, astfel încât capacitățile permise ale fișierului sunt activate automat în setul efectiv al procesului atunci când se execută fișierul. Nucleul recunoaște un fișier al cărui bit de capacitate efectivă este definit ca fiind „capability-dumb” în scopul verificării descrise aici.

Atunci când se execută un binar „capability-dumb”, nucleul verifică dacă procesul a obținut toate capacitățile permise care au fost specificate în setul permis al fișierului, după ce au fost efectuate transformările de capacități descrise mai sus; (motivul tipic pentru care acest lucru ar putea să nu se întâmple este că setul de limitare a capacităților a mascat unele dintre capacitățile din setul permis al fișierului). În cazul în care procesul nu a obținut setul complet de capacități permise ale fișierului, atunci execve(2) eșuează cu eroarea EPERM. Acest lucru previne posibilele riscuri de securitate care ar putea apărea atunci când o aplicație cu capacități insuficiente este executată cu mai puține privilegii decât are nevoie. Rețineți că, prin definiție, aplicația însăși nu ar putea recunoaște această problemă, deoarece nu utilizează API-ul libcap(3).

  Capacități și executarea de programe de către root
Pentru a reflecta semantica tradițională UNIX, nucleul efectuează un tratament special al capacităților fișierelor atunci când un proces cu UID 0 (root) execută un program și atunci când este executat un program set-user-ID-root.

După efectuarea oricăror modificări ale ID-ului efectiv al procesului care au fost declanșate de bitul de mod set-user-ID al binarului - de exemplu, schimbarea ID-ului efectiv al utilizatorului la 0 (root) deoarece a fost executat un program set-user-ID-root - nucleul calculează seturile de capacități ale fișierelor după cum urmează:

(1) Dacă ID-ul de utilizator real sau efectiv al procesului este 0 (root), atunci seturile de fișiere moștenite și permise sunt ignorate; în schimb, acestea sunt considerate în mod teoretic ca fiind toate unu (adică toate capacitățile activate). Există o excepție de la acest comportament, descrisă în secțiunea Programele set-user-ID-root care au capacități de fișier de mai jos.

(2) Dacă ID-ul de utilizator efectiv al procesului este 0 (root) sau bitul efectiv al fișierului este de fapt activat, atunci bitul efectiv al fișierului este definit noțional ca fiind unu (activat).

Aceste valori noționale pentru seturile de capacități ale fișierului sunt apoi utilizate conform descrierii de mai sus pentru a calcula transformarea capacităților procesului în timpul execve(2).

Astfel, atunci când un proces cu UID-uri diferite de zero apelează execve(2) pe un program set-user-ID-root care nu are capacități atașate, sau atunci când un proces ale cărui UID-uri reale și efective sunt zero apelează execve(2) pe un program, calculul noilor capacități permise ale procesului se simplifică la:

    P'(permitted)   = P(inheritable) | P(bounding)

    P'(effective)   = P'(permitted)

În consecință, procesul obține toate capacitățile din seturile sale de capacități permise și efective, cu excepția celor mascate de setul de limitare a capacităților; (în calculul lui P'(permitted), termenul P'(ambient) poate fi simplificat, deoarece este prin definiție un subset propriu al lui P(inheritable)).

Tratamentele speciale ale ID-ului de utilizator 0 (root) descrise în această subsecțiune pot fi dezactivate utilizând mecanismul „securebits” descris mai jos.

  Programele set-user-ID-root care au capacități de fișier
Există o excepție de la comportamentul descris la punctul Capacități și executarea de programe de către root de mai sus. Dacă (a) binarul care este executat are atașate capacități și (b) ID-ul de utilizator real al procesului nu este 0 (root) și (c) ID-ul de utilizator efectiv al procesului este este 0 (root), atunci biții de capacitate ai fișierului sunt onorați (adică nu sunt considerați teoretic ca fiind toți unu). Modul obișnuit în care poate apărea această situație este atunci când se execută un program set-UID-root care are, de asemenea, capacități de fișier. Atunci când se execută un astfel de program, procesul obține doar capacitățile acordate de program (și anume, nu toate capacitățile, așa cum s-ar întâmpla în cazul executării unui program set-user-ID-root care nu are asociate capacități de fișier).

Rețineți că se pot atribui seturi de capacități goale unui fișier de program și, astfel, este posibil să se creeze un program set-user-ID-root care modifică set-user-ID-ul efectiv și salvat al procesului care execută programul la 0, dar nu conferă nicio capacitate procesului respectiv.

  Setul de limitare a capacităților
Setul de limitare a capacităților este un mecanism de securitate care poate fi utilizat pentru a limita capacitățile care pot fi obținute în timpul unei execve(2). Setul de limitare este utilizat în următoarele moduri:

•   În timpul unei operații execve(2), setul de limitare a capacităților este combinat cu ȘI logic cu setul de capacități permise ale fișierului, iar rezultatul acestei operații este atribuit setului de capacități permise ale firului. Setul de limitare a capacităților impune astfel o limită asupra capacităților permise care pot fi acordate de un fișier executabil.

•   (Începând cu Linux 2.6.25) Setul de limitare a capacităților acționează ca un superset limitativ pentru capacitățile pe care un fir le poate adăuga la setul său moștenit utilizând capset(2). Aceasta înseamnă că, dacă o capacitate nu se află în setul limitativ, atunci un fir de execuție nu poate adăuga această capacitate la setul său moștenit, chiar dacă se afla în capacitățile sale permise, și, prin urmare, nu poate păstra această capacitate în setul său permis atunci când se apelează execve(2) pe un fișier care are capacitatea în setul său moștenit.

Rețineți că setul delimitator maschează capacitățile permise ale fișierului, dar nu și capacitățile moștenite. În cazul în care un fir de execuție menține o capacitate în setul său moștenit care nu se află în setul său limitativ, atunci acesta poate obține în continuare acea capacitate în setul său permis prin executarea unui fișier care are capacitatea respectivă în setul său moștenit.

În funcție de versiunea nucleului, setul de limitare a capacității este fie un atribut la nivel de sistem, fie un atribut per proces.

Setul de limitare a capacităților de la Linux 2.6.25 încoace

Începând cu Linux 2.6.25, setul de limitare a capacităților este un atribut per-fir; (setul de delimitare a capacităților la nivelul întregului sistem descris mai jos nu mai există).

Setul de limitare este moștenit la fork(2) de la părintele firului și este păstrat pe parcursul unui execve(2).

Un fir de execuție poate elimina capacități din setul său de limitare a capacităților utilizând operația prctl(2) PR_CAPBSET_DROP, cu condiția să aibă capacitatea CAP_SETPCAP. Odată ce o capacitate a fost eliminată din setul limitator, aceasta nu mai poate fi readusă în acel set. Un fir de execuție poate determina dacă o capacitate se află în setul său limitator utilizând operația prctl(2) PR_CAPBSET_READ.

Eliminarea capacităților din setul de limitare este acceptată numai dacă capacitățile de fișier sunt compilate în nucleu. Înainte de Linux 2.6.33, capacitățile de fișier erau o caracteristică opțională configurabilă prin opțiunea CONFIG_SECURITY_FILE_CAPABILITIES. Începând cu Linux 2.6.33, opțiunea de configurare a fost eliminată, iar capacitățile de fișier fac întotdeauna parte din nucleu. Atunci când capacitățile de fișier sunt compilate în nucleu, procesul init (strămoșul tuturor proceselor) începe cu un set de limitare complet. În cazul în care capacitățile de fișier nu sunt compilate în nucleu, atunci init începe cu un set de limitare complet minus CAP_SETPCAP, deoarece această capacitate are o semnificație diferită atunci când nu există capacități de fișier.

Eliminarea unei capacități din setul limitator nu o elimină din setul moștenit al firului. Cu toate acestea, împiedică adăugarea în viitor a capacității înapoi în setul moștenit al firului.

Setul de limitare a capacităților înainte de Linux 2.6.25

Înainte de Linux 2.6.25, setul de limitare a capacităților este un atribut la nivel de sistem care afectează toate firele din sistem. Setul de limitare este accesibil prin intermediul fișierului /proc/sys/kernel/cap-bound; (în mod confuz, acest parametru al măștii de biți este exprimat ca număr zecimal cu semn în /proc/sys/kernel/cap-bound).

Numai procesul init poate stabili capacități în setul de limitare a capacităților; în afară de acesta, superutilizatorul (mai precis: un proces cu capacitatea CAP_SYS_MODULE) poate doar șterge capacități din acest set.

Într-un sistem standard, setul de limitare a capacităților maschează întotdeauna capacitatea CAP_SETPCAP. Pentru a elimina această restricție (periculos!), modificați definiția lui CAP_INIT_EFF_SET în include/linux/capability.h și reconstruiți nucleul.

În Linux 2.2.11 a fost adăugată funcția de set de limitare a capacităților la nivel de sistem.

  Efectul modificărilor ID-ului utilizatorului asupra capacităților
Pentru a păstra semantica tradițională pentru tranzițiile între ID-uri de utilizator 0 și diferite de zero, nucleul efectuează următoarele modificări ale seturilor de capacități ale unui fir de execuție la modificările ID-urilor de utilizator reale, efective, salvate și ale sistemului de fișiere ale firului de execuție (utilizând setuid(2), setresuid(2) sau similar):

•   În cazul în care unul sau mai multe dintre ID-urile de utilizator ale setului real, efectiv sau salvat au fost anterior 0 și, ca urmare a modificărilor UID, toate aceste ID-uri au o valoare diferită de zero, atunci toate capacitățile sunt șterse din seturile de capacități permise, efective și ambientale.

•   Dacă ID-ul efectiv al utilizatorului este schimbat de la 0 la diferit de zero, atunci toate capacitățile sunt șterse din setul efectiv.

•   Dacă ID-ul utilizatorului efectiv este schimbat de la diferit de zero la 0, atunci setul permis este copiat în setul efectiv.

•   Dacă ID-ul utilizatorului sistemului de fișiere este schimbat de la 0 la diferit de zero (a se vedea setfsuid(2)), următoarele capacități sunt șterse din setul efectiv: CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_LINUX_IMMUTABLE (începând cu Linux 2.6.30), CAP_MAC_OVERRIDE și CAP_MKNOD (începând cu Linux 2.6.30). Dacă UID-ul sistemului de fișiere este schimbat de la diferit de zero la 0, atunci oricare dintre aceste capacități care sunt activate în setul permis sunt activate în setul efectiv.

Dacă un fir care are o valoare 0 pentru unul sau mai multe dintre ID-urile sale de utilizator dorește să împiedice ștergerea setului său de capacități permise atunci când își restabilește toate ID-urile de utilizator la valori diferite de zero, acesta poate face acest lucru utilizând fanionul „securebits” SECBIT_KEEP_CAPS descris mai jos.

  Ajustarea programatică a seturilor de capacități
Un fir de execuție își poate recupera și modifica seturile de capacități permise, efective și moștenite utilizând apelurile de sistem capget(2) și capset(2). Cu toate acestea, în acest scop este preferată utilizarea apelurilor cap_get_proc(3) și cap_set_proc(3), ambele furnizate în pachetul libcap. Următoarele reguli guvernează modificările aduse seturilor de capacități ale firelor de execuție:

•   Dacă apelantul nu are capacitatea CAP_SETPCAP, noul set moștenit trebuie să fie un subset al combinației dintre seturile moștenite și permise existente.

•   (De la Linux 2.6.25) Noul set moștenit trebuie să fie un subset al combinației dintre setul moștenit existent și setul de limitare a capacităților.

•   Noul set permis trebuie să fie un subset al setului permis existent (de exemplu, nu este posibil să se dobândească capacități permise pe care firul nu le are în prezent).

•   Noul set efectiv trebuie să fie un subset al noului set permis.

  Fanioanele „securebits”: stabilirea unui mediu exclusiv pentru capacități
Începând cu Linux 2.6.26, și cu un nucleu în care sunt activate capacitățile de fișier, Linux implementează un set de fanioane securebits per-fir care pot fi utilizate pentru a dezactiva gestionarea specială a capacităților pentru UID 0 (root). Aceste fanioane sunt după cum urmează:

SECBIT_KEEP_CAPS
    Definirea acestui fanion permite unui fir care are unul sau mai multe UID-uri 0 să păstreze capacitățile din setul său permis atunci când își schimbă toate UID-urile la valori diferite de zero. Dacă acest fanion nu este definit, atunci o astfel de schimbare de UID face ca firul să piardă toate capacitățile permise. Acest fanion este întotdeauna eliminat în cazul unui apel execve(2).

    Rețineți că, chiar dacă fanionul SECBIT_KEEP_CAPS este activat, capacitățile efective ale unui fir sunt șterse atunci când acesta își schimbă UID-ul efectiv la o valoare diferită de zero. Cu toate acestea, dacă firul de execuție a activat acest fanion și UID-ul său efectiv este deja diferit de zero, iar firul de execuție trece ulterior toate celelalte UID-uri la valori diferite de zero, capacitățile efective nu vor fi șterse.

    Activarea fanionului SECBIT_KEEP_CAPS este ignorată dacă este activat fanionul SECBIT_NO_SETUID_FIXUP; (cel din urmă fanion oferă un superset al efectului primului fanion).

    Acest fanion oferă aceeași funcționalitate ca și vechea operație prctl(2) PR_SET_KEEPCAPS.

SECBIT_NO_SETUID_FIXUP
    Activarea acestui fanion împiedică nucleul să ajusteze seturile de capacități permise, efective și ambientale ale procesului atunci când UID-urile efective și de sistem de fișiere ale firului sunt schimbate între valori zero și diferite de zero. Consultați Efectul modificărilor ID-ului utilizatorului asupra capacităților de mai sus.

SECBIT_NOROOT
    Dacă acest bit este activat, atunci nucleul nu acordă capacități atunci când este executat un program set-user-ID-root sau când un proces cu un UID efectiv sau real de 0 apelează execve(2); (a se vedea secțiunea Capacități și executarea de programe de către root de mai sus).

SECBIT_NO_CAP_AMBIENT_RAISE
    Activarea acestui fanion nu permite creșterea capacităților ambientale prin operația prctl(2) PR_CAP_AMBIENT_RAISE.

Fiecare dintre fanioanele „de bază” de mai sus are un fanion „blocat” însoțitor. Activarea oricărui fanion „blocat” este ireversibilă și are ca efect împiedicarea modificărilor ulterioare ale fanionului „de bază” corespunzător. Indicatoarele blocate sunt: SECBIT_KEEP_CAPS_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED, SECBIT_NOROOT_LOCKED și SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED.

Fanioanele securebits pot fi modificate și recuperate utilizând operațiile prctl(2) PR_SET_SECUREBITS și PR_GET_SECUREBITS. Capacitatea CAP_SETPCAP este necesară pentru modificarea fanioanelor. Rețineți că constantele SECBIT_* sunt disponibile numai după includerea fișierului antet <linux/securebits.h>.

Fanioanele securebits sunt moștenite de procesele copii. În timpul unui execve(2), toate fanioanele sunt păstrate, cu excepția SECBIT_KEEP_CAPS care este întotdeauna șters.

O aplicație poate utiliza următorul apel pentru a se bloca, împreună cu toți descendenții săi, într-un mediu în care singura modalitate de a obține capacități este prin executarea unui program cu capacități de fișier asociate:

    prctl(PR_SET_SECUREBITS,
            /* SECBIT_KEEP_CAPS off */
            SECBIT_KEEP_CAPS_LOCKED |
            SECBIT_NO_SETUID_FIXUP |
            SECBIT_NO_SETUID_FIXUP_LOCKED |
            SECBIT_NOROOT |
            SECBIT_NOROOT_LOCKED);
            /* Definirea/blocarea SECBIT_NO_CAP_AMBIENT_RAISE
               nu este necesară */

  Programele "set-user-ID-root" per spațiu de nume de utilizator
Un program set-user-ID al cărui UID se potrivește cu UID-ul care a creat un spațiu de nume de utilizator va conferi capacități în seturile permise și efective ale procesului atunci când este executat de orice proces din interiorul acelui spațiu de nume sau al oricărui spațiu de nume de utilizator descendent.

Regulile privind transformarea capacităților procesului în timpul execve(2) sunt exact cele descrise în Transformarea capacităților în timpul execve() și Capacitățile și executarea de programe de către root de mai sus, cu diferența că, în ultima subsecțiune, „root” este UID-ul creatorului spațiului de nume al utilizatorului.

  Capacități de fișiere plasate în spații de nume
Capacitățile de fișier tradiționale (adică versiunea 2) asociază doar un set de măști de capacități cu un fișier binar executabil. Atunci când un proces execută un fișier binar cu astfel de capacități, acesta obține capacitățile asociate (în cadrul spațiului său de nume de utilizator) conform regulilor descrise la punctul Transformarea capacităților în timpul execve() de mai sus.

Deoarece capacitățile de fișier ale versiunii 2 conferă capacități procesului executant indiferent de spațiul de nume al utilizatorului în care acesta se află, numai procesele privilegiate sunt autorizate să asocieze capacități cu un fișier. Aici, „privilegiat” înseamnă un proces care are capacitatea CAP_SETFCAP în spațiul de nume al utilizatorului în care a fost montat sistemul de fișiere (în mod normal, spațiul de nume al utilizatorului inițial). Această limitare face ca capacitățile fișierelor să fie inutile pentru anumite cazuri de utilizare. De exemplu, în containerele cu spațiu de nume de utilizator, poate fi de dorit să se poată crea un binar care să confere capacități numai proceselor executate în interiorul containerului respectiv, dar nu și proceselor care sunt executate în afara containerului.

Linux 4.14 a adăugat așa-numitele capacități de fișier cu spații de nume pentru a oferi suport pentru astfel de cazuri de utilizare. Capacitățile de fișier cu spații de nume sunt înregistrate ca atribute extinse security.capability versiunea 3 (adică, VFS_CAP_REVISION_3). Un astfel de atribut este creat automat în circumstanțele descrise la Versiunea extinsă a atributelor capacității fișierului de mai sus. Atunci când este creat un atribut extins security.capability versiunea 3, nucleul înregistrează nu numai măștile de capacitate în atributul extins, ci și ID-ul utilizatorului rădăcină al spațiului de nume.

Ca și în cazul unui binar care are capacități de fișier VFS_CAP_REVISION_2, un binar cu capacități de fișier VFS_CAP_REVISION_3 conferă capacități unui proces în timpul execve(). Cu toate acestea, capacitățile sunt conferite numai dacă binarul este executat de un proces care se află într-un spațiu de nume al utilizatorului al cărui UID 0 corespunde ID-ului utilizatorului root care este salvat în atributul extins sau atunci când este executat de un proces care se află într-un descendent al unui astfel de spațiu de nume.

  Interacțiunea cu spațiile de nume ale utilizatorilor
Pentru informații suplimentare privind interacțiunea dintre capacități și spațiile de nume ale utilizatorilor, consultați user_namespaces(7).

STANDARDE
Nu există standarde care să reglementeze capacitățile, dar implementarea capacităților Linux se bazează pe proiectul de standard POSIX.1e retras https://archive.org:/details/posix_1003.1e-990310.

NOTE
Atunci când încercați să strace(1) binarii care au capacități (sau binarii set-user-ID-root), este posibil să găsiți utilă opțiunea -u <username>. Ceva precum:

    $ sudo strace -o trace.log -u ceci ./prog_meu_privat

De la Linux 2.5.27 la Linux 2.6.26, capacitățile erau o componentă opțională a nucleului și puteau fi activate/dezactivate prin opțiunea de configurare a nucleului CONFIG_SECURITY_CAPABILITIES.

Fișierul /proc/pid/task/TID/status poate fi utilizat pentru a vizualiza seturile de capacități ale unui fir. Fișierul /proc/pid/status arată seturile de capacități ale firului principal al unui proces. Înainte de Linux 3.8, capacitățile inexistente erau afișate ca fiind activate (1) în aceste seturi. Începând cu Linux 3.8, toate capacitățile inexistente (peste CAP_LAST_CAP) sunt afișate ca fiind dezactivate (0).

Pachetul libcap oferă o suită de rutine pentru definirea și obținerea capacităților care este mai confortabilă și mai puțin susceptibilă de schimbare decât interfața oferită de capset(2) și capget(2). Acest pachet furnizează și programele setcap(8) și getcap(8). Acesta poate fi găsit la adresa
https://git.kernel.org/pub/scm/libs/libcap/libcap.git/refs/.

Înainte de Linux 2.6.24 și de la Linux 2.6.24 la Linux 2.6.32, dacă capacitățile de fișier nu sunt activate, un fir cu capacitatea CAP_SETPCAP poate manipula capacitățile altor fire decât el. Cu toate acestea, acest lucru este posibil doar teoretic, deoarece niciun fir nu are CAP_SETPCAP în niciunul dintre aceste cazuri:

•   În implementarea anterioară versiunii 2.6.25, setul de limitare a capacităților la nivel de sistem, /proc/sys/kernel/cap-bound, maschează întotdeauna capacitatea CAP_SETPCAP, iar acest lucru nu poate fi schimbat fără modificarea sursei nucleului și reconstruirea nucleului.

•   În cazul în care capacitățile de fișier sunt dezactivate (de exemplu, opțiunea CONFIG_SECURITY_FILE_CAPABILITIES a nucleului este dezactivată), atunci init începe cu capacitatea CAP_SETPCAP eliminată din setul său de limitare per-proces, iar acest set de limitare este moștenit de toate celelalte procese create în sistem.

CONSULTAȚI ȘI
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 în arborele sursă al nucleului Linux

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.