Examene și lucrări 2010-2011

Examen restanță

Examen final

Lucrări

Lucrare 1

  • 8 martie, 09:05-09:15, EC004, seria CA
  • 9 martie, 17:05-17:15, EC105, seria CC

3CA, nr. 1

# Dați exemplu de două apeluri care modifică valoarea cursorului de fișier (file pointer). #* Răspuns: # lseek}/fseek}, apeluri al căror rol este de modificare a cursorului de fișier; # read/fread/fgets – la fiecare citire cursorul de fișier este incrementat cu numărul de octeți citiți; # write/fwrite/fputs/fprints – la fiecare scriere cursorul de fișier este incrementat cu numărul de octeți scriși; # ftruncate – trunchiază fișierul (cursorul este plasat pe 0); # apelurile echivalante Windows. # Care dintre următoarele apeluri durează cel mai mult: strcpy}, strdup}, strchr}? #* Răspuns: strcpy copiază șirul iar strchr caută un caracter în șir; strdup realizează operație similară strcpy dar, în plus, alocă spațiu pentru noul șir, operație costisitoare ce poate însemna și efectuarea unui apel de sistem. În concluzie, strdup durează, în general, cel mai mult. # Care dintre următoarele apeluri au legătură directă cu procesele zombie: fork}, dup}, wait}, exec}, malloc}? #* Răspuns: Un proces zombie este un proces care a murit dar care nu a fost așteptat (wait) de procesul părinte; informațiile legate de încheiere ocupă spațiu în memorie până la un apel wait}/waitpid}/waitforsingleobject} al procesului părinte. Apelul wait} are, așadar, legătură directă cu procesele zombie. ==== 3CA, nr. 2 ==== # Ce valoare întoarce fork} în procesul părinte? Dar în procesul copil? De ce? #* Răspuns: În procesul copil întoarce 0 pentru că procesul poate folosi apelul getppid} pentru a afla PID-ul procesul părinte. În procesul părinte, fork} întoarce PID-ul procesului copil. Un proces poate avea mai multe procese copil și este comod ca fork} să întoarcă PID-ul procesului copil proaspăt creat. # Unde este poziționat cursorul de fișier în urma apelului:<code c> open(“a.txt”, O_CREAT | O_RDWR, 0644); </code>Dar în urma apelului:<code> open(“a.txt”, O_RDWR | O_TRUNC); </code>Se presupune că apelurile se întorc cu succes. #* Răspuns: De fiecare dată cursorul este plasat la începutul fișierului: în prima situație se va începe citirea/scrierea de la începutul fișierului; în a doua situație fișierul este trunchiat și cursorul se află la început. Singura situație în care cursorul este plasat altundeva în momentul deschiderii acestuia este aceea în care se folosește flag-ul o_append}. # Câți descriptori de fișier ai unui proces pot referi, la un moment dat, ieșirea standard (standard output)? #* Răspuns: Oricâți, în limita dimensiunii tabelei de descriptori de fișier a procesului, prin intermediul folosirii apelului dup}/dup2}:<code> for (i = 3; i < getdtablesize(); i++) dup2(1, i); </code> ==== 3CC, nr. 1 ==== # Care dintre următoarele apeluri întoarce un întreg: open}, read}, malloc}, fopen}? #* Răspuns: # open întoarce un file descriptor (întreg) – DA # read întoarce numărul de octeți citiți (întreg) – DA # malloc întoarce adresa de memorie alocată (pointer) – NU # fopen întoarce FILE * (un pointer) – NU # În ce situație modificarea cursorului de fișier pentru un descriptor conduce la modificarea cursorului de fișier pentru alt descriptor? #* Răspuns: în cazul în care unul dintre descriptori este un duplicat al altui descriptor; amândoi vor partaja descriptorul de fișier # Un descriptor de fișier pentru un proces dat poate referi între x} și y} fișiere. Ce valori au x} și y}? #* Răspuns: X = 0 în cazul în care descriptorul este nevalid/nealocat; Y = 1 – un descriptor de fișier referă un singur fișier; nu poate să refere mai multe fișiere ==== 3CC, nr. 2 ==== # Un proces poate avea între a} și b} procese copil și între c} și d} procese părinte. Ce valori au (a}, b}) respectiv (c}, d})? #* Răspuns: # (A, B) = (0, inf) - un proces poate avea oricâte procese copil, în limita resurselor disponibile # (C, D) = (1, 1) - orice proces copil are un proces părinte, se poate considera init ca proces fără proces părinte; se permite soluția (C, D) = (0, 1) (dacă se precizează init) # Un apel de bibliotecă (libc) poate invoca între x} și y} apeluri de sistem. Ce valori au x} și y}? #* Răspuns: (X, Y) = (0, inf) poate să nu invoce nici un apel de sistem (vezi strcpy) sau mai multe apeluri de sistem (teoretic infinite); nu există o limitare pentru ca un apel de bibliotecă să apeleze mai multe apeluri de sistem (sau foarte multe), doar că nu este ceva comun. # Listați secvența de pseudocod prin care scrierea la descriptorul 1 al unui proces să realizeze afișarea la stderr iar scrierea la descriptorul 2 să realizeze afișarea la stdout. #* Răspuns:<code> dup2(1, 3); dup2(2, 1); dup2(3, 2); </code> ==== Lucrare 2 ==== *29 martie, 09:05-09:15, EC004, seria CA *30 martie, 17:05-17:15, EC105, seria CC ==== 3CA, nr. 1 ==== # Câte procese se pot găsi, la un moment dat, într-un sistem de operare, în stările running}, ready} și waiting}? #* Răspuns: # În starea running} se găsesc procesele care execută cod pe procesor. Numărul maxim de procese în acea stare este dat de numărul de procesoare. # În starea ready}, respectiv waiting} se pot găsi oricâte procese în limita resurselor sistemului. În ready} se vor găsi procese gata de rulare, neblocate, care așteaptă acordarea de timp pe procesor; în starea waiting} se vor găsi procese blocate în așteptarea unei acțiuni de blocare (dispozitiv de I/O, semafoare cozi de mesaje). Nu există o limitare dată pentru procesele din starea ready} sau waiting}. # Se poate implementa un semafor folosind doar mutex-uri? Dar un mutex folosind doar semafoare? #* Răspuns: # Un mutex se poate implementa ca un semafor binar. Răspuns afirmativ la a doua întrebare. # (Mulțumim lui Răzvan Pistolea pentru observație) Pentru implementarea unui semafor cu mutex-uri, este nevoie de un mutex care să îndeplinească rolul unei variabile condiție (pentru notificare). În acest caz, trebuie ca acel mutex să nu poată fi incrementat de două ori (adică să se apeleze release de două ori). În plus, trebuie asigurată sincronizarea corespunzătoare, pentru a preveni condițiile de cursă, precum două thread-uri care trec de semafor în momentul în care valoarea acestuia este 1. #* Mai multe exemple sunt prezentate aici. # Dați exemplu de avantaj, respectiv dezavantaj al paginării ierarhice în fața paginării simple (neierarhice). #* Răspuns: # Avantaj: paginarea ierarhică ocupă mai puțin spațiu; se ocupă spațiu doar pentru zonele de memorie virtuale valide. În cazul paginării simple, tabela de pagini ocupă același spațiu indiferent de numărul de pagini virtuale valide. # Dezavataje: #* overhead de prelucrare mai mare (trebuie parcurse mai multe tabele de pagini, mai multe referențieri); #* complexitate mai mare de implementare (împărțire mai fină a unei adrese de memorie).

