pkeys(7) Miscellaneous Information Manual pkeys(7) NUME pkeys - prezentare generala a cheilor de protecie a memoriei DESCRIERE Cheile de protecie a memoriei (pkeys) sunt o extensie a permisiunilor de memorie existente bazate pe pagini. Permisiunile normale de pagini care utilizeaza tabele de pagini necesita apeluri de sistem costisitoare i invalidari ale TLB (Translation Lookaside Buffer) atunci cand se schimba permisiunile. Cheile de protecie a memoriei ofera un mecanism de modificare a proteciilor fara a necesita modificarea tabelelor de pagini la fiecare modificare a permisiunilor. Pentru a utiliza pkeys, software-ul trebuie mai intai sa ,,eticheteze" o pagina din tabelele de pagini cu o cheie de protecie ,,pkey". Dupa ce aceasta eticheta este plasata, o aplicaie trebuie doar sa modifice coninutul unui registru pentru a elimina accesul la scriere sau tot accesul la o pagina etichetata. Cheile de protecie funcioneaza impreuna cu permisiunile existente PROT_READ, PROT_WRITE i PROT_EXEC transmise apelurilor de sistem, cum ar fi mprotect(2) i mmap(2), dar acioneaza intotdeauna pentru a restriciona i mai mult aceste mecanisme tradiionale de permisiune. In cazul in care un proces efectueaza un acces care incalca restriciile cheii de protecie, acesta primete un semnal SIGSEGV. A se vedea sigaction(2) pentru detalii privind informaiile disponibile cu acest semnal. Pentru a utiliza caracteristica pkeys, procesorul trebuie sa o accepte, iar nucleul trebuie sa conina suport pentru aceasta caracteristica pe un anumit procesor. De la inceputul anului 2016 sunt acceptate doar viitoarele procesoare Intel x86, iar acest hardware suporta 16 chei de protecie in fiecare proces. Cu toate acestea, ,,pkey 0" este utilizata drept cheie implicita, astfel incat sunt disponibile maximum 15 pentru utilizarea efectiva a aplicaiilor. Cheia implicita este atribuita oricarei regiuni de memorie pentru care nu a fost atribuita in mod explicit o cheie de protecie prin pkey_mprotect(2). Cheile de protecie au potenialul de a adauga un nivel de securitate i fiabilitate la aplicaii. Dar ele nu au fost concepute in primul rand ca o caracteristica de securitate. De exemplu, WRPKRU este o instruciune complet neprivilegiata, astfel incat cheile de protecie sunt inutile in orice caz in care un atacator controleaza registrul PKRU sau poate executa instruciuni arbitrare. Aplicaiile trebuie sa fie foarte atente pentru a se asigura ca nu ,,li se scurg" cheile de protecie.De exemplu, inainte de a apela pkey_free(2), aplicaia ar trebui sa se asigure ca nu exista nicio memorie care sa aiba atribuita acea cheie de protecie ,,pkey". In cazul in care aplicaia a lasat atribuita cheia de protecie eliberata, un viitor utilizator al acelei chei de protecie ar putea modifica din greeala permisiunile unei structuri de date nerelaionata, ceea ce ar putea avea un impact asupra securitaii sau stabilitaii. In prezent, nucleul permite ca pkey_free(2) sa fie apelat pentru cheile de acces in uz, deoarece efectuarea verificarilor suplimentare necesare pentru a interzice acest lucru ar avea implicaii asupra performanei procesorului sau a memoriei. Implementarea verificarilor necesare este lasata la latitudinea aplicaiilor. Aplicaiile pot pune in aplicare aceste verificari prin cautarea in fiierul /proc/pid/smaps a regiunilor de memorie carora le-a fost atribuita cheia ,,pkey". Mai multe detalii pot fi gasite in proc(5). Orice aplicaie care dorete sa utilizeze chei de protecie trebuie sa poata funciona fara acestea. Acestea ar putea fi indisponibile deoarece hardware-ul pe care ruleaza aplicaia nu le accepta, codul nucleului nu conine suport, suportul nucleului a fost dezactivat sau deoarece toate cheile au fost alocate, poate de catre o biblioteca pe care o utilizeaza aplicaia. Se recomanda ca aplicaiile care doresc sa utilizeze chei de protecie sa apeleze pur i simplu pkey_alloc(2) i sa testeze daca apelul reuete, in loc sa incerce sa detecteze suportul pentru aceasta caracteristica in orice alt mod. Dei nu este necesar, suportul hardware pentru cheile de protecie poate fi enumerat cu instruciunea cpuid. Detalii despre cum se face acest lucru pot fi gasite in ,,Intel Software Developers Manual". Nucleul efectueaza aceasta enumerare i expune informaiile in /proc/cpuinfo sub campul ,,flags". irul ,,pku" din acest camp indica suportul hardware pentru chei de protecie, iar irul ,,ospke" indica faptul ca nucleul conine i a activat suportul pentru chei de protecie. Aplicaiile care utilizeaza fire de execuie i chei de protecie trebuie sa fie deosebit de atente. Firele motenesc drepturile cheilor de protecie ale parintelui in momentul apelului de sistem clone(2). Aplicaiile ar trebui fie sa se asigure ca propriile permisiuni sunt adecvate pentru firele-copil in momentul in care se apeleaza clone(2), fie sa se asigure ca fiecare fir-copil poate efectua propria iniializare a drepturilor cheilor de protecie. Comportamentul gestionarului de semnale De fiecare data cand este invocat un gestionar de semnal (inclusiv semnalele imbricate), firului i se atribuie temporar un set nou, implicit, de drepturi de cheie de protecie care inlocuiesc drepturile din contextul intrerupt. Acest lucru inseamna ca aplicaiile trebuie sa restabileasca din nou drepturile de cheie de protecie dorite la intrarea intr-un gestionar de semnal daca drepturile dorite difera de cele implicite. Drepturile oricarui context intrerupt sunt restabilite la returnarea gestionarului de semnal. Acest comportament al semnalului este neobinuit i se datoreaza faptului ca registrul x86 PKRU (care stocheaza drepturile de acces la cheia de protecie) este gestionat cu acelai mecanism hardware (XSAVE) care gestioneaza registrele in virgula mobila. Comportamentul semnalului este acelai cu cel al registrelor in virgula mobila. Apeluri de sistem cu chei de protecie Nucleul Linux implementeaza urmatoarele apeluri de sistem legate de chei de protecie: pkey_mprotect(2), pkey_alloc(2) i pkey_free(2). Apelurile de sistem Linux pentru pkey sunt disponibile numai daca nucleul a fost configurat i construit cu opiunea CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS. EXEMPLE Programul de mai jos aloca o pagina de memorie cu permisiuni de citire i scriere. Apoi scrie cateva date in memorie i le citete cu succes inapoi. Dupa aceea, incearca sa aloce o cheie de protecie i interzice accesul la pagina prin utilizarea instruciunii WRPKRU. Apoi incearca sa acceseze pagina, ceea ce ne ateptam acum sa provoace un semnal fatal pentru aplicaie. $ ./a.out memoria tampon conine: 73 pe cale de a citi din nou memoria tampon... Eroare de segmentare (coninutul memoriei a fost descarcat) Sursa programului #define _GNU_SOURCE #include #include #include #include #include int main(void) { int status; int pkey; int *buffer; /* * Aloca o pagina 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 nite date aleatorii in pagina (intotdeauna in regula pentru a le accesa). */ *buffer = __LINE__; printf("memoria tampon conine: %d\n", *buffer); /* * Aloca o cheie de protecie: */ pkey = pkey_alloc(0, 0); if (pkey == -1) err(EXIT_FAILURE, "pkey_alloc"); /* * Dezactiveaza accesul la orice memorie cu ,,pkey" stabilita, * chiar daca nu exista niciuna in acest moment. */ status = pkey_set(pkey, PKEY_DISABLE_ACCESS); if (status) err(EXIT_FAILURE, "pkey_set"); /* * Stabilete cheia de protecie pe ,,memorie tampon". * Reinei ca este in continuare de citire/scriere in ceea ce privete mprotect(), * iar precedentul pkey_set() are prioritate faa 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 prabui, deoarece am interzis accesul. */ printf("memoria tampon conine: %d\n", *buffer); status = pkey_free(pkey); if (status == -1) err(EXIT_FAILURE, "pkey_free"); exit(EXIT_SUCCESS); } CONSULTAI I pkey_alloc(2), pkey_free(2), pkey_mprotect(2), sigaction(2) TRADUCERE Traducerea in limba romana a acestui manual a fost facuta de Remus- Gabriel Chelu Aceasta traducere este documentaie gratuita; citii Licena publica generala GNU Versiunea 3 sau o versiune ulterioara cu privire la condiii privind drepturile de autor. NU se asuma NICIO RESPONSABILITATE. Daca gasii erori in traducerea acestui manual, va rugam sa trimitei un e-mail la . Pagini de manual de Linux 6.18 8 februarie 2026 pkeys(7)