This shows you the differences between two versions of the page.
|
so2:laboratoare:lab05:exercitii [2018/03/21 11:31] ionel.ghita [5. [3p] Curățarea buffer-ului dacă este tastată o parolă] |
so2:laboratoare:lab05:exercitii [2019/03/20 11:49] (current) gabriel.bercaru [1. [2.5p] Alocare de porturi I/O] - fixed typo ('kdb' instead of 'kbd') |
||
|---|---|---|---|
| Line 104: | Line 104: | ||
| Obiectivul exercițiilor următoare este să creați un driver pentru a intercepta tastele apăsate (//keylogger//). Driver-ul va intercepta IRQ-ul destinat controller-ului de tastatură și va inspecta codurile tastelor primite, stocându-le într-un buffer. | Obiectivul exercițiilor următoare este să creați un driver pentru a intercepta tastele apăsate (//keylogger//). Driver-ul va intercepta IRQ-ul destinat controller-ului de tastatură și va inspecta codurile tastelor primite, stocându-le într-un buffer. | ||
| - | ==== 1. [1.5p] Alocare de porturi I/O ==== | + | ==== 1. [2.5p] Alocare de porturi I/O ==== |
| Pentru început ne propunem să alocăm spații din zona I/O pentru dispozitive hardware. Vom vedea că nu putem să alocăm spațiu pentru tastatură întrucât regiunea aferentă e deja alocată. Apoi vom aloca spațiu I/O pentru porturi care nu sunt folosite. | Pentru început ne propunem să alocăm spații din zona I/O pentru dispozitive hardware. Vom vedea că nu putem să alocăm spațiu pentru tastatură întrucât regiunea aferentă e deja alocată. Apoi vom aloca spațiu I/O pentru porturi care nu sunt folosite. | ||
| Line 141: | Line 141: | ||
| Descărcați modulul din kernel folosind comanda<code> | Descărcați modulul din kernel folosind comanda<code> | ||
| - | rmmod kdb | + | rmmod kbd |
| </code> și verificați acum conținutul fișierului ''/proc/ioports''; observți că a dispărut alocarea spațiului I/O pentru cele două porturi. | </code> și verificați acum conținutul fișierului ''/proc/ioports''; observți că a dispărut alocarea spațiului I/O pentru cele două porturi. | ||
| Line 148: | Line 148: | ||
| </note> | </note> | ||
| - | ==== 2. [1.5p] Rutina de tratare a întreruperii ==== | + | ==== 2. [2p] Rutina de tratare a întreruperii ==== |
| Urmărim să înregistrăm o rutină de tratare a întreruperii de tastatură. Veți scrie o funcție (rutină) de tratare a înteruperii și o veți înregistra folosind ''[[https://elixir.bootlin.com/linux/v4.15/source/include/linux/interrupt.h#L145|request_irq]]''. | Urmărim să înregistrăm o rutină de tratare a întreruperii de tastatură. Veți scrie o funcție (rutină) de tratare a înteruperii și o veți înregistra folosind ''[[https://elixir.bootlin.com/linux/v4.15/source/include/linux/interrupt.h#L145|request_irq]]''. | ||
| Line 207: | Line 207: | ||
| <note tip> | <note tip> | ||
| Pentru afișare în cadrul handler-ului de întrerupere folosiți o construcție de forma:<code> | Pentru afișare în cadrul handler-ului de întrerupere folosiți o construcție de forma:<code> | ||
| - | pr_info("IRQ:% d, scancode = 0x% x (% u,% c) \ n" | + | pr_info("IRQ %d: scancode=0x%x (%u) pressed=%d ch=%c\n", |
| - | irq_no, scancode, scancode, scancode); | + | irq_no, scancode, scancode, pressed, ch); |
| </code> | </code> | ||
| unde ''scancode'' este valoarea registrului citit cu ajutorul funcției ''i8042_read_data()''. | unde ''scancode'' este valoarea registrului citit cu ajutorul funcției ''i8042_read_data()''. | ||
| Line 256: | Line 256: | ||
| <note tip> | <note tip> | ||
| Pentru afișare în cadrul handler-ului de întrerupere folosiți o construcție de forma:<code> | Pentru afișare în cadrul handler-ului de întrerupere folosiți o construcție de forma:<code> | ||
| - | printk(LOG_LEVEL "IRQ %d: scancode=0x%x (%u) pressed=%d ch=%c\n", | + | pr_info(LOG_LEVEL "IRQ %d: scancode=0x%x (%u) pressed=%d ch=%c\n", |
| irq_no, scancode, scancode, pressed, ch); | irq_no, scancode, scancode, pressed, ch); | ||
| </code> | </code> | ||
| Line 324: | Line 324: | ||
| O să obțineți conținutul bufferului keylogger-ului din kernel space. | O să obțineți conținutul bufferului keylogger-ului din kernel space. | ||
| - | ==== 5. [1p] Curățarea buffer-ului la scriere ==== | + | ==== 5. [1.5p] Curățarea buffer-ului la scriere ==== |
| Dorim să %%"curățăm"%% buffer-ul atunci când se scrie în device node-ul asociat driver-ului. În acel moment buffer-ul va fi resetat: conținutul său va fi resetat și dimensiunea va fi ''0''. | Dorim să %%"curățăm"%% buffer-ul atunci când se scrie în device node-ul asociat driver-ului. În acel moment buffer-ul va fi resetat: conținutul său va fi resetat și dimensiunea va fi ''0''. | ||
| Line 346: | Line 346: | ||
| ===== Extra ===== | ===== Extra ===== | ||
| - | |||
| - | ==== [1 karma] Resetarea buffer-ului în rutina de read ==== | ||
| - | |||
| - | Implementarea curentă este problematică pentru că rutina de tratare a întreruperii este cea care face resetarea buffer-ului, lucru care este consumator de timp și nerecomandat să fie făcut în context întrerupere. | ||
| - | |||
| - | O soluție este să actualizăm comportamentul astfel încât resetarea buffer-ului să se producă la apelul funcției ''kbd_read()''. După ce informația este copiată în user space, buffer-ul este resetat. Nu mai resetăm în momentul tastării | ||
| - | |||
| - | Simplificați implementarea în așa fel încât resetarea buffer-ului să se producă în funcția ''kbd_read()'' imediat după copierea datele în user space. | ||
| - | |||
| - | <note tip> | ||
| - | În momentul în care copiați datele în buffer-ul temporare ''tmp_buf'' resetați buffer-ul principal: adică umpleți buffer-ul ''buf'' cu zero-uri și inițialiați ''buf_idx'' la ''0''. | ||
| - | </note> | ||
| - | |||
| - | Pentru verificarea după citirea din ''/dev/kbd'' veți avea buffer-ul resetat. Citiri ulterioare vor găsi buffer-ul gol. | ||
| ==== [3 karma] Utilizare kfifo ==== | ==== [3 karma] Utilizare kfifo ==== | ||