3CA, nr. 2

# Pentru un sistem se dorește productivitate (throughput) mare. De ce se preferă alegerea unei cuante de timp (timeslice) mare pentru procese? #* Răspuns: # Productivitate mare înseamnă un timp mare consumat pe lucru efectiv (rulare pe procesor) pe lângă timpi consumați pentru alte activități, cea mai importantă fiind schimabrea de context. # În cazul unei cuante de timp mari, proceselor vor lucra timp îndelungat iar timpul consumat pe schimbarea de context (apărută la expirarea cuantei) va fi mai mic, relativ. # Fie un sistem cu două procesoare. Câte procese pot “aștepta” simultan eliberarea unui spinlock? Dar a unui mutex? #* Răspuns: # La un mutex pot aștepta oricâte procese. Dacă mutexul este achiziționat, procesele se blochează și trec în starea waiting}. Pot exista oricâte procese în starea waiting}. # Dacă un proces a achiziționat un spinlock, cel mult un alt proces poate “aștepta” (busy waiting) așteptarea acestuia pe un alt procesor. Dacă cele două procese (ce rulează pe procesor) au ajuns la un livelock (ambele așteaptă la spinlock) sistemul este “agățat”; ambele așteaptă în acel moment la spinlock. #* Un proces care deține un spinlock nu va fi planificat pentru că atunci alte procese ar aștepta nedefinit și sistemul devine instabil. Un spinlock protejează o zonă scurtă și rapidă. De asemenea, un proces care “așteaptă” la un spinlock nu va fi preemptat pentru că așteptarea este că va aștepta puțin la procesor (prin busy waiting). #* În concluzie, pe un sistem cu două procesoare, eliberarea unui spinlock poate fi așteptată de cel mult două procese. # Fie un sistem cu paginare simplă (neierarhică). Pot două pagini de memorie virtuală referi aceeași pagină de memorie fizică? Dar invers? #* Răspuns: # Da, două pagini de memorie virtuală pot referi aceeași pagină. #* În această situație, în cadrul unui proces, în tabela de pagini, unor intrări diferite (indexate de pagina virtuală A și pagina virtuală B) le corespunde aceeași pagină fizică. #* În cazul a două procese este vorba de implementarea mecanismului de shared memory. # Nu, două pagini de memorie fizică nu pot referi aceeași pagină virtuală. Adresa virtuală este cea folosită de proces. O astfel de adresă nu poate indica spre două adrese fizice diferite. Este similar cu a spune că f_x_a} și f_x_b}, unde a_b}. # Nu are relevanță folosirea paginării simple. Afirmațiile sunt valabile pentru orice tip de paginare: ierarhică, neierarhică, inversată. ==== 3CC, nr. 1 ==== # Dați exemplu de acțiune ce conduce la trecerea unui proces din starea ready} în running} și un exemplu care conduce la o trecere inversă. #* Răspuns: # Un proces trece din starea running} în ready} în momentul în care i-a expirat cuanta de timp sau când există un alt proces prioritar lui în coada ready}. #* Observație: Blocarea procesului conduce la trecerea acestuia în coada waiting}, iar omorârea procesului înseamnă că acesta nu trece în nici o altă coadă. # Un proces trece din ready} în running} în momentul în care se găsește în vârful cozii ready} și procesului care rulează pe procesor (cel din starea running}) îi expiră cuanta, sau are prioritate mai mică, sau acel proces se blochează sau acel proces moare. # Este nevoie de folosirea unui mecanism de sincronizare la folosirea memoriei partajate? Dar la folosirea cozilor de mesaje? #* Răspuns: # Da, la memoria partajată. Două (sau mai multe procese) pot decide să scrie în memorie partajată și pot rezulta date incorecte. Este nevoie de protejarea prin folosirea unui mecanism de locking. # În cazul folosirii cozilor de mesaje nu este nevoie de folosirea unui mecanism de sincronizare. Aceasta deoarece operațiile pe cozile de mesaje sunt atomice și serializate. #* Scrierea unui mesaj se face după altă scriere, iar citirea unui mesaj se realizează în momentul în care un mesaj există deja în coadă (altfel se blochează în așteptare). Nu este necesară folosirea unei forme de utilizare de genul unlock}. # Fie struct_tlb_entry} o structură aferentă unei intrări în TLB. Ce câmpuri conține o astfel de structură? #* Răspuns: # TLB-ul este folosit pentru translatarea rapidă a adreselor virtuale în adrese fizice. Structura conține adresa paginii virtuale și adresa paginii fizice aferente.

