microsoft / microsoft/mimalloc

Potential security issues in mimalloc-secure

Aperta
#372 8 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Lingua principale
C
Stelle
13.4k
Fork
1.2k
Merge medio
4g 45m
PR unite (30g)
13

Descrizione

Hi! @ironore15 and I are working for research on secure allocators.

During research, we have found several potential security issues in mimalloc-secure mode.
We want to get your feedback regarding these issue.s

  • Metadata leakage

We found that metadata can be leaked even in secure mode.

Here is the proof of concept code.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    void *p1 = malloc(32);  // prevent calling mi_segment_free
    void *p2 = malloc(64);  // page with xblock_size = 64
    free(p2);  // calling _mi_page_retire
    void *p3 = malloc(-8);  // trigger mi_heap_collect with MI_FORCE
    void *p4 = malloc(128);  // alloc page with same page_area
    fprintf(stderr, "%p\n", ((void **)p4)[8]);
}

If we run the code in Ubuntu 18.04, it shows like this.

$ LD_PRELOAD=./libmimalloc-secure.so ./test
0x41cb4a160092279d

As you can see, ((void **)p4)[8] contains encoded metadata of mimalloc heap.
We believe that it breaks your attempt to remove internal data in secure mode.

It happens because _mi_page_free doesn't remove metadata of free_list. In the above PoC, when we call malloc(-8), which is huge page, mimalloc calls _mi_page_free to reclaim used pages. A page with xblock_size=64 from p2 is also one of reclaimed pages. Then, the next malloc(128) will reuse the previous page, which contains an encoded free_list.

I think one way to fix this issue is that we can zero-out page in secure mode.

  • Heap spray

In mimalloc-secure mode, an attacker can allocate a fixed memory address and bypass ASLR.
Here is PoC code.

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    void *p = malloc(0x40000000000);
    *(int *)0x7FFFFFFF000 = 0;
    return 0;
}

This always exit successfully without segmentation fault.

It happens because eager commit option and mmap with aligned hint address. When segment is initially allocated, it calls _mi_mem_alloc_aligned. On UNIX system, it internally calls mi_unix_mmapx with addr is NULL, and mi_os_get_aligned_hint to get address for segment. In the following the code, (1 << 42) ~ (1 << 43) are only valid segment address. Since Eager commit is enabled default, very large allocation, e.g., malloc(1 << 42), will always alloc memory address between 0x7FFFFFFF000 ~ 0x80000000000.

We believe that one easy way to mitigate this is to disable eager commit in secure mode.
But I am not sure that it fits with mimalloc's design descision.

Best,
Insu Yun

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo le PoC in C fornite sulla configurazione Ubuntu segnalata, incluso il preload sicuro della libreria. Leggi i percorsi referenziati in src/alloc.c, src/os.c e src/options.c per tracciare il recupero delle pagine, il mapping allineato e il commit eager. Il lavoro è completato quando esiste una mitigazione concordata per entrambi i comportamenti segnalati ed è stato verificato che le PoC non li dimostrino più.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c
Ambito
operating-systems, security
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.