È stato pubblicato il rilascio del linguaggio di programmazione generale Rust 1.81, originariamente sviluppato da Mozilla e ora mantenuto sotto l'egida dell'organizzazione non profit Rust Foundation. Il linguaggio è focalizzato su un utilizzo sicuro della memoria e fornisce strumenti per raggiungere un alto parallelismo nell'esecuzione dei compiti, il tutto senza necessità di un garbage collector e runtime (il runtime si limita a una base di inizializzazione e al supporto della libreria standard).
I metodi di gestione della memoria in Rust liberano gli sviluppatori dagli errori di manipolazione dei puntatori e li proteggono da problemi derivanti da operazioni a basso livello con la memoria, come l'accesso a aree di memoria dopo il loro rilascio, la dereferenziazione di puntatori nulli, l'uscita dai limiti del buffer, ecc. Per la distribuzione delle librerie, l'assicurazione della compilazione e la gestione delle dipendenze, il progetto promuove il gestore di pacchetti Cargo. È supportato un repository per l'hosting delle librerie su crates.io.
La gestione sicura della memoria in Rust è garantita durante la compilazione attraverso il controllo dei riferimenti, il tracciamento della proprietà degli oggetti, la considerazione del tempo di vita degli oggetti (ambiti di visibilità) e la valutazione della correttezza dell'accesso alla memoria durante l'esecuzione del codice. Rust fornisce anche strumenti per proteggere da overflow interi, richiede l'inizializzazione obbligatoria delle variabili prima dell'uso, gestisce meglio gli errori nella libreria standard, applica il concetto di riferimenti e variabili immutabili per impostazione predefinita e offre una forte tipizzazione statica per minimizzare gli errori logici.
Novità principali:
- È stato stabilizzato il trait core::error::Error, che definisce le descrizioni degli errori emessi. Questa modifica consente di utilizzare un singolo trait Error in diverse librerie, indipendentemente dall'ambiente, comprese quelle non legate alla libreria standard, che utilizzano l'attributo «#![no_std]».
- Le funzioni di ordinamento stabili e instabili nella libreria standard sono state tradotte per utilizzare nuovi algoritmi, che mostrano tempi di esecuzione più rapidi e tempi di compilazione ridotti. Nella realizzazione dei nuovi algoritmi di ordinamento è stata garantita la rilevazione di trait Ord non definiti correttamente e, in tali casi, viene restituito un errore (panic) anziché dati raggruppati casualmente.
- Nel linter è stato implementato un nuovo livello di controllo «expect» («#[expect(lint)]»), che consente di verificare il rispetto del controllo e di restituire un avviso se il controllo non viene rispettato (a causa di un errore nell'implementazione o della disattivazione del controllo). Ad esempio, nella migrazione del codice alla verifica di undocumented_unsafe_blocks tramite Clippy, è possibile specificare «#[expect(clippy::undocumented_unsafe_blocks)]» per garantire che, nel corso della transizione, tutti i blocchi unsafe siano documentati. In Clippy sono state introdotte anche le verifiche clippy::allow_attributes e clippy::allow_attributes_without_reason, che semplificano la sostituzione degli attributi «#[allow]» con «#[expect(lint)]».
- È stata fornita la possibilità di documentare il motivo della sostituzione dei livelli di controllo (lint), fornendo ai nuovi sviluppatori informazioni sulle ragioni dell'aggiunta di uno specifico controllo, emesse sotto forma di messaggio del compilatore. Ad esempio: #![deny(clippy::float_arithmetic, reason = «no hardware float support»)]
- Una nuova serie di API è stata trasformata in versioni stabili, inclusi i metodi stabilizzati e le implementazioni delle trait:
- core::error
- hint::assert_unchecked
- fs::exists
- AtomicBool::fetch_not
- Duration::abs_diff
- IoSlice::advance
- IoSlice::advance_slices
- IoSliceMut::advance
- IoSliceMut::advance_slices
- PanicHookInfo
- PanicInfo::message
- PanicMessage
Il segno «const», che determina la possibilità di utilizzo in qualsiasi contesto invece delle costanti, è applicato nelle funzioni:
- char::from_u32_unchecked (funzione)
- char::from_u32_unchecked (metodo)
- CStr::count_bytes
- CStr::from_ptr
Il tipo std::panic::PanicInfo è stato rinominato in std::panic::PanicHookInfo (il funzionamento del vecchio nome è mantenuto, ma a partire dalla prossima versione il suo utilizzo genererà un avviso). Nel contempo, core::panic::PanicInfo rimarrà invariato, ma sarà sviluppato come un tipo separato. La separazione dei tipi consentirà di implementare metodi diversi specifici per l'esecuzione nel contesto di snd e no_std.
- Completata la transizione all'ABI C-unwind (‘extern «C-unwind»‘), che si differenzia dall'ABI senza il suffisso «-unwind» (‘extern «C»‘) per la conservazione del comportamento sicuro (safe), se il processo di «unwinding», avviato al termine anomalo del programma o alla generazione di un'eccezione in stile C++, attraversa il confine dell'ABI (ad esempio quando un'eccezione generata in codice su un linguaggio di programmazione tocca lo stack associato a codice su un altro linguaggio di programmazione). A partire dalla versione Rust 1.81, nell'ABI ‘extern «C»‘ viene attivato il termine anomalo durante l'unwinding non intercettato.
- Implementato un terzo livello di supporto per le piattaforme i686-unknown-redox, xtensa-esp32-none-elf, xtensa-esp32s2-none-elf, xtensa-esp32s3-none-elf, xtensa-esp32-espidf, xtensa-esp32s2-espidf, xtensa-esp32s3-espidf. Il terzo livello implica un supporto di base, ma senza test automatizzati, pubblicazione di versioni ufficiali e verifica della possibilità di compilare il codice.
- Implementato un secondo livello di supporto per le piattaforme target loongarch64-unknown-linux-musl e arm64ec-pc-windows-msvc. Il secondo livello di supporto garantisce la compilazione.
- Per i sistemi Linux sulla piattaforma LoongArch è stato fornito un completo set di strumenti e un profiler.
- Risolto il problema di sicurezza (CVE-2024-43402) in std::process::Command, che si manifesta solo sulla piattaforma Windows e risolve un bypass per l'exploit di una vulnerabilità precedentemente corretta, BatBadBut, relativa alla gestione dei caratteri speciali durante l'uso delle chiamate Command::arg e Command::args, progettate per la trasmissione diretta degli argomenti al processo, senza la loro elaborazione da parte del comando interprete. In pratica, all'esecuzione di script bat e cmd, si avviava il processo cmd.exe, dotato di una propria logica per la separazione degli argomenti. Il bypass della sicurezza si basa sul fatto che Windows rimuove gli spazi e i punti iniziali nei percorsi, quindi un file con estensione «.bat. .» viene trattato come «.bat».
Inoltre, si segnala l'uscita di Wedson Almeida Filho dal ruolo di manutentore del progetto Rust for Linux, che si occupa dell'integrazione nel kernel Linux delle risorse per lo sviluppo in linguaggio Rust. Dopo l'uscita di Wedson, il progetto ha ancora due manutentori: Miguel Ojeda, autore e sviluppatore principale del progetto Rust-for-Linux, e Alex Gaynor, ex direttore dell'organizzazione Python Software Foundation, che si è dedicato alla promozione di Rust. Il manutentore che ha lasciato il progetto, entrato nel team quattro anni fa, è un dipendente di Microsoft e autore di un driver sperimentale con implementazione del file system EXT2, scritto in Rust. Recentemente, il lavoro di Almeida si è concentrato sulla creazione di strumenti per lo sviluppo di file system in Rust. Quest'anno Almeida ha effettuato 17 commit nel repository Rust-for-Linux (per confronto, Miguel Ojeda ha aggiunto 53 commit).
Come motivo della sua uscita, si cita la mancanza di energie e di entusiasmo, un tempo presenti, per rispondere ad alcune sciocchezze di natura non tecnica (nontechnical nonsense). Secondo Almeida, gli sviluppatori sono costretti a spendere molte energie in dispute su questioni irrilevanti, che fanno svanire obiettivi globali più importanti. Almeida continua a credere che il futuro dei kernel sia nell'utilizzo di linguaggi che garantiscano un lavoro sicuro con la memoria e, se la comunità degli sviluppatori Linux non lo comprende, Linux sarà sostituito da un altro kernel, come è successo un tempo con Unix.
I sostenitori del progetto Rust-for-Linux si sono trovati ad affrontare la necessità di superare la resistenza da parte di esperti sviluppatori del kernel, che non vedono la necessità di apprendere un nuovo linguaggio. Nella sua lettera di dimissioni, Almeida usa come esempio un link a una discussione tenutasi durante la presentazione di Almeida e Kent Overstreet alla conferenza "Linux Storage, Filesystem, Memory-Management, and BPF Summit", dedicata all'uso di Rust per lo sviluppo di file system. Ted Ts'o, autore dei file system ext2/ext3/ext4, ha criticato l'iniziativa di Rust-for-Linux, paragonandola a un tentativo di costringere tutti ad accettare la religione Rust.
In risposta all'intenzione di Almeida di creare un wrapper per le interfacce dei file system scritte in linguaggio C da utilizzare nel codice in Rust, Ted Ts'o ha sottolineato che un tale wrapper porterà inevitabilmente a problemi, poiché qualsiasi modifica alle interfacce C e rifattorizzazione richiederà modifiche al wrapper per Rust e non vuole prendersi la responsabilità di risolvere i problemi che potrebbero sorgere nel codice Rust e monitorare lo stato del wrapper Rust. Il codice C è in continua evoluzione e se la sua modifica interrompe il funzionamento del wrapper per Rust, questo causerà il malfunzionamento di tutti i file system legati a questo wrapper.
Ted ritiene anche che, nel prossimo futuro, il wrapper per Rust rimarrà secondario e che i problemi nei binding saranno un mal di testa solo per gli sviluppatori di Rust-for-Linux, e non per la comunità degli sviluppatori di file system nel kernel. È stato evidenziato che non tutti gli sviluppatori hanno intenzione di apprendere Rust e, quindi, dopo aver apportato modifiche al codice che influenzano il resto, saranno in grado di aggiornare solo il codice C dipendente, ma non potranno correggere i wrapper Rust, poiché non conoscono Rust. James Bottomley, responsabile del sottosistema SCSI, ha anche partecipato alla discussione, osservando che più semantica viene codificata nei wrapper, più questi diventano fragili in termini di gestione della sincronizzazione.
Nel frattempo, Google, che l'anno scorso ha riscritto in linguaggio Rust il firmware pvmfm, utilizzato in macchine virtuali, lanciati sulla piattaforma Android, ha condiviso l'esperienza dell'integrazione graduale del codice in Rust nei firmware esistenti, originariamente scritti in C o C++. È stato dimostrato come sia possibile migliorare significativamente la sicurezza dei firmware, creando componenti sostitutivi identici in funzionalità, scritti in Rust. Si suggerisce di focalizzarsi sull'uso di Rust per il nuovo codice e per il codice che esegue funzioni critiche dal punto di vista della sicurezza (ad esempio, codice per l'elaborazione di dati esterni provenienti da fonti non affidabili). Per integrare codice Rust e C, si propone di utilizzare strati (shim) che traducono le chiamate tra le API in Rust e in C (l'API C viene esportata per essere utilizzata nel codice Rust e viceversa), consentendo di riscrivere gradualmente elementi dell'API in Rust.
Fonte: opennet.ru