3CC, nr. 2

# Dați exemplu de acțiune ce conduce la trecerea unui proces din starea ready} în waiting} și un exemplu care conduce la o trecere inversă. #* Răspuns: # Un proces nu poate trece direct din starea ready} în waiting}. Pentru a ajunge în waiting} trebuie să execute o acțiune blocantă, adică trebuie să ruleze, adică trebuie să se găsească în starea running}. # Un proces trece din starea waiting} în ready} atunci când a dispărut cauza blocării sale: a apărut un eveniment de I/O pe care îl aștepta, a fost notificat, a fost făcut unlock pe mutex-ul la care aștepta etc. Procesul este, atunci, pregătit pentru execuție. # Dați exemplu de situație în care trei procese care interacționează ajung în deadlock. #* Răspuns: # Cea mai simplă situație este aceea a unei așteptări circulare a proceselor. Procesele, respectiv, p1}, p2}, p3} dețin resursele r1}, r2}, r3} fără a le elibera. Apoi procesul p1} solicită accesul la resursa r2}, p2} la r3} iar p3} la r1}. Fiecare proces așteaptă la o resursă deținută de alt proces, fără ca vreunul din ele să o fi eliberat. Toate sunt blocate – deadlock. # De ce este golit (flushed) TLB-ul la o schimbare de context? #* Răspuns: # TLB-ul conține un subset de intrări din tabela de pagini pentru acces rapid din partea procesorului. Tabela de pagini este proprie fiecărui proces (spațiului de adresă al acestuia). La o shimbare de context, procesul este schimbat și la fel și tabela de pagini. Schimbarea tabelei de pagini înseamnă invalidarea TLB-ului și este necesară golirea acestuia.

