Fil-C — un compilatore per i linguaggi C e C++, che garantisce un uso sicuro della memoria.

Filip Pizlo ha presentato alla conferenza SPLASH'24 il compilatore open source C/C++ Fil-C, che offre protezione contro i problemi causati da errori di gestione della memoria. Il progetto è mirato a garantire la piena compatibilità con il codice esistente nei linguaggi C e C++: per assicurare un utilizzo sicuro della memoria, è sufficiente ricompilare il codice già esistente. Il compilatore è costruito utilizzando componenti del progetto LLVM ed è distribuito con la licenza Apache 2.0. Il runtime è fornito con licenza BSD. A differenza del recentemente annunciato progetto TrapC, che è ancora in fase di progettazione, il compilatore Fil-C è già pronto per la costruzione del codice esistente.

Il progetto include anche varianti delle librerie standard C (libc) e C++ (libc++) che funzionano in sicurezza con la memoria, basate sulle librerie Musl e LLVM libc++. Tra l'altro, nei programmi compilati possono essere utilizzate funzionalità come il multithreading, la gestione dei segnali, il mapping dei file in memoria (mmap), longjmp/setjmp e la gestione delle eccezioni in C++. Utilizzando Fil-C, è possibile compilare progetti come bzip2, zip, pcre e ncurses senza modifiche. Con lievi modifiche è supportata la compilazione di OpenSSH, OpenSSL, CPython, SQLite, Lua, Curl, Lynx, jpeg6b, zsh, xzutils e simdutf.

La protezione contro i problemi di memoria è garantita grazie all'uso di puntatori MonoCaps a 128 bit con metadati per il controllo dei tipi e il monitoraggio dei confini dei buffer, oltre all'implementazione di un garbage collector FUGC, che gestisce tutte le operazioni di allocazione e liberazione della memoria. In caso di errori nella gestione della memoria, l'applicazione si arresta immediatamente, impedendo l'esploatazione di potenziali vulnerabilità.

Si afferma che la combinazione di MonoCaps e FUGC consente di rilevare e bloccare tutti gli errori legati all'overflow del buffer nello stack e nell'heap, all'accesso alla memoria già liberata, alle condizioni di gara nell'uso dei puntatori, nonché a una gestione errata dei tipi (Type Confusion) nel contesto dell'incrocio tra puntatori e non puntatori, problemi nella composizione dinamica (linking) e uso scorretto di va_lists. Inoltre, Fil-C verifica separatamente i limiti e i tipi nei buffer trasmessi alle chiamate di sistema.

Il prezzo da pagare per l'utilizzo di Fil-C per proteggere i progetti esistenti, senza la necessità di riscrivere il loro codice o di impiegare costrutti linguistici speciali, è una riduzione delle prestazioni. In questa fase di sviluppo, i programmi compilati in Fil-C sono più lenti di circa 1,5-5 volte rispetto ai compilatori tradizionali. Sono previsti lavori di ottimizzazione. Si stima che, al termine di questa fase, il codice sarà eseguito più lentamente di 1,2 volte nella maggior parte dei casi, mentre nei peggiori scenari il rallentamento non supererà una volta e mezzo. Attualmente, il compilatore supporta solo la piattaforma Linux su sistemi X86_64. Le versioni precedenti supportavano macOS e FreeBSD, ma è stato deciso di non disperdere gli sforzi e preparare all'inizio un porting di qualità della libc per una sola piattaforma.

Un'altra limitazione di Fil-C è il principio di rifiuto della compatibilità a livello ABI per il codice C/C++, che impedisce di collegare il codice compilato in Fil-C con librerie e file oggetto compilati con altri compilatori. I metodi di chiamata delle funzioni e il modo di collegamento dinamico in Fil-C sono diversi da quelli degli attuali compilatori e linker. Questa decisione è motivata dal fatto che collegare codice non protetto vanificherebbe il concetto di protezione offerto da Fil-C, creando l'illusione di un'applicazione sicura: con la compatibilità ABI, gli sviluppatori avrebbero la tentazione di assemblare in Fil-C solo singoli file, senza doversi impegnare a portare l'intero progetto.

Il meccanismo MonoCap utilizzato in Fil-C si basa sull'applicazione di puntatori a 16 byte, nei quali, oltre all'indirizzo in memoria, è contenuto un riferimento a un oggetto che include informazioni sulle capacità, come i limiti superiori e inferiori del buffer associato al puntatore, e un array che definisce i tipi di dati memorizzati in ciascun blocco di memoria (1 byte con informazioni sul tipo (unset, int, ptr, free) per ogni blocco di memoria da 16 byte). Ad ogni accesso alla memoria tramite puntatore, viene effettuato un controllo dei limiti e del tipo (ad esempio, non possono essere scritti dati di tipo 'int' in una memoria di tipo 'ptr' e viceversa).

Tutte le operazioni di allocazione e liberazione della memoria vengono gestite dal Garbage Collector FUGC (Fil’s Unbelievable Garbage Collector), il quale, al momento della liberazione della memoria, imposta tutte le registrazioni dei tipi associati al buffer liberato sul valore "free" e poi reindirizza tutti i puntatori agli oggetti liberati su un oggetto separato che segnala che la memoria è già stata liberata. Qualsiasi ulteriore accesso a un blocco di dati con tipo "free" o tramite un puntatore associato a un oggetto liberato genera un'eccezione, proteggendo così da vulnerabilità di tipo use-after-free. Il Garbage Collector funziona in parallelo e non sospende l'esecuzione di altri thread.

L'uso della combinazione di MonoCaps e FUGC consente di mantenere la consueta gestione dei puntatori e di preservare la semantica delle chiamate a malloc e free, offrendo al contempo una protezione garantita. Il codice del programma può contenere vari errori logici, come cast di tipo errati, operazioni aritmetiche sbagliate con puntatori, condizioni di competizione e chiamate intempestive alla funzione free(), ma indipendentemente da tutto ciò, Fil-C ricorderà i confini originali e il tipo di dato, e interromperà l'esecuzione se si tenta di accedere tramite puntatore a un'area al di fuori dei confini memorizzati, di accedere a un blocco di memoria liberato o di leggere dati di tipo 'int' come puntatore e viceversa.

L'autore Fil-C, Filip Pizlo, ricopre in Epic Games il ruolo di direttore responsabile dei progetti legati ai linguaggi di programmazione. Filippo ha una vasta esperienza nello sviluppo di macchine virtuali, linguaggi di programmazione, compilatori e garbage collector. Ad esempio, presso IBM ha sviluppato il linguaggio di programmazione X10, presso Microsoft ha lavorato sui garbage collector Stopless, Clover e Chicken, mentre in Apple si è occupato del compilatore JIT e delle ottimizzazioni del motore di rendering del browser WebKit. In Epic Games guida il team di sviluppatori che sta sviluppando il linguaggio di programmazione Verse e la relativa macchina virtuale. Filippo è anche uno dei principali sviluppatori di macchine virtuali Jikes RVM, Ovm e Fiji VM.

Riproduci video


Fonte: opennet.ru
Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster