DirtyCOW: bug del kernel di 11 anni

by Marco Bonfiglio on

Il ciclo di sviluppo del kernel è continuo, e la maggior parte dello sforzo riguarda la correzione degli errori; sapendo questo, è strano scoprire che settimana scorsa è stato sistemato un bug presente da ben 11 anni.

Cominciamo spiegando di cosa si stratta: il bug CVE-2016-5195, ribattezzato per comodità in DirtyCOW, permette ad un utente di eseguire codice come fosse root; il nome viene dalla funzionalità del kernel COW (Copy On Write): se due programmi fanno riferimento agli stessi dati, questi non sono copiati finché uno dei due non modifica i dati stessi. In questa maniera non si perde tempo a copiare inutilmente dati nel caso debbano essere solo letti gli stessi.
Come molti bachi il processo sfrutta una errata gestione della memoria e non è immediatamente sfruttabile, ma basti dire che con un paio di processi è possibile cambiare il contenuto di qualsiasi file del computer, anche quelli del sistema operativo. Se interessa una spiegazione più tecnica e precisa rimando al thread di bugzilla di Red Hat.

La parte ironica del bug non è tanto la sua permanenza nel kernel, ma il fatto che Linus Torvalds l'avesse già risolto 11 anni fa, ma non avesse potuto applicare la soluzione perché non valida per i sistem s390 (i server mainframe di IBM, usati nelle grande aziende), come scrive lui stesso nella mailing list:

This is an ancient bug that was actually attempted to be fixed once (badly) by me eleven years ago in commit 4ceb5db9757a ("Fix get_user_pages() race for write access") but that was then undone due to problems on s390 by commit f33ea7f404e5 ("fix get_user_pages bug").

In the meantime, the s390 situation has long been fixed, and we can now fix it by checking the pte_dirty() bit properly (and do it better). The s390 dirty bit was implemented in abf09bed3cce ("s390/mm: implement software dirty bits") which made it into v3.9.

Questo è un vecchio bug che è stato in effetti  tentato di correggere (malamente) da me 11 anni fa nel commit 4ceb5db9757a ("Fix get_user_pages() race for write access"), ma che allora non fu applicato per problemi su s390 del commit f33ea7f404e5 ("fix get_user_pages bug").

Intanto, la situzione s390 è stata da tempo risolta, e ora possiamo correggerlo facendo il check (e farlo meglio) del bit pte_dirty(). Il bit sporco dell's390 è stato introdotto nel [commit] abf09bed3cce ("s390/mm: implement software dirty bits") che è incluso nel [kernel] v3.9.

Ma se la soluzione era pronta ed applicabile da tanto tempo, perché farlo subito? Semplicemente perché era ritenuto un bug sfruttabile solo in principio: infatti servono almeno due processi attivi nello stesso istante perché sia innescata un condizione di race, ovvero di accesso simultaneo alle stesse risorse.

Also, the VM has become more scalable, and what used a purely theoretical race back then has become easier to trigger.

Inoltre, la VM è diventata più scalabile, e quello che è sempre stato un race puramente teorico allora adesso è diventato più facile da scatenare.

Per avere attivi assieme due processi, è necessario che la macchina abbia due CPU (o come minimo la CPU supporti due thread, come l'Hyper-Threading di Intel) che 11 anni fa non erano tanto diffuse, nonché che il kernel possa trarne vantaggio.

Come sempre, in breve tempo sarà disponibile un aggiornamento del kernel per la vostra distribuzione: aggiornate presto, aggiornate spesso!

Font: https://nakedsecurity.sophos.com/2016/10/21/linux-kernel-bug-dirtycow-easyroot-hole-and-what-you-need-to-know/

Leggi il contenuto originale su Mia mamma usa Linux!

Written by: Marco Bonfiglio