Lucrare 3

  • 19 aprilie, 09:05-09:15, EC004, seria CA
  • 20 aprilie, 17:05-17:15, EC105, seria CC

3CA, nr. 1

# Dați exemplu de situație în care se produce page fault (la nivelul subsistemului de gestiune a memoriei), fără a rezulta în segmentation fault/excepție la nivelul procesului care a cauzat page fault-ul. ## În cazul demand paging, se alocă o pagină virtuală (page) fără suport fizic (frame). La apariția unui page fault se va aloca o pagină fizică, fără a rezulta o excepție. ## În cazul copy-on-write, două pagini virtuale (page) (din două procese diferite) sunt marcate read-only și referă aceeași pagină fizică (frame). În momentul în care unul dintre cele două procese efectuează o operație de scriere, se obține page fault, se duplică pagina fizică și se continuă execuția. ## În cazul unei pagini virtuale (page) valide, al cărei conținut se găsește în swap, un acces generează page fault. Conținutul este swapped in într-o pagină fizică (frame) si procesul își continuă execuția. # Fie un program multithreaded care efectuază multe operații I/O per thread. Este mai eficientă folosirea user-level threads sau kernel-level threads? #* Operațiile I/O sunt, în general, operații blocante. Efectuarea unei operații de I/O în cadrul unei implementări de thread-uri user-level va bloca întreg procesul, nu doar thread-ul curent. #* În cadrul unei implementări de thread-uri kernel-level, doar thread-ul care a efectuat operația I/O, celelalte thread-uri putând fi planificate pe procesor. #* Implementarea kernel-level threads este, în acest caz mai eficientă, prin folosirea procesorului/procesoarelor de mai multe thread-uri ale proceselor. # Cine/ce generează întreruperi și cine/ce le tratează? #* Întreruperile sunt generate de dispozitivele hardware la apariția unui eveniment specific (primirea de date/eliberarea unui buffer local, caz de eroare). #* Tratarea întreruperilor este realizează de procesor în cadrul unei rutine de tratare a întreruperii (IRQ handler sau ISR – Interrupt Service Routine).

3CA, nr. 2

