Provided by: manpages-ro_4.27.0-1_all bug

NUME

       pkeys - prezentare generală a cheilor de protecție a memoriei

DESCRIERE

       Cheile  de  protecție  a  memoriei (pkeys) sunt o extensie a permisiunilor de memorie existente bazate pe
       pagini. Permisiunile normale de pagini care utilizează  tabele  de  pagini  necesită  apeluri  de  sistem
       costisitoare  și  invalidări  ale TLB (Translation Lookaside Buffer) atunci când se schimbă permisiunile.
       Cheile de protecție a memoriei oferă un mecanism de modificare a protecțiilor fără a necesita modificarea
       tabelelor de pagini la fiecare modificare a permisiunilor.

       Pentru a utiliza pkeys, software-ul trebuie mai întâi să „eticheteze” o pagină din tabelele de pagini  cu
       o  cheie de protecție „pkey”. După ce această etichetă este plasată, o aplicație trebuie doar să modifice
       conținutul unui registru pentru a elimina accesul la scriere sau tot accesul la o pagină etichetată.

       Cheile de protecție funcționează împreună cu permisiunile existente PROT_READ,  PROT_WRITE  și  PROT_EXEC
       transmise  apelurilor  de  sistem,  cum ar fi mprotect(2) și mmap(2), dar acționează întotdeauna pentru a
       restricționa și mai mult aceste mecanisme tradiționale de permisiune.

       În cazul în care un proces efectuează un acces care  încalcă  restricțiile  cheii  de  protecție,  acesta
       primește  un  semnal  SIGSEGV. A se vedea sigaction(2) pentru detalii privind informațiile disponibile cu
       acest semnal.

       Pentru a utiliza caracteristica pkeys, procesorul trebuie să o accepte, iar nucleul  trebuie  să  conțină
       suport  pentru  această  caracteristică pe un anumit procesor. De la începutul anului 2016 sunt acceptate
       doar viitoarele procesoare Intel x86, iar acest hardware suportă 16 chei de protecție în fiecare  proces.
       Cu toate acestea, „pkey 0” este utilizată drept cheie implicită, astfel încât sunt disponibile maximum 15
       pentru  utilizarea  efectivă  a  aplicațiilor. Cheia implicită este atribuită oricărei regiuni de memorie
       pentru care nu a fost atribuită în mod explicit o cheie de protecție prin pkey_mprotect(2).

       Cheile de protecție au potențialul de a adăuga un nivel de securitate și fiabilitate  la  aplicații.  Dar
       ele  nu  au  fost  concepute  în primul rând ca o caracteristică de securitate. De exemplu, WRPKRU este o
       instrucțiune complet neprivilegiată, astfel încât cheile de protecție sunt inutile în orice caz  în  care
       un atacator controlează registrul PKRU sau poate executa instrucțiuni arbitrare.

       Aplicațiile  trebuie  să fie foarte atente pentru a se asigura că nu „li se scurg” cheile de protecție.De
       exemplu, înainte de a apela pkey_free(2), aplicația ar trebui să se asigure că nu  există  nicio  memorie
       care să aibă atribuită acea cheie de protecție „pkey”. În cazul în care aplicația a lăsat atribuită cheia
       de  protecție  eliberată, un viitor utilizator al acelei chei de protecție ar putea modifica din greșeală
       permisiunile unei structuri de date nerelaționată, ceea ce ar putea avea un impact asupra securității sau
       stabilității. În prezent, nucleul permite ca pkey_free(2) să fie apelat pentru cheile  de  acces  în  uz,
       deoarece efectuarea verificărilor suplimentare necesare pentru a interzice acest lucru ar avea implicații
       asupra  performanței  procesorului  sau  a  memoriei. Implementarea verificărilor necesare este lăsată la
       latitudinea aplicațiilor. Aplicațiile pot pune în aplicare aceste verificări prin  căutarea  în  fișierul
       /proc/pid/smaps a regiunilor de memorie cărora le-a fost atribuită cheia „pkey”. Mai multe detalii pot fi
       găsite în proc(5).

       Orice  aplicație  care  dorește  să  utilizeze chei de protecție trebuie să poată funcționa fără acestea.
       Acestea ar putea fi indisponibile deoarece hardware-ul pe care rulează aplicația  nu  le  acceptă,  codul
       nucleului  nu  conține  suport,  suportul  nucleului  a fost dezactivat sau deoarece toate cheile au fost
       alocate, poate de către o bibliotecă pe care o utilizează aplicația. Se  recomandă  ca  aplicațiile  care
       doresc  să  utilizeze  chei de protecție să apeleze pur și simplu pkey_alloc(2) și să testeze dacă apelul
       reușește, în loc să încerce să detecteze suportul pentru această caracteristică în orice alt mod.

       Deși nu este necesar, suportul hardware pentru cheile de protecție poate  fi  enumerat  cu  instrucțiunea
       cpuid.  Detalii  despre  cum  se  face  acest  lucru pot fi găsite în „Intel Software Developers Manual”.
       Nucleul efectuează această enumerare și expune informațiile în /proc/cpuinfo sub  câmpul  „flags”.  Șirul
       „pku”  din  acest câmp indică suportul hardware pentru chei de protecție, iar șirul „ospke” indică faptul
       că nucleul conține și a activat suportul pentru chei de protecție.

       Aplicațiile care utilizează fire de execuție și chei de protecție trebuie  să  fie  deosebit  de  atente.
       Firele  moștenesc drepturile cheilor de protecție ale părintelui în momentul apelului de sistem clone(2).
       Aplicațiile ar trebui fie să se asigure că propriile permisiuni  sunt  adecvate  pentru  firele-copil  în
       momentul  în  care  se  apelează  clone(2),  fie să se asigure că fiecare fir-copil poate efectua propria
       inițializare a drepturilor cheilor de protecție.

   Comportamentul gestionarului de semnale
       De fiecare dată când este invocat un gestionar de semnal (inclusiv semnalele  imbricate),  firului  i  se
       atribuie  temporar un set nou, implicit, de drepturi de cheie de protecție care înlocuiesc drepturile din
       contextul întrerupt. Acest lucru înseamnă că aplicațiile trebuie să restabilească din nou  drepturile  de
       cheie  de  protecție dorite la intrarea într-un gestionar de semnal dacă drepturile dorite diferă de cele
       implicite. Drepturile oricărui context întrerupt sunt restabilite la returnarea gestionarului de semnal.

       Acest comportament al semnalului este neobișnuit și se datorează faptului că  registrul  x86  PKRU  (care
       stochează  drepturile de acces la cheia de protecție) este gestionat cu același mecanism hardware (XSAVE)
       care gestionează registrele  în  virgulă  mobilă.  Comportamentul  semnalului  este  același  cu  cel  al
       registrelor în virgulă mobilă.

   Apeluri de sistem cu chei de protecție
       Nucleul  Linux implementează următoarele apeluri de sistem legate de chei de protecție: pkey_mprotect(2),
       pkey_alloc(2) și pkey_free(2).

       Apelurile de sistem Linux pentru pkey sunt disponibile numai dacă nucleul a fost configurat și  construit
       cu opțiunea CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS.

