Jonge programmeertaal Rust levert volwassen geheugenmanagement

o29-technologie-rust

De jonge programmeertaal Rust kan alles wat C en C++ ook kunnen. Het verschil? Rust biedt gegarandeerde beveiliging tegen een groot aantal geheugenproblemen. De taal lost daarmee een probleem op waar programmeurs al decennialang mee kampen.

Artikel uit Objective 29, 2018 - ook beschikbaar in pdf

Von Neumann en geheugenmanagement

De basis voor computers en computerprogramma’s is het Von Neumann-model, dat al meer dan zeventig jaar oud is. In deze architectuur is er één geheugen waarin zowel de instructies als de gegevens van een programma liggen. Dit is de reden dat programmeurs altijd veel aandacht moeten besteden aan het geheugenmanagement van hun code.

De veelgebruikte programmeertalen C en C++ bieden geen ondersteuning voor automatisch geheugenmanagement. De programmeur moet dit zelf afhandelen. Een fout is hierbij snel gemaakt. Als een programmeur honderd geheugenlocaties reserveert en het programma schrijft iets weg op locatie 101, dan is er sprake van een ’buffer overflow’.

Bij een buffer overflow is vaak niet duidelijk wat er precies aan de hand is. In het gunstigste geval wordt er alleen een stuk geheugen beschreven dat toch niet werd gebruikt. Maar de gevolgen kunnen groter zijn. Is er een cruciaal stukje informatie, zoals een wachtwoord, overschreven of juist weggeschreven? Wordt de informatie die is weggeschreven, straks door een andere applicatie ingelezen of door het besturingssysteem? In deze gevallen kan gevoelige informatie op de verkeerde plek terechtkomen. Wat er ook gebeurt, het gebeurt buiten de controle van de programmeur. 

Buffer overruns – Heartbleed
Buffer overruns liggen aan de basis van veel computerproblemen, zoals vastlopers en kwetsbaarheden voor aanvallen. In de afgelopen jaren zijn meerdere ‘exploits’ gevonden: kwetsbaarheden die ontstaan door dit soort fouten en die grote gevolgen kunnen hebben.
Kort geleden werd een kwetsbaarheid ontdekt die bekend is geworden onder de naam Heartbleed. De totale kosten voor het wereldwijd updaten van systemen is geraamd op minimaal vijfhonderd miljoen dollar. De fout zat in een component, OpenSSL, die onder andere gebruikt wordt in netwerkrouters en webservers. De kwetsbaarheid liet toe dat op afstand encryptiesleutels konden worden gelezen uit deze systemen. Met de buitgemaakte encryptiesleutels kan een aanvaller verkeer van en naar de systemen lezen en zich ook voordoen als de originele eigenaar van de sleutel. Als een sleutel van een webserver van een bank wordt buitgemaakt, kan een aanvaller zich voordoen als de webserver van die bank zonder dat een gebruiker in zijn browser het verschil kan zien. Deze kwetsbaarheid zou niet zijn ontstaan als OpenSSL in Rust geschreven zou zijn.

o29-technologie-van-neumann-model

Het Von Neumann-model

Veilig programmeren in Rust

Rust is een relatief nieuwe programmeertaal. Het is net als C en C++ een systeemtaal die geschikt is om systeemprogrammatuur mee te bouwen, zoals besturingssystemen, drivers en compilers. Rust-programma’s compileren direct naar machinecode, waardoor de executables klein blijven en maximale performance haalbaar is.

Er is een ding dat Rust onderscheidt van de meeste overige mainstream-talen: als het gaat om geheugenmanagement is Rust onverbiddelijk. Het is een automatisch proces. Al tijdens het compileren controleert de Borrow Checker (zie kader) het geheugenmanagement. Bevat de programmacode het risico op geheugenproblemen tijdens runtime? Dan breekt de Borrow Checker de compilatie af. Hetzelfde gebeurt wanneer de code data-races veroorzaakt: parallelle processen die gelijktijdig dezelfde geheugenplaats benaderen. Veilig programmeren wordt op deze manier afgedwongen. Voor doorgewinterde programmeurs is programmeren met Rust daardoor een compleet nieuwe ervaring, ondanks de overeenkomsten met C en C++. Zij moeten even wennen aan de strenge Borrow Checker.