# Care este rolul bitului dirty / modified pentru subsistemul de înlocuire a paginilor? Bitul este activat în momentul în care o pagină este modificată/scrisă. #* Dacă o pagină este modificată atunci o eventuală alegere a acestei pagini pentru a fi evacuată (swapped out) va înseamnă scrierea acesteia pe disc. #* Dacă o pagină nu este modificată (bitul dirty este dezactivat) nu va mai fi scrisă pe disc în momentul evacuării, rezultând într-un overhead redus al operației de înlocuire. #* În general, algoritmii de înlocuire de pagini din cadrul subsistemelor aferente, vor ține cont de ultimul acces (fie de scriere, fie de citire al unei pagini) – LRU, NRU (Least/Not Recently Used). Se vor prefera paginile nereferite recent, iar dintre acestea, cele care nu au fost scrise (bitul dirty dezactivat) – vezi NRU. # Fie un program multithreaded care rulează pe un sistem multiprocesor. Este mai eficientă folosirea user-level threads sau kernel-level threads? #* În cadrul unei implementări user-level, un singur thread rulează pe procesor; planificatorul de la nivelul nucleului “vede” o singură entitate planificabilă – procesul corespunzător. #* În cadrul unei implementări kernel-level, fiecare thread al procesului poate rula pe un procesor. Se poate întâmpla ca, pe un sistem cu număr suficient de procesoare, toate thread-urile unui proces să ruleze pe procesoare. #* În concluzie, este mai eficientă folosirea unei implementări kernel-level prin utilizarea mai bună a procesoarelor, rezultând, astfel, într-o productivitate mai bună. # Dați exemplu de funcție de API care efectuează operații I/O sincrone și o funcție care efectuează operații I/O asincrone. #* Operații I/O sincrone: read}, write}. Sunt funcții la apelul cărora se execută operația de I/O. #* Operații I/O asincrone: aio_read}, aio_write}, o}, select}. # Primele 3 sunt operații asincrone, neblocante. Asincrone – declanșează o operația I/O fără a urmări “sincron” execuția acesteia; neblocante – nu se blochează în așteptarea încheierii operației. # select} – nu este cu adevărat o operație I/O, ci un apel de control a acestora. Poate fi considerată asincronă pentru că nu urmărește execuția unui set de operații; fie sincrone sau asincrone, select} este un apel blocant care notifică încheierea unei operații I/O.

3CC, nr. 1

# Dați exemplu de situație/scenariu în care apariția unui page fault determină swap out. #* În cazul apariției unui page fault, este posibil ca pagina fizică (frame) aferentă să nu fie alocată (demand paging sau copy-on-write) sau să fie pe disc (swapped). În acest caz pagina trebuie adusă în RAM. #* Dacă memoria fizică (RAM) este ocupată, va trebui aleasă o pagină fizică pentru a fi înlocuită. Se aplică un algoritm de înlocuire a paginii. #* În momentul aplicării algoritmului de înlocuire a paginii, pagina fizică este evacuată pe disc (swapped out); conținutul de pe disc aferent paginii ce a cauzat page fault-ul este adus în memorie (swapped in) în locul paginii fizice proaspăt evacuate. # Fie următoarea secvență de cod:

int main(void)
{
    int a = 0;
    pthread_create(...);
    a++;
}

Care va fi valoarea lui a} la finalul secvenței? #* În urma apelului pthread_create} thread-ul principal (main thread, master thread) își continuă execuția; thread-ul nou creat execută funcția transmisă ca argument funcției pthread_create}. #* Variabila a} va fi incrementată doar de thread-ul principal, astfel că valoarea finală a acesteia va fi 1. #* O situație diferită este aceea în care a} este transmisă într-o formă ca argument funcției aferente thread-ului nou creat și acesta o modifică; de asemenea, o valoare diferită rezultă în momentul în care thread-ul nou creat accesează variabila a pe stiva thread-ului principal (foarte puțin probabil, dar posibil). # Care este scopul sortării cererilor de I/E pe care le face un sistem de operare atunci când lucrează cu discul? #* Sortarea cererilor de I/E rezultă în organizarea acestora după sectorul de pe disc din care fac parte. #* Prin sortarea acestora se minimizează timpul de căutare și poziționarea acului mecanic pe sector corespunzător. În loc să se rotească discul înainte și înapoi pentru poziționare pe capătul/sectorul/platanul corespunzător, se parcurg liniar/secvențial sectoarele descrise în cereri. #* Rezultă, astfel, un overhead redus al căutării (seek) pe disc în cadrul cererilor de I/E – performanță îmbunătățită.

3CC, nr. 2

