Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so2:laboratoare:lab02:exercitii [2017/03/02 17:13]
george.muraru [Laborator 2: Exerciții - propagate RD modifications for netconsole]
so2:laboratoare:lab02:exercitii [2019/02/25 15:18] (current)
ionel.ghita [Extra]
Line 1: Line 1:
 ====== Laborator 2: Exerciții ====== ====== Laborator 2: Exerciții ======
  
-Pentru desfășurarea laboratorului ​pornim ​de la [[http://​elf.cs.pub.ro/so2/res/laboratoare/lab02-tasks.zip|arhiva ​de sarcini a laboratorului]]. Descărcăși decomprimăm arhiva în directorul ''​so2/'' ​din directorul home al utilizatorului ''​student''​ de pe sistemul de bază (stația ''​asgard''​):<code bash> +===== Pregătirea laboratorului ===== 
-student@asgard:​~$ cd so2/ + 
-student@asgard:​~/​so2$ wget http://​elf.cs.pub.ro/​so2/​res/​laboratoare/​lab02-tasks.zip +Pentru rezolvarea laboratorului,​ vom lucra în același director din care pornim ​mașina virtuală (''​~/so2/linux/tools/labs''​). 
-student@asgard:​~/​so2$ unzip lab02-tasks.zip + 
-student@asgard:​~/​so2tree lab02-tasks+Pașii ​de rezolvare sunt următorii: 
 +  * pregătirea scheletului de laborator 
 +  * compilarea modulelor de Kernel 
 +  * copierea modulelor pe mașina virtuală 
 +  * pornirea mașinii virtuale ​și testarea modulelor 
 + 
 +==== Pregătirea scheletului de laborator ==== 
 + 
 +Scheletul de laborator este generat din sursele din directorul ''​tools/labs/​templates''​. Putem genera scheletele pentru toate laboratoarele folosind următoarea comanda: 
 + 
 +<code bash> 
 +tools/labs make skels
 </​code>​ </​code>​
-În cadrul directorului ''​lab02-tasks/''​ se găsesc resursele necesare pentru dezvoltarea exercițiilor de mai jos: fișiere schelet de cod sursă, fișiere Makefile și Kbuild, scripturi și programe de test. 
  
-Vom dezvolta exercițiile pe sistemul ​de bază (stația ​''​asgard''​și apoi le vom testa pe [[:so2:​resurse:​masini-virtuale|mașina virtuală ​QEMU]]. După editarea și compilarea unui modul de kernel îl vom copia în directorul dedicat pentru ​mașina virtuală ​QEMU folosind ​o comandă de forma<code bash> +Pentru a genera scheletul pentru un singur laborator, vom folosi variabila ​de mediu ''​LABS''​
-student@asgard:~/so2$ cp /path/to/module.ko ​~/so2/qemu-so2/fsimg/​root/​modules+ 
-</​code> ​unde ''​/​path/​to/​module.ko'' ​este calea către fișierul obiect aferent modulului de kernelApoi vom porni, din directorul ''​~/so2/qemu-so2/'', ​mașina virtuală ​QEMU folosind comanda<code bash> +<code bash> 
-student@asgard:~/so2/qemu-so2make+tools/labs $ make clean 
 +tools/labs $ LABS=<​lab name> make skels 
 +</​code>​ 
 + 
 +<note important>​ 
 +Numele laboratorului curent este ''​kernel_modules''​. 
 +</​note>​ 
 + 
 +Similar, putem genera ​și scheletul pentru un singur exercițiu, atribuind valoarea ''<​lab_name>/<​task_name>''​ variabilei ''​LABS''​. 
 + 
 +<​note>​ 
 +Scheletul este generat în directorul ''​tools/​labs/​skels''​. 
 +</​note>​ 
 + 
 +==== Compilarea modulelor ==== 
 + 
 +Comanda ''​make build''​ compilează toate modulele din directorul ''​skels''​. 
 + 
 +<code bash> 
 +student@eg106:~/so2/​linux/​tools/​labs$ make build 
 +echo "# autogenerated,​ do not edit " > skels/​Kbuild 
 +echo "​ccflags-y += -Wno-unused-function -Wno-unused-label -Wno-unused-variable " >> skels/​Kbuild 
 +for i in ./​kernel_modules/​9-kdb ./​kernel_modules/​7-list-proc ./​kernel_modules/​3-error-mod ./​kernel_modules/​1-2-test-mod ./​kernel_modules/​5-oops-mod ./​kernel_modules/​6-cmd-mod ./​kernel_modules/​8-kprobes ./​kernel_modules/​4-multi-mod;​ do echo "obj-m += $i/" >> skels/​Kbuild;​ done 
 +... 
 +</​code>​ 
 + 
 +==== Copierea modulelor pe mașina virtuală ​==== 
 + 
 +Putem copia modulele generate pe mașina virtuală folosind ​target-ul ''​copy''​ al comenzii make, atunci când mașina virtuală este oprită. 
 + 
 +<code bash> 
 +student@eg106:~/so2/linux/tools/labs$ make copy 
 +student@eg106:​~/so2/linux/tools/labs$ make boot 
 +</​code>​ 
 + 
 +Alternativ, putem copia fișierele prin ''​scp''​, pentru e evita repornirea mașinii virtualePentru detalii despre folosirea interacțiunea prin rețea cu mașina virtuală citiți [[https://ocw.cs.pub.ro/​courses/​so2/resurse/​masini-virtuale#​interactiunea_cu_masina_virtuala|Interacțiunea cu mașina virtuală]]. 
 + 
 +==== Testarea modulelor ==== 
 + 
 +Modulele generate sunt copiate pe mașina virtuală în directorul ''/​home/​root/​skels/<​lab_name>/<​task_name>''​. 
 + 
 +<code bash> 
 +root@qemux86:~/skels/kernel_modules$ ls 
 +1-2-test-mod ​ 3-error-mod ​ 5-oops-mod ​ 6-cmd-mod ​ 7-list-proc ​ 8-kprobes ​ 9-kdb 
 +root@qemux86:​~/​skels/​kernel_modulesls 1-2-test-mod/​ 
 +hello_mod.ko
 </​code>​ </​code>​
  
-După pornirea mașinii virtuale QEMU vom putea folosi comenzi în fereastra QEMU pentru a încărca și descărca modulul de kernel:<​code>​ +După pornirea mașinii virtuale QEMU vom putea folosi comenzi în fereastra QEMU (sau în ''​minicom''​) ​pentru a încărca și descărca modulul de kernel:<​code>​ 
-# insmod ​root/modules/module-name.ko +root@qemux86:​~# insmod ​skels/<​lab_name>​/<​task_name>/<​module_name>​.ko  
-# rmmod root/modules/module-name +root@qemux86:​~# rmmod skels/<​lab_name>​/<​task_name>/<​module_name>​.ko ​ 
-</​code> ​unde ''​module-name''​ este numele modulului de kernel.+</​code> ​
  
 <​note>​ <​note>​
 Pentru dezvoltarea laboratorului,​ este recomandat să folosim trei terminale sau, mai bine, trei tab-uri de terminal. Pentru a deschide un nou tab de terminal folosim combinația de taste ''​Ctrl+Shift+t''​. Cele trei tab-uri de terminal îndeplinesc următoarele roluri: Pentru dezvoltarea laboratorului,​ este recomandat să folosim trei terminale sau, mai bine, trei tab-uri de terminal. Pentru a deschide un nou tab de terminal folosim combinația de taste ''​Ctrl+Shift+t''​. Cele trei tab-uri de terminal îndeplinesc următoarele roluri:
-  - În primul tab de terminal dezvoltăm modulul de kernel: editare, compilare, copiere în directorul dedicat pentru mașina virtuală QEMU. Lucrăm în directorul aferent rezultat în urma decomprimării arhivei ​de sarcini a laboratorului+  - În primul tab de terminal dezvoltăm modulul de kernel: editare, compilare, copiere în directorul dedicat pentru mașina virtuală QEMU. Lucrăm în directorul aferent rezultat în urma generării scheletului ​de laborator, din ''​~/​so2/​linux/​tools/​labs/​skels''​
-  - În al doilea tab de terminal pornim mașina virtuală QEMU și apoi testăm modulul de kernel: încărcare/​descărcare modul, rulare teste. Lucrăm în directorul aferent mașinii virtuale: ''​~/​so2/​qemu-so2/''​. +  - În al doilea tab de terminal pornim mașina virtuală QEMU și apoi testăm modulul de kernel: încărcare/​descărcare modul, rulare teste. Lucrăm în directorul aferent mașinii virtuale: ''​~/​so2/​linux/tools/labs''​. 
-  - În al treilea tab de terminal pornim un server UDP care să primească [[:​so2:​laboratoare:​lab02#​netconsole|mesajele de netconsole]]. Nu contează în ce director ne aflăm. Folosim comanda<​code bash>+  - În al treilea tab de terminal pornim ​[[:​so2:​laboratoare:​lab02#​minicom|minicom]] sau un server UDP care să primească [[:​so2:​laboratoare:​lab02#​netconsole|mesajele de netconsole]]. Nu contează în ce director ne aflăm. Folosim comanda<​code bash>
 student@asgard:​~$ nc -l -p 6000 -u student@asgard:​~$ nc -l -p 6000 -u
 </​code>​ </​code>​
Line 47: Line 102:
   * Variabila ''​ignore_loglevel''​ este folosită pentru a ignora configurațiile de afișare a mesajelor de logging ale nucleului. În mod normal se poate stabili un prag peste care mesajele sunt afișate la terminal. Folosirea ''​ignore_loglevel''​ duce la ignorarea acelui prag.   * Variabila ''​ignore_loglevel''​ este folosită pentru a ignora configurațiile de afișare a mesajelor de logging ale nucleului. În mod normal se poate stabili un prag peste care mesajele sunt afișate la terminal. Folosirea ''​ignore_loglevel''​ duce la ignorarea acelui prag.
 </​hidden>​ </​hidden>​
- 
-<note tip> 
-Pentru ''​cscope''​ parcurgeți [[:​so2:​laboratoare:​lab01#​cscope|secțiunea cscope din primul laborator]]. 
-</​note>​ 
  
 <note warning> <note warning>
Line 59: Line 110:
  
 <note tip> <note tip>
-Atunci când folosiți ''​cscope'',​ va trebui să vă aflați în directorul ''​so2/​linux-4.9.11/''​ din directorul home al utilizatorului ''​student''​.+Atunci când folosiți ''​cscope'',​ va trebui să vă aflați în directorul ''​so2/​linux/''​ din directorul home al utilizatorului ''​student''​.
 </​note>​ </​note>​
  
Line 79: Line 130:
  
 La fel, dacă ați găsit mai multe match-uri și dacă ai deschis o subfereastră cu toate match-urile (folosind '':​copen''​) și dacă sunteți în căutarea locului de definiție a unui macro, ​ este indicat să căutați în subfereastră (folosind ''/''​ -- //slash//) după șirul ''​define''​ (șirul care indică locul de definiție a unui macro). La fel, dacă ați găsit mai multe match-uri și dacă ai deschis o subfereastră cu toate match-urile (folosind '':​copen''​) și dacă sunteți în căutarea locului de definiție a unui macro, ​ este indicat să căutați în subfereastră (folosind ''/''​ -- //slash//) după șirul ''​define''​ (șirul care indică locul de definiție a unui macro).
 +</​note>​
 +
 +<note tip>
 +Pentru mai multe detalii despre ''​cscope''​ parcurgeți [[:​so2:​laboratoare:​lab01#​cscope|secțiunea cscope din primul laborator]].
 </​note>​ </​note>​
 ==== 1. [1p] Module ==== ==== 1. [1p] Module ====
  
 Pentru a putea lucra cu modulele de kernel, vom realiza următorii pași, descriși și [[:​so2:​laboratoare:​lab02:​exercitii|mai sus în pagină]]: Pentru a putea lucra cu modulele de kernel, vom realiza următorii pași, descriși și [[:​so2:​laboratoare:​lab02:​exercitii|mai sus în pagină]]:
-  - Vom compila modulul ​de kernel. Adică vom rula, în directorul în care se găsesc sursele și fișierele de tip ''​Makefile''​ și ''​Kbuild''​ aferente modulului, comanda:<​code>​ +  - Vom genera scheletul ​de laboratorrulând ​comanda <​code ​bash>LABS=kernel_modules ​make skels</​code>​ în directorul ''​tools/labs''​. ​Această comandă copiază fișierele necesare laboratorului în directorul ​''​tools/labs/skels''​. 
-make +  - Vom compila modulele de kernel. ​
-</​code>​ +
-  - Vom copia modulul ​în directorul ​din care va fi generat sistemul de fișiere al mașinii virtuale. Adică vom folosi comanda ​''​cp <​nume-modul>​.ko ~/​so2/​qemu-so2/​fsimg/​root/​modules/''​. +
-  - Vom porni mașina virtuală. Adică vom rula, din cadrul directorului aferent mașinii virtuale (adică ​''​~/so2/​qemu-so2/''​) comanda<​code>​ +
-make +
-</​code>​+
  
-Realizați pașii ​de mai sus pentru modulul din subdirectorul ​''​1-2-test-mod/'' ​din arhiva laboratoruluiUrmăriți fișierele din subdirector. Apoi urmați pașii de mai sus pentru a porni mașina virtuală cu fișierul modul ''​hello_mod.ko''​ în sistemul de fișiere al mașinii virtuale. În cadrul mașinii virtuale, fișierul modul se găsește în directorul ''/​root/modules/''​+<note important>​ 
- +Până la rezolvarea exercițiului 3, o să primiți o eroare ​de compilare la modului ​''​3-error-mod''​. ​Puteți evita problema ​ștergând ​directorul ''​skels/kernel_modules/3-error-mod/''​.
-<note tip> +
-Parcurgeți secțiunea [[:​so2:​laboratoare:​lab02#​Compilarea modulelor de kernel|Compilarea modulelor de kernel]] din laborator.+
 </​note>​ </​note>​
  
-Apoi urmați pașii uzuali în foosirea ​unui modul de kernel:+Vom rula, în directorul ''​tools/​labs'',​ comanda <code bash>​make build</​code>​. Această comandă compilează modulele din toate exercițiile din laborator. 
 +  - Vom copia modulele compilate în mașina virtuală. Adică vom folosi comanda ''​make copy''​. 
 +  - Vom porni mașina virtuală. Adică vom rula, din cadrul directorului aferent mașinii virtuale (adică ''​~/​so2/​linux/​tools/​labs/''​) comanda<​code>​ 
 +make boot 
 +</​code>​ 
 + 
 +Ne propunem să testăm pe mașina virtuală modulul din directorul ''​1-2-test-mod/''​ din scheletul laboratorului. Urmăriți fișierele din subdirector.  
 +Urmați pașii de mai sus pentru a compila și copia modulele pe mașina virtuală, apoi testați modulul ''​hello_mod.ko''​ din directorul ''/​home/​root/​skels/​kernel_modules/​1-2-test-mod''​. 
 + 
 +Apoi urmați ​**pașii uzuali** în folosirea ​unui modul de kernel:
   - Încărcați modulul în kernel.   - Încărcați modulul în kernel.
   - Listați modulele din kernel și verificați existența modulului curent.   - Listați modulele din kernel și verificați existența modulului curent.
Line 104: Line 161:
  
 <note tip> <note tip>
-Parcurgeți secțiunea [[:​so2:​laboratoare:​lab02#​Încărcarea/​descarcarea unui modul de kernel|Încărcarea/​descarcarea unui modul de kernel]] din laborator.+Parcurgeți secțiunea [[:​so2:​laboratoare:​lab02:exercitii#Testarea modulelor|Testarea modulelor]].
  
 La descărcarea unui modul din kernel poate fi precizat doar numele modulului (fără extensie). La descărcarea unui modul din kernel poate fi precizat doar numele modulului (fără extensie).
 </​note>​ </​note>​
- 
-Este indicat să facem curat în locul în care am lucrat. Pentru aceasta, pe mașina fizică, în subdirectorul ''​1-2-test-mod/''​ în care ați compilat sursele modulului, pentru a curăța directorul rulați comanda<​code>​ 
-make clean 
-</​code>​ 
  
 ==== 2. [1p] Printk ==== ==== 2. [1p] Printk ====
Line 122: Line 175:
 Citiți secțiunea [[:​so2:​laboratoare:​lab02#​Printk Debugging|Printk Debugging]] din laborator și urmăriți precizările referitoare la folosirea funcției ''​printk''​. Citiți secțiunea [[:​so2:​laboratoare:​lab02#​Printk Debugging|Printk Debugging]] din laborator și urmăriți precizările referitoare la folosirea funcției ''​printk''​.
  
-Pentru aceasta va trebui să editați opțiunile de bootare din fișierul ''/​home/​student/​so2/qemu-so2/​Makefile'',​ și să adăugați opțiunea de boot ''​ignore_loglevel''​ pe linia care începe cu ''​%%append root...%%''​+Pentru aceasta va trebui să editați opțiunile de bootare din fișierul ''​tools/labs/​qemu/​Makefile'',​ și să adăugați opțiunea de boot ''​ignore_loglevel''​ pe linia care începe cu ''​%%append root...%%''​
 </​note>​ </​note>​
  
-Compilați modulul. Încărcați și apoi descărcați modulul din kernel. Mesajele sunt afișate la consola mașinii virtuale. Dacă ați deschis pseudo-terminalul indicat de qemu (pentru ''​char device redirected to /dev/pts/19 (label virtiocon0)''​ folosiți ''​minicom -D /​dev/​pts/​19''​) atunci ​veti observa mesajele și acolo. ​+Compilați modulul. Încărcați și apoi descărcați modulul din kernel. Mesajele sunt afișate la consola mașinii virtuale. Dacă ați deschis pseudo-terminalul indicat de qemu (pentru ''​char device redirected to /dev/pts/19 (label virtiocon0)''​ folosiți ''​minicom -D /dev/pts/19''​) sau, mai simplu, link-ul simbolic ''​serial.pts''​ (folosiți ''​minicom -D serial.pts''​) atunci ​veți observa mesajele și acolo. ​
 ==== 3. [1p] Error ==== ==== 3. [1p] Error ====
-  ​+  
 +<note important>​ 
 +Dacă ați șters directorul ''​3-error-mod/''​ pentru a evita eroarea de compilare, puteți genera doar scheletul pentru acest exercițiu folosind urmăroarea comandă: <code bash>​LABS=kernel_modules/​3-error-mod make skels</​code>​ 
 +</​note>​ 
 Intrați în directorul ''​3-error-mod/''​. Obțineți modulul de kernel asociat. De ce au apărut erori de compilare? **Hint**: Cu ce diferă acest modul de modulul precedent? ​ Intrați în directorul ''​3-error-mod/''​. Obțineți modulul de kernel asociat. De ce au apărut erori de compilare? **Hint**: Cu ce diferă acest modul de modulul precedent? ​
  
Line 136: Line 193:
 Intrați în directorul ''​4-multi-mod/''​. Inspectați fișierele sursă C: ''​mod1.c''​ și ''​mod2.c''​. Exemplul este unul academic (modulul 2 conține doar definiția unei funcții folosite de modulul 1). Intrați în directorul ''​4-multi-mod/''​. Inspectați fișierele sursă C: ''​mod1.c''​ și ''​mod2.c''​. Exemplul este unul academic (modulul 2 conține doar definiția unei funcții folosite de modulul 1).
  
-Creați un fișier Kbuild ​care să conducă la crearea fișierului-modul ''​multi_mod.ko''​ pornind de la cele două fișiere sursă C. **Hint**: Citiți secțiunea [[:​so2:​laboratoare:​lab02#​Compilarea modulelor de kernel|Compilarea modulelor de kernel]] din laborator.+Modificați fișierul ''​Kbuild''​ astfel încât ​să conducă la crearea fișierului-modul ''​multi_mod.ko''​ pornind de la cele două fișiere sursă C. **Hint**: Citiți secțiunea [[:​so2:​laboratoare:​lab02#​Compilarea modulelor de kernel|Compilarea modulelor de kernel]] din laborator.
  
 Compilați, încărcați și descărcați modulul. Mesajele sunt afișate corespunzător la consolă. Compilați, încărcați și descărcați modulul. Mesajele sunt afișate corespunzător la consolă.
Line 177: Line 234:
 ==== 7. [1.5p] Proc Info ==== ==== 7. [1.5p] Proc Info ====
  
-Intrați în directorul ''​7-list-proc/''​. ​Creați un modul care să afișeze informații despre procesul curent. Numele modulului trebuie ​sa fie ''​list_proc.ko''​.+Intrați în directorul ''​7-list-proc/''​. ​Completați modulul astfel încât ​să afișeze informații despre procesul curent. Numele modulului trebuie ​rezultat este ''​list_proc.ko''​.
  
-Afișați process ID-ul (PID-ul procesului) și numele executabilului. Informațiile vor fi afișate atât la încărcarea cât și la descărcarea modulului.+Urmăriți comentariile marcate cu ''​TODO''​. ​Afișați process ID-ul (PID-ul procesului) și numele executabilului. Informațiile vor fi afișate atât la încărcarea cât și la descărcarea modulului.
  
 <note tip> <note tip>
-Nu începeți de la zero. Copiați fișierele ''​Makefile''​ și ''​Kbuild''​ și fișierele sursă C din unul din directoarele anterioare și modificați-le corespnzător. 
-  
 În kernel-ul Linux un proces este descris de structura [[http://​lxr.free-electrons.com/​source/​include/​linux/​sched.h?​v=3.13#​L1042|struct task_struct]]. În kernel-ul Linux un proces este descris de structura [[http://​lxr.free-electrons.com/​source/​include/​linux/​sched.h?​v=3.13#​L1042|struct task_struct]].
  
-Folositi [[http://​lxr.free-electrons.com/|LXR]] sau ''​cscope''​ pentru a afla conținutul unei structuri din nucleu (în cazul de față ''​struct task_struct''​).+Folositi [[http://​lxr.bootlin.com/|LXR]] sau ''​cscope''​ pentru a afla conținutul unei structuri din nucleu (în cazul de față ''​struct task_struct''​).
  
 Pentru a găsi câmpul structurii ce conține numele executabilului aferent, căutați șirul //​executable//​. Pentru a găsi câmpul structurii ce conține numele executabilului aferent, căutați șirul //​executable//​.
Line 198: Line 253:
  
 Repetați apoi operația de încărcare/​descărcare. Observați că diferă PID-urile proceselor afișate. Acest lucru se întâmplă pentru că la încărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​insmod''​ iar la descărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​rmmod''​. Procesele vor fi diferite. Repetați apoi operația de încărcare/​descărcare. Observați că diferă PID-urile proceselor afișate. Acest lucru se întâmplă pentru că la încărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​insmod''​ iar la descărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​rmmod''​. Procesele vor fi diferite.
-==== 8. [2.5p] Kprobes ==== 
- 
-**[0.5p]** Intrați în directorul ''​8-kprobes/''​ din arhiva de resurse a laboratorului. Urmăriți fișierul sursă ''​kprobes.c''​. Modulul folosește ''​jprobes''​ pentru a urmări apelul ''​do_execve_common'',​ aferent apelului de sistem [[http://​man7.org/​linux/​man-pages/​man3/​exec.3.html|exec]]. 
- 
-Compilați și încărcați în mașina virtuală modulul de kernel rezultat (''​kprobes.c''​). Urmăriți mesajele de debug și comparați cu procesele existente în sistem. 
- 
-<​note>​ 
-Este chiar exmplul din laborator din secțiunea [[:​so2:​laboratoare:​lab02#​Kprobes|Kprobes]]. 
-</​note>​ 
- 
-**[2p]** Creați un modul care analizează valoarea de retur a funcției [[http://​lxr.free-electrons.com/​source/​kernel/​fork.c?​v=4.9#​L1904|_do_fork]]. La întoarcerea din funcție, afișați valoarea de retur, numele și pid-ul procesului părinte și pid-ul procesului curent. 
- 
-<note tip> 
-Revedeți secțiunea [[:​so2:​laboratoare:​lab02#​Kprobes|Kretprobes]]. 
- 
-Puteți urmări și exemplul de cod din sursele nucleului din [[https://​git.kernel.org/​cgit/​linux/​kernel/​git/​torvalds/​linux.git/​tree/​samples/​kprobes/​kretprobe_example.c?​h=v3.13|samples/​kprobes/​kretprobe_example.c]]. 
-</​note>​ 
- 
-<note tip> 
-Urmăriți comentariile marcate cu ''​TODO''​ din cadrul fișierului cod sursă ''​kprobes.c''​. 
-</​note>​ 
- 
-<note tip> 
-Pentru a afișa adresa de retur în handler-ul de ''​kretprobe''​ (adică în funcțion ''​my_ret_handler''​) folosiți funcția [[http://​lxr.free-electrons.com/​source/​arch/​x86/​include/​asm/​ptrace.h?​v=3.13#​L82|regs_return_value]]. 
-</​note>​ 
- 
-<note tip> 
-Pentru a obține structura de tip ''​struct task_struct *''​ aferentă procesului părinte al procesului curent folosiți construcția ''​%%current->​parent%%''​. 
-</​note>​ 
- 
-<​note>​ 
-Procesul interceptat de ''​kretprobe''​ este shell-ul. În mașina virtuală procesul său părinte este procesul ''​init''/''​busybox''​ (cu PID-ul ''​1''​). Valoarea întoarsă de apelul [[http://​lxr.free-electrons.com/​source/​kernel/​fork.c?​v=4.9#​L1904|_do_fork]] afișată în cadrul handler-ului ''​kretprobe''​ este PID-ul procesului copil proaspăt creat, așa cum se întâmplă și în user space în cazul apelului [[http://​man7.org/​linux/​man-pages/​man2/​fork.2.html|fork]] pentru procesul părinte. ​ 
-</​note>​ 
  
-Puteți folosi comanda ''​pstree -p''​ pentru a afișa ierarhia de procese a sistemului și pentru a verifica astfel, informațiile afișate de handler-ul de ''​kretprobe''​ în modulul de kernel. Puteți, deasemenea, confirma acest lucru verificând pid-ul procesului din proba anterioară ( ''​do_execveat_common''​). +==== Extra ====
-==== Extra: Pentru acasă ​====+
  
 **1. [1KP] KDB** **1. [1KP] KDB**
  
-Intrați în directorul ''​9-kdb/''​. Activați KDB peste serială și intrați în modul KDB folosind SysRq.+Intrați în directorul ''​8-kdb/''​. Activați KDB peste serială și intrați în modul KDB folosind SysRq.
  
-Conectațivă la pseudo-terminalul conectat la virtiocon0 folosind minicom, configurați KDB pentru a folosi portul serial hvc0 (''​echo hvc0 > /​sys/​module/​kgdboc/​parameters/​kgdboc''​) și activați-l folosind SysRq (Ctrl+O g). Analizați starea curentă a sistemului (''​help''​ pentru a vedea comenzile KDB disponibile). Continuați execuția kernelului folosind comand ''​go''​.+Conectați-vă la pseudo-terminalul conectat la virtiocon0 folosind minicom, configurați KDB pentru a folosi portul serial hvc0 (''​echo hvc0 > /​sys/​module/​kgdboc/​parameters/​kgdboc''​) și activați-l folosind SysRq (Ctrl+O g). Analizați starea curentă a sistemului (''​help''​ pentru a vedea comenzile KDB disponibile). Continuați execuția kernelului folosind comand ''​go''​.
  
 Inserați modulul ''​hello_kdb''​. Modulul va simula un bug la scrierea în fișierul ''/​proc/​hello_kdb_bug''​. Pentru a simula un bug folosiți comanda de mai jos: <code bash> Inserați modulul ''​hello_kdb''​. Modulul va simula un bug la scrierea în fișierul ''/​proc/​hello_kdb_bug''​. Pentru a simula un bug folosiți comanda de mai jos: <code bash>
Line 246: Line 267:
 Analizați stacktrace-ul și determinați codul care a generat bugul. Cum putem afla din KDB adresa la care a fost încărcat modulul? Analizați stacktrace-ul și determinați codul care a generat bugul. Cum putem afla din KDB adresa la care a fost încărcat modulul?
  
-În paralel, folosiți GDB într-o nouă fereastră pentru a vizualiza codul pornind de la informațiile din KDB. ** Hint: ** Încărcați fișierul de simboluri. Folosiți ''​info line''​. ​+În paralel, folosiți GDB într-o nouă fereastră pentru a vizualiza codul pornind de la informațiile din KDB. 
 +** Hint: ** Încărcați fișierul de simboluri. Folosiți ''​info line''​. ​
  
 La scrierea în fișierul ''/​proc/​hello_kdb_break'',​ modulul va incrementa variabila ''​kdb_write_address''​. Intrați în KDB și setați un breakpoint pentru fiecare acces de scriere al variabilei ''​kdb_write_address''​. Reveniți în kernel pentru a declanșa o scriere folosind: <code bash> echo 1 > /​proc/​hello_kdb_break </​code>​ La scrierea în fișierul ''/​proc/​hello_kdb_break'',​ modulul va incrementa variabila ''​kdb_write_address''​. Intrați în KDB și setați un breakpoint pentru fiecare acces de scriere al variabilei ''​kdb_write_address''​. Reveniți în kernel pentru a declanșa o scriere folosind: <code bash> echo 1 > /​proc/​hello_kdb_break </​code>​
Line 269: Line 291:
 Porniți de la un modul existent. Porniți de la un modul existent.
  
-Investigați structura [[http://lxr.free-electrons.com/​source/​include/​linux/​sched.h?v=3.13#L1042|struct task_struct]],​ structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L344|struct mm_struct]] și structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L240|struct vm_area_struct]]. O zonă de memorie este indicată de o structură de tipul +Investigați structura [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​sched.h#​L520|struct task_struct]],​ structura [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​mm_types.h#​L356|struct mm_struct]] și structura [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​mm_types.h#​L274|struct vm_area_struct]]. O zonă de memorie este indicată de o structură de tipul [[https://​elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​mm_types.h#​L274|struct vm_area_struct]].
  
 Să includeți header-ele în care sunt definite structurile necesare. Să includeți header-ele în care sunt definite structurile necesare.
Line 276: Line 298:
 **4. [2KP] Dynamic Debugging** **4. [2KP] Dynamic Debugging**
  
-Intrați în directorul ''​10-dyndbg/''​ și compilați modulul ''​dyndbg.ko''​.+Intrați în directorul ''​9-dyndbg/''​ și compilați modulul ''​dyndbg.ko''​.
  
 Familiarizați-vă cu sistemul de fișiere ''​debugfs''​ montat în ''/​debug''​ și analizați conținutul fișierului ''/​debug/​dynamic_debug/​control''​. Inserați modulul dyndbg.ko și observați noul conținut al fișierului ''​dynamic_debug/​control''​. Familiarizați-vă cu sistemul de fișiere ''​debugfs''​ montat în ''/​debug''​ și analizați conținutul fișierului ''/​debug/​dynamic_debug/​control''​. Inserați modulul dyndbg.ko și observați noul conținut al fișierului ''​dynamic_debug/​control''​.
so2/laboratoare/lab02/exercitii.1488467585.txt.gz · Last modified: 2017/03/02 17:13 by george.muraru
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