Rust is niet de enige taal die een oplossing biedt voor geheugenmanagement. Een taal als Java doet dit ook, maar dan tijdens runtime, met flinke gevolgen voor de performance. Een significant nadeel wanneer software zo snel mogelijk moet reageren, zoals in medische of industriële toepassingen. In Rust speelt dit nadeel niet. Overigens is het ook mogelijk om onveilig te programmeren in Rust, maar dit kan alleen als de programmeur hier expliciet voor kiest.

Borrow Checker – automatisch geheugenmanagement
De schijnbare magie van het automatische geheugenmanagement, zonder performance-verlies, van Rust ligt in de Borrow Checker. Dit stuk software, onderdeel van de compiler, houdt nauwgezet bij hoe de programmeur de data in het geheugen van de computer gebruikt. De Borrow Checker weigert de programmacode om te zetten in een uitvoerbaar bestand als er geheugenfouten in zitten. De Borrow Checker detecteert veel bekende fouten zoals ‘double free’, ‘null pointer access’, ‘dangling pointer’, ‘uninitalised read’ en ‘data-races’. Rust kan er zo ook voor zorgen dat geheugen precies op het goede moment weer wordt vrijgegeven.

Belang voor klanten

Technolution gebruikt verschillende programmeertalen en kiest de taal die het beste past bij de oplossing. De meeste van onze klanten hebben geen voorkeur voor een taal. Zij kijken vooral naar het eindproduct en verwachten een robuuste, goed onderhoudbare applicatie die doet wat hij moet doen. De selectie van de onderliggende technologie laten ze doorgaans aan ons over. De keuze voor de taal maken wij daarom meestal.

Wanneer kiezen wij voor Rust? Dat hangt sterk van de context af. Hierbij spelen verschillende vragen een rol. Wat zijn de eisen op het gebied van security? Hoe belangrijk is een hoge performance? Rust en het bijbehorende ecosysteem zijn nog volop in ontwikkeling, maar de taal zal zeker in beeld komen bij de ontwikkeling van nieuwe toepassingen waarbij hoge prestaties, robuustheid en bescherming tegen exploits cruciale factoren zijn. De belangen van de opdrachtgever wegen uiteraard altijd het zwaarst bij deze afwegingen.

Ecosysteem en community

Vergeleken met andere programmeertalen is Rust piepjong. De taal is begonnen als een privéproject van een medewerker van Mozilla, de makers van de open source internetbrowser Firefox. Mozilla publiceerde de eerste stabiele versie in 2015. Ter vergelijking: Java dateert uit 1996 en de eerste versie van C kwam al in 1972 op de markt. Er komen bijna dagelijks nieuwe programmeertalen beschikbaar. Het leeuwendeel daarvan verdwijnt al snel weer in de vergetelheid. Het kost tijd totdat een nieuwe taal bij ontwikkelaars voldoende krediet opbouwt en een vaste plek verovert. Toch zijn er voldoende redenen om vertrouwen te hebben in de toekomst van Rust.

Wat maakt een programmeertaal tot een goede programmeertaal? En wanneer is een taal succesvol? Allereerst is het belangrijk dat de taal een duidelijke syntaxis heeft en goed leesbaar is. Performance is in veel toepassingsgebieden ook cruciaal, net als ondersteuning voor datastructuren en verschillende besturingssystemen. Rust voldoet aan al deze eisen. Maar een goede programmeertaal is nog geen succesvolle programmeertaal.