# Dați exemplu de situație/scenariu în care apariția unui page fault determină swap in. #* Vezi explicația de la exercițiul 1 de la numărul 3CC, nr. 1. # În ce situație pot două thread-uri din două procese diferite să partajeze o pagină de memorie? #* Două thread-uri din două procese diferite nu pot partaja o pagină de memorie decât în cazul în care cele două procese o partajează la rândul lor. #* Întrebarea se transformă, așadar, în “când pot două procese diferite să partajeze o pagină de memorie?” # când cele două procese referă au mapată aceeași pagină fizică (folosint apeluri de forma mmap}); # când cele două procese sunt înrudite și referă o pagină prin copy-on-write; # când cele două procese au mapat același executabil/aceeași bibliotecă (codul acestora este read-only și paginile fizice aferente sunt partajate). # Cu ce diferă o operație I/O asincronă de o operație I/O neblocantă? #* O operație I/O asincronă este pornită dar nu se așteaptă încheierea acesteia. În momentul încheierii operației, se trimite o notificare. #* O operație I/O neblocantă se întoarce imediat. Dacă este sincronă atunci va citi/scrie cât îi oferă dispozitivul. Dacă este asincronă, va primi notificare la încheierea operației. #* Diferența constă, în general, în primirea sau nu a unei notificări, la sfârșitul încheierii operației de I/O. Acest lucru se întâmplă tot timpul la o operație I/O asincronă; la o operație I/O neblocantă se întâmplă doar dacă aceasta este asincronă – dacă este sincronă (read} cu o_nonblock}) atunci nu se primește notificare, doar se întoarce după ce a scris/citit cât i-a oferit dispozitivul. ==== Lucrare 4 ==== *17 aprilie, 09:05-09:15, EC004, seria CA *18 aprilie, 17:05-17:15, EC105, seria CC ==== 3CA, nr. 1 ==== # Care este forma de asociere între dentry și inode? (unu la unu, mai multe la mai multe etc.) #* Un dentry conține un nume și un inode number. Două sau mai multe dentry-uri pot referi același inode, prin intermediul inode number-ului (denumite și hard link-uri). Asocierea este mai multe dentry-uri la un inode. # De ce nu poate rula un sistem de operare Windows într-un container OpenVZ? #* OpenVZ este o soluție de virtualizare la nivelul sistemului de operare (operating system-level virtualization). În consecință, mașinile virtuale/containerele create partajează nucleul sistemului de operare. #* Nu se poate crea/rula un container care folosește un kernel diferit de al sistemului de bază. Întrucât OpenVZ este o soluție specifică nucleului Linux doar soluții bazate pe acest nucleu vor putea rula (nu Windows, Mac OS X, Open Solaris, *BSD). # Cum previne tehnica ASLR (Address Space Layout Randomization) atacuri de tipul return-to-libc? #* Un atac de tipul return-to-libc presupune suprascrierea adresei de retur din cadrul stack frame-ului unei funcții cu o adresă din zona de cod a procesului (cel mai probabil codul aferent pentru system} sau exec}). #* Tehnica ASLR împiedică atacatorul să cunoască adresa funcției dorite din cadrul zonei de cod prin maparea acestora în puncte aleatoare din spațiul de adresă. În cazul unui spațiu virtual suficient de mare (spre exemplu în cazul sistemelor pe 64 de biți), timpul de “căutare” a adresei dorite face impractice atacuri de tipul return-to-libc. ==== 3CA, nr. 2 ==== # De ce este mai eficientă folosirea unei tabele FAT în locul alocării cu liste pentru gestiunea blocurilor libere ale unui sistem de fișiere? #* Alocarea cu liste presupune existența, la sfârșitul fiecărui bloc, a unui pointer către următorul bloc de date. Acest lucru înseamnă că, pentru a ajunge la al N-lea bloc de date, trebuie parcurse (citite de pe disc și aduse în memorie) N-1 blocuri de date. #* În cazul tabelei FAT toți pointerii sunt ținuți localizat în cadrul tabelei. La o adresă specifică unui bloc se găsește un pointer către o altă adresă (specifică altui bloc). Overhead-ul/timpul de citire a unui bloc de date este, astfel, mult redus. #* Tabela FAT, fiind localizată, poate fi stocată în cache-ul de memorie, mărind astfel viteza de acces la resursele aferente. # De ce OpenVZ scalează mai bine decât VMware Workstation (scalează = se pot crea și pot rula simultan mai multe mașini virtuale)? #* Fiind vorba de o soluție de virtualizare la nivelul sistemului de operare (operating system-level virtualization), aplicațiile din cadrul containerelor OpenVZ apelează direct nucleul sistemului de operare. Overhead-ul de rulare este minimal, dat de asigurarea separării între containere. #* În cazul VMware Workstation, o soluție de virtualizare hosted, aplicațiile aferente apelează hypervisor-ul (VMM) care face legătura cu sistemul de operare al sistemului de bază. Overhead-ul este dat de trecerea prin niveluri suplimentare date de hypervisor. În plus, separația datelor este dată de fișiere specializate pentru disc (vmdk}) ce înseamnă overhead suplimentar. # Cum previne flag-ul NX (No eXecute) atacurile de tipul stack buffer overflow? #* Atacurile de tipul stack buffer overflow presupun suprascrierea adresei de retur din cadrul stack frame-ului unei funcții prin trecerea peste limita unui buffer alocat pe stivă. În general, adresa este suprascrisă chiar cu o adresă de pe stivă din cadrul buffer-ului. # Atacatorul completează în cadrul buffer-ului de pe stivă un shell code și apoi suprascrie adresa de retur cu adresa din cadrul buffer-ului unde începe shell code-ul. #* Flag-ul NX este un flag/bit hardware ce marchează anumite pagini ca fiind neexecutabile. Exemple de zone care sunt candidați pentru acest bit sunt stiva, heap-ul și zonele de date. Marcarea stivei ca fiind neexecutabilă, prin folosirea flag-ului NX, înseamnă imposibilitatea realizării unui atac de tipul stack buffer overflow.

3CC, nr. 1

# De ce nu se poate crea un hard link către un inode de pe alt sistem de fișiere? #* Un hard link este un dentry; conține un nume și un număr de inode. #* Întrucât două sisteme de fișiere diferite pot avea alocat același inode, este ambiguă prezența unui număr de inode ce referă al sistem de fișiere. Numărul de inode din cadrul dentry-ul aferent va referi inode-ul de pe sistemul curent de fișiere. # De ce este considerat VMware Workstation o soluție de tipul hosted hypervisor, pe când Xen nu? #* VMware Workstation rulează ca o aplicație peste un sistem de operare existent. Sistemul de operare oferă o gamă largă de servicii utilizatorului, printre acestea numărându-se și posibilitatea rulării VMware Workstation. #* Xen nu rulează peste un sistem de operare existent. În general, Xen este instalat în forma unui sistem de operare Linux cu suportul de virtualizare direct peste hardware (bare metal hypervisor). # Cum sunt prevenite atacurile de tipul stack buffer overflow folosind soluții de tipul stack smashing protection? #* Vezi descriere stack buffer overflow mai sus. #* Soluțiile de tipul stack smashing protection presupun plasarea unei valori speciale (canary value) înaintea adresei de retur dintr-un stack frame. #* Întrucât majoritatea atacurilor presupun operații pe șiruri, suprascrierea adresei de retur va însemna și suprascrierea valorii speciale. Înainte de revenirea de funcție se verifică această valoare. Dacă a fost modificată atunci se generează eroare.

3CC, nr. 2

# În cazul alocării indexate, inode-ul conține un număr limitat de pointeri către blocuri de date, limitând astfel dimensiunea maximă a unui fișier. Cum este rezolvată această problemă? #* Problema este rezolvată prin indirectare. O parte din pointerii din cadrul inode-ului nu vor referi blocuri de date, ci vor referi blocuri cu pointeri către blocuri de date (indirectare simplă) sau blocuri cu pointeri către blocuri cu pointeri către blocuri de date (indirectare dublă) etc. Dezavantajul este o latență mai mare de acces pentru blocurile finale. # De ce este considerat Xen o soluție de tipul bare metal hypervisor, pe când VMware Workstation nu? #* Vezi răspunsul de la 3CC, nr. 1, exercițiul 2. # De ce executabilul aferent comenzii su (/bin/su) are bitul setuid activat? #* Un proces care ia naștere din cadul executabilului su} execută o serie de operații privilegiate precum: # parcurgerea fișierului shadow} pentru a citi parola; # schimbarea user id-ului curent (practic schimbarea utilizatorului). #* Pentru executarea operațiilor privilegiate este nevoie de drept de superuser. Prezența bitului setuid permite efectuarea acestora.

so/examen/2010-2011.txt · Last modified: 2013/01/31 21:57 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0