Το χρονικό ενός κρίσιμου σφάλματος
Η κοινότητα της Rust ήρθε αντιμέτωπη με ένα από τα πιο σημαντικά σφάλματα ασφαλείας των τελευταίων ετών (issue #164250). Πρόκειται για ένα κενό ασφαλείας (soundness hole) που επιτρέπει την παράκαμψη των εγγυήσεων του borrow checker, οδηγώντας σε ακαθόριστη συμπεριφορά (undefined behavior) και σφάλματα τύπου use-after-free. Το ανησυχητικό είναι ότι το σφάλμα αυτό παρέμενε απαρατήρητο για περίπου 11 χρόνια, επηρεάζοντας εκδόσεις της γλώσσας από το 2017 και μετά.
Η αρχιτεκτονική διάσταση του προβλήματος
Το πρόβλημα προκύπτει από τον τρόπο με τον οποίο ο compiler διαχειρίζεται τη συνδιακύμανση (covariance) σε πεδία δομών (structs). Συγκεκριμένα, όταν μια δομή ορίζει ένα lifetime bound (π.χ. T: 'static), ο compiler αποτυγχάνει να επιβάλει αυτόν τον περιορισμό κατά την ανάθεση τιμών σε πεδία της δομής, εάν η ανάθεση γίνεται μέσω covariant μετατροπών.
Αυτό επιτρέπει σε έναν Drop destructor να αποκτήσει πρόσβαση σε μια αναφορά που θεωρείται λανθασμένα ως 'static, ενώ στην πραγματικότητα αναφέρεται σε δεδομένα που έχουν ήδη βγει εκτός εμβέλειας (out of scope). Το αποτέλεσμα είναι η δυνατότητα εκτέλεσης κώδικα που διαβάζει ή τροποποιεί μνήμη που έχει ήδη αποδεσμευτεί.
Επιπτώσεις και επόμενα βήματα
Η ομάδα των Types της Rust αξιολογεί το ζήτημα ως υψηλής προτεραιότητας (P-high). Το σφάλμα υπογραμμίζει τις προκλήσεις στη διατήρηση της ορθότητας (soundness) σε ένα σύστημα τύπων που βασίζεται σε σύνθετους κανόνες lifetimes και variance. Η επίλυση του προβλήματος απαιτεί πιθανότατα αλλαγές στον τρόπο που ο compiler εκτελεί το type unification, ώστε να διασφαλίζεται ότι τα lifetime bounds ελέγχονται εξαντλητικά σε κάθε σημείο ανάθεσης, ανεξάρτητα από τη διακύμανση των τύπων.