Om succes te hebben in de wereld van ontwikkelaars is het vooral belangrijk dat een programmeertaal een uitgebreid ecosysteem en een sterke community heeft. Java is een goed voorbeeld van een taal die groot is geworden dankzij een groot ecosysteem met vele library’s, in stand gehouden door een levendige, goed georganiseerde community. De community is precies waar ook de kracht van Rust ligt.

Mozilla heeft een uitstekende reputatie als het gaat om het ondersteunen van open source. Hun Firefox-browser heeft een grote community, die actief bijdraagt aan de veiligheid van de browser, de ontwikkeling van nieuwe features en het oplossen van bugs. Voor Rust heeft Mozilla dan ook vanaf het allereerste begin gekozen voor een inzichtelijk updateschema, soepele en omvangrijke ondersteuning voor library’s en een krachtige, snelgroeiende community. Een ontwikkelaar die aan de slag gaat met Rust zal ontdekken dat er uitstekende documentatie klaar staat, dat er een grote set kant-en-klare library’s beschikbaar is en dat er vele anderen klaar staan om te helpen bij vragen of problemen.

o29-technologie-rust-code

Technolution en Rust

De kennismaking met Rust verliep op een typische Technolution-manier. De meeste ontwikkelaars bij Technolution hebben ervaring met meerdere programmeertalen. Een van hen had een goed presterende taal nodig voor de ontwikkeling van een videowall-applicatie. Java bood niet de gewenste performance en het was lang geleden dat onze collega in C had geprogrammeerd. Hij besloot om voor Rust te kiezen en werd aangenaam verrast door de stabiliteit, het ecosysteem en het gemak waarmee hij productief kon worden in Rust. Andere collega’s werden aangestoken door zijn enthousiasme. Dat was genoeg aanleiding om ons verder te verdiepen in Rust.

We zijn nu een jaar verder. Rust heeft zich bewezen in verschillende projecten. De taal heeft veel momentum opgebouwd en we zijn begonnen met het geven van interne en externe workshops voor ontwikkelaars. De reacties zijn heel positief. Er is veel belangstelling, binnen en buiten Technolution.

Vertrouwen en investeren

Wij hebben vertrouwen in Rust en leveren daarom graag een bijdrage aan de Rust-community. In Nederland zijn wij actief betrokken bij meerdere Rust-gebruikersgroepen. Ook inhoudelijk werken wij aan het vergroten van de toepasbaarheid van Rust. In samenwerking met de TU Delft ontwikkelen we bijvoorbeeld een tool die ervoor moet zorgen dat in Rust geschreven software alle mogelijke foutcondities onderkent en hier corrigerende maatregelen voor neemt. De software gaat hierdoor niet meer onderuit en is dus continu beschikbaar om de gewenste functionaliteit te leveren. 

Daarnaast onderzoeken wij de mogelijkheden voor het gebruik van Rust in de open source processorarchitectuur RISC-V. Deze is nu nog volledig in C gecodeerd. Rust compileert naar een native executable in machinecode, biedt automatisch geheugenmanagement en is daardoor bijzonder geschikt voor deze toepassing. We letten uiteraard ook op eventuele nadelen. Is het überhaupt mogelijk met Rust? Zijn er gevolgen voor de performance? Welke beperkingen zien we? Wij gebruiken een softcoreversie van RISC-V in ons securityplatform JelloPrime, dat snelle beveiligde verbindingen realiseert op basis van encryptie die is embedded in elektronica. We streven naar maximale security en wij denken dat Rust hier aan kan bijdragen.

Contact:

sergedevos-website
  • Serge de Vos
  • CTO

Gerelateerde items

De wereld als sensor - Koppelaar van ‘big data’

Lees verder

Publicatie

Asset monitoring: 'Technolution levert ons nachtrust'

Lees verder

Publicatie

Veilige autonome systemen dankzij enabling technologies

Lees verder

Publicatie

Video over IP: snelheid, kwaliteit en gebruiksgemak

Lees verder

Publicatie