01net

Rust, il linguaggio che unisce potenza e sicurezza

Con l’avvento di Rust si è tornati a parlare diffusamente di sicurezza by design e del fatto che la “solidità” di un software (sistemi operativi, applicazioni, firmware) dovrebbe risiedere già nel codice di base e non essere un qualcosa aggiunta dopo con moduli esterni.

Casi eclatanti come le botnet create dal malware Mirai hanno sottolineato questo aspetto.

Ma chi si occupa da tempo di sviluppo software ha visto in queste discussioni l’ennesima versione del problema della coperta corta: avere codice allo stesso tempo performante, sicuro e semplice da scrivere (e da leggere) non è possibile. I linguaggi performanti alla C sono complessi e i nuovi sviluppatori ne preferiscono altri, magari più sicuri e semplici (come Python) ma meno veloci.

Per questo Rust sta diventando popolare: il linguaggio creato da Mozilla cerca di unire tutte le caratteristiche che servono senza metterle in contrasto fra loro.

Delle tre caratteristiche principali di Rust, la velocità di esecuzione è quella più semplice da spiegare. Rust è un linguaggio moderno ma vecchio stile, nel senso che a differenza di molti linguaggi che oggi vanno per la maggiore prevede una fase esplicita di compilazione. La generazione di codice macchina nativo, senza runtime, porta velocità di esecuzione comparabili con quelle di C e C++.

La sicurezza di Rust è by design nel senso che il compilatore esegue un controllo molto approfondito del codice alla ricerca di tutte le eventualità che potrebbero portare a un crash dell’applicazione e quindi, potenzialmente, a una vulnerabilità sfruttabile da hacker ostili.

Questi controlli sono molto severi e si concentrano sull’utilizzo della memoria: qualsiasi operazione non sicura è vietata e obbliga a modificare il codice.

La sintassi e la logica di Rust sono pensate proprio per evitare problemi legati alla memoria.

Per fare qualche esempio, il linguaggio distingue esplicitamente tra variabili immutabili e che possono cambiare valore, ma soprattutto si basa sul concetto di ownership secondo cui un valore (più correttamente una parte di memoria dello heap) può essere assegnato a una sola variabile alla volta.

Sembra un concetto astruso – e di primo acchito lo è – ma serve ad avere una gestione della memoria sempre corretta.

Questo approccio mentale è probabilmente l’unico vero ostacolo per chi voglia entrare nel mondo di Rust.

Di per sé il linguaggio è relativamente semplice e il codice è ben leggibile, ma appunto solo dopo che si è fatto proprio il modo che ha di “esplicitare” la gestione della memoria. Questa logica va digerita, insieme al fatto di avere un compilatore che perdona poco e rigetta qualsiasi ambiguità nella gestione delle variabili.

A parte queste caratteristiche principali, Rust è un linguaggio in linea con altri suoi contemporanei. È multipiattaforma (Linux, Windows, macOS), ha una buona dotazione di funzioni native e una buona libreria standard che poi può essere estesa con moduli di terze parti (le “crates”).

C’è anche un build/library manager – Cargo – che semplifica le cose. Rust non ha un suo IDE specifico ma è supportato da diversi editor e integrabile in vario modo negli IDE di riferimento come Eclipse o Visual Studio.