I ricercatori del team Google Project Zero hanno pubblicato un metodo per sfruttare una vulnerabilità (CVE-2020-29661) nell'implementazione del gestore ioctl TIOCSPGRP del sottosistema tty del kernel Linux e hanno esaminato in dettaglio i meccanismi di protezione che potrebbero bloccare tali vulnerabilità.
L'errore che causava il problema è stato corretto nel kernel Linux il 3 dicembre dell'anno scorso. Il problema si manifesta nei kernel fino alla versione 5.9.13, ma la maggior parte delle distribuzioni ha risolto la questione negli aggiornamenti dei pacchetti kernel proposti già l'anno scorso (Debian, RHEL, SUSE, Ubuntu, Fedora, Arch). Una vulnerabilità simile (CVE-2020-29660) è stata individuata contemporaneamente nell'implementazione della chiamata ioctl TIOCGSID, ma è già stata ampiamente corretta.
Il problema è causato da un errore nell'impostazione dei lock, che porta a una condizione di race nel codice drivers/tty/tty_jobctrl.c, che è stato sfruttato per creare condizioni di accesso alla memoria dopo la sua liberazione (use-after-free), sfruttabile dallo spazio utente attraverso la manipolazione della chiamata ioctl TIOCSPGRP. È stato dimostrato un exploit funzionante per l'innalzamento dei privilegi in Debian 10 con kernel 4.19.0-13-amd64.
Nell'articolo pubblicato, l'accento non è tanto posto sulla tecnica di creazione di un exploit funzionante, quanto sugli strumenti nel kernel esistenti per proteggere contro tali vulnerabilità. La conclusione non è confortante: metodi come la segmentazione della memoria nella heap e il controllo degli accessi alla memoria dopo la sua liberazione non vengono applicati nella pratica, poiché comportano una riduzione delle prestazioni, e la protezione basata su CFI (Control Flow Integrity), che blocca gli exploit nelle fasi avanzate dell'attacco, richiede ulteriori sviluppi.
Nel considerare cosa potrebbe cambiare la situazione nel lungo termine, si evidenzia l'applicazione di analizzatori statici avanzati o l'uso di linguaggi che garantiscono un lavoro sicuro con la memoria, come Rust e i dialetti del linguaggio C con annotazioni avanzate (ad esempio, Checked C), per controllare lo stato dei blocchi, degli oggetti e dei puntatori durante la fase di compilazione. Tra i metodi di protezione si menziona anche l'attivazione della modalità panic_on_oops, la conversione delle strutture del kernel in modalità di sola lettura e la limitazione dell'accesso alle chiamate di sistema tramite meccanismi come seccomp.
Fonte: opennet.ru
