
Sfruttamento per CVE-2021-3679 e documento per la sua correzione
Questo è un programma proof-of-concept per innescare e dimostrare un bug logico in rb_per_cpu_empty. I programmi che colpiscono il bug rimarranno bloccati in un ciclo morto nello spazio kernel in tracing_read_pipe e impossibili da sospendere o terminare usando qualsiasi segnale UNIX (incluso SIGKILL).
Nonostante mostri un comportamento simile (ciclo morto & consumo di CPU) al bug del calcolo di seq_buf_used corretto in linux 4.5, questo programma serve a dimostrare l'esistenza di un altro bug che ha una causa completamente diversa e si ritiene esista nei kernel con versioni dalla 3.10 alla 5.14-rc1 (vedi anche il risultato dell'esecuzione del POC).
AVVERTENZA: questo programma proof-of-concept potrebbe bloccare il tuo linux, consumare molta energia e non può essere terminato usando segnali UNIX quando viene attivato, usalo a tuo rischio.
Questi pacchetti o comandi devono essere installati prima di eseguire lo script proof-of-concept.
gcc
realpath
nm
Anche Bash e comandi di elaborazione di stringhe come awk e grep sono richiesti, e probabilmente sono già inclusi nelle vostre distribuzioni.
Sebbene sia uno script bash, la parte di codice che specifica uprobe dipende dalla piattaforma (non possiamo usare $argN in uprobe), e supportiamo i386, x86_64, arm e aarch64. Sentiti libero di aggiungere il supporto per la tua piattaforma.
Per eseguire il proof-of-concept, basta eseguire il seguente comando con privilegi di root:
./rbdetonate

Se il bug viene innescato dal proof-of-concept, verrà generato un processo dd che consumerà un intero core della CPU, e non potrà essere ucciso usando semplicemente segnali UNIX come SIGKILL.
Il processo bash dello script rbdetonate può essere ucciso, ma l'invio del segnale SIGINT potrebbe terminarlo o meno, a seconda dell'implementazione di bash. E le versioni più recenti di bash possono essere uccise solo da SIGINT quando il processo dd generato è in esecuzione.

rbdetonate potrebbe uscire e stampare Nothing buggy has been detected se non riesce a creare il processo dd dopo diversi tentativi. Tuttavia, questo potrebbe richiedere del tempo a causa dei nostri 8192 tentativi.
Nota: in teoria questo bug esiste in tutte le versioni che hanno la funzionalità di tracing nello spazio utente (>=3.10), ma le versioni più vecchie del kernel non hanno uprobe funzionante correttamente in molti modi. Saremo grati se potrete aiutarci a correggere il suo comportamento.
R: Basta eseguire il comando
echo > /sys/kernel/debug/tracing/instances/rbdetonate/trace
con privilegi di root dovrebbe far uscire il programma dal ciclo morto.
R: No. Gli strumenti di compilazione qui usati servono solo per compilare il programma rbwrite, che produce un risultato deterministico scrivendo nelle pagine del ring buffer sulla CPU#0, secondo i passaggi progettati.
Banalmente per questo proof-of-concept, può essere usata anche una versione compilata del programma rbwrite simile al codice, e l'indirizzo del tracepoint potrebbe essere recuperato dopo.
Per usare il tracing di linux, se non vi dispiace il rumore prodotto dalle applicazioni, l'aggiunta di kprobe tracepoint a syscall e funzioni del kernel genererà anche eventi. Ma per il proof-of-concept, questo potrebbe introdurre indeterminismo e non è preferito.
| Versione | Riprodotto | Screenshot |
|---|
| 5.14.0-rc2-00479-g86020194bc7e (Versione corretta) | No | 5.14.0-rc2-00479-g86020194bc7e.png |
| 5.14.0-rc2-00478-g2734d6c1b1a0 (5.14.0-rc2) | Sì | 5.14.0-rc2-00478-g2734d6c1b1a0.png |
| 5.4.0-77-generic | Sì | 5.4.0-77-generic.png |
| 4.4.0-142-generic | Sì | 4.4.0-142-generic.png |