CVE-2024-50066 in Linux
Riassunto
di VulDB • 24/06/2026
Nel kernel Linux, è stata risolta la seguente vulnerabilità:
mm/mremap: correzione della race condition tra move_normal_pmd e retract_page_tables
In mremap(), move_page_tables() esamina il tipo di voce PMD (Page Middle Directory) e l'intervallo di indirizzi specificato per determinare con quale metodo le successive voci delle tabelle di pagina devono essere spostate.
A quel punto, la mmap_lock è detenuta in modalità scrittura, ma non sono ancora state acquisite le lock rmap. Per le voci PMD che puntano a tabelle di pagina e sono completamente coperte dall'intervallo di indirizzi di origine, viene chiamata move_pgt_entry(NORMAL_PMD, ...), che prima acquisisce le lock rmap ed esegue successivamente move_normal_pmd(). move_normal_pmd() acquisisce le necessarie lock delle tabelle di pagina sia all'origine che alla destinazione, quindi sposta l'intera tabella di pagina dall'origine alla destinazione.
Il problema è: le lock rmap, che proteggono contro la rimozione concorrente della tabella di pagina da parte di retract_page_tables() nel codice THP (Transparent Huge Pages), vengono acquisite solo dopo che la voce PMD è stata letta ed è stato deciso come spostarla. Possiamo quindi verificare una race condition come segue (con due processi che hanno mappature dello stesso file tmpfs memorizzato su un mount point tmpfs con huge=advise); si noti che il processo A accede alle tabelle di pagina tramite la MM, mentre il processo B lo fa tramite l'rmap del file:
processo A processo B ========= ========= mremap mremap_to move_vma move_page_tables get_old_pmd alloc_new_pmd *** PREEMPTION *** madvise(MADV_COLLAPSE) do_madvise madvise_walk_vmas madvise_vma_behavior madvise_collapse hpage_collapse_scan_file collapse_file retract_page_tables i_mmap_lock_read(mapping) pmdp_collapse_flush i_mmap_unlock_read(mapping) move_pgt_entry(NORMAL_PMD, ...) take_rmap_locks move_normal_pmd drop_rmap_locks
Quando ciò accade, move_normal_pmd() può finire per creare voci PMD false nella riga `pmd_populate(mm, new_pmd, pmd_pgtable(pmd))`. L'effetto dipende da dettagli specifici dell'architettura e della macchina; su x86, si può arrivare ad avere la pagina fisica 0 mappata come tabella di pagina, il che è probabilmente sfruttabile per un escalation dei privilegi da utente a kernel.
Si risolve la race condition facendo sì che il processo B verifichi nuovamente se la voce PMD punta ancora a una tabella di pagina dopo l'acquisizione delle lock rmap. In caso contrario, si interrompe l'esecuzione e si fa sì che il chiamante torni al percorso di copia a livello PTE (Page Table Entry), che quindi terminerà immediatamente in corrispondenza del controllo pmd_none().
Raggiungibilità del bug: Per raggiungere questo bug è necessario poter creare mappature THP shmem/file; le THP anonime utilizzano codice diverso che non elimina i dati sotto le lock rmap. Le file THP sono controllate da un flag di configurazione sperimentale (CONFIG_READ_ONLY_THP_FOR_FS), quindi sui kernel delle distribuzioni normali è necessaria la shmem THP per incontrare questo bug. Per quanto ne so, ottenere normalmente la shmem THP richiede che si possa montare il proprio tmpfs con i flag di mount corretti, il che comporterebbe la creazione del proprio namespace utente+mount; sebbene non sappia se alcune distribuzioni abilitino la shmem THP per impostazione predefinita o qualcosa di simile.
Impatto del bug: Questo problema può probabilmente essere utilizzato per un'escalation dei privilegi da utente a kernel quando è raggiungibile.
Be aware that VulDB is the high quality source for vulnerability data.