EXEMPLE

       Programul de mai jos alocă o pagină de memorie cu permisiuni de citire și scriere. Apoi scrie câteva date
       în  memorie  și  le  citește  cu  succes  înapoi.  După  aceea, încearcă să aloce o cheie de protecție și
       interzice accesul la pagină prin utilizarea instrucțiunii WRPKRU. Apoi încearcă să acceseze pagina,  ceea
       ce ne așteptăm acum să provoace un semnal fatal pentru aplicație.

           $ ./a.out
           memoria tampon conține: 73
           pe cale de a citi din nou memoria tampon...
           Eroare de segmentare (conținutul memoriei a fost descărcat)

   Sursa programului

       #define _GNU_SOURCE
       #include <err.h>
       #include <unistd.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/mman.h>

       int
       main(void)
       {
           int status;
           int pkey;
           int *buffer;

           /*
            * Alocă o pagină de memorie.
            */
           buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
                         MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
           if (buffer == MAP_FAILED)
               err(EXIT_FAILURE, "mmap");

           /*
            * Introduce niște date aleatorii în pagină (întotdeauna în regulă pentru a le accesa).
            */
           *buffer = __LINE__;
           printf("memoria tampon conține: %d\n", *buffer);

           /*
            * Alocă o cheie de protecție:
            */
           pkey = pkey_alloc(0, 0);
           if (pkey == -1)
               err(EXIT_FAILURE, "pkey_alloc");

           /*
            * Dezactivează accesul la orice memorie cu „pkey” stabilită,
            * chiar dacă nu există niciuna în acest moment.
            */
           status = pkey_set(pkey, PKEY_DISABLE_ACCESS);
           if (status)
               err(EXIT_FAILURE, "pkey_set");

           /*
            * Stabilește cheia de protecție pe „memorie tampon”.
            * Rețineți că este în continuare de citire/scriere în ceea ce privește mprotect(),
            * iar precedentul pkey_set() are prioritate față de acesta.
            */
           status = pkey_mprotect(buffer, getpagesize(),
                                  PROT_READ | PROT_WRITE, pkey);
           if (status == -1)
               err(EXIT_FAILURE, "pkey_mprotect");

           printf("pe cale de a citi din nou memoria tampon...\n");

           /*
            * Aceasta se va prăbuși, deoarece am interzis accesul.
            */
           printf("memoria tampon conține: %d\n", *buffer);

           status = pkey_free(pkey);
           if (status == -1)
               err(EXIT_FAILURE, "pkey_free");

           exit(EXIT_SUCCESS);
       }

CONSULTAȚI ȘI

       pkey_alloc(2), pkey_free(2), pkey_mprotect(2), sigaction(2)

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  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.

Pagini de manual de Linux 6.9.1                   15 iunie 2024                                         pkeys(7)