Säkra programspråk för automationssystemet ABB 800xA Markus Borg och Lukasz Serafin Institutionen för reglerteknik Institutionen för datavetenskap Lunds Tekniska Högskola 1 Programvara överallt I vår moderna värld blir vi allt mer beroende av datorer. Dessa används till att styra allt möjligt, t ex industrirobotar, produktionsprocesser och flygplan. Det är lätt att förstå att många av dessa system ställer mycket höga krav på säkerheten. Om något går fel i dessa system, så finns risken att mycket stor skada sker. I värsta fall så kan människoliv vara i fara. Man säger att den här typen av system är säkerhetskritiska. En viktig orsak till många av de fel som inträffar är att det finns fel i programvaran, alltså koden som bestämmer hur ett system uppför sig. Dagens stora programvarusystem kan bestå av flera miljoner rader kod, och de programmerare som skriver koden är inte mer än människor; då och då kommer de att göra fel. För att antalet fel i ett system ska vara så få som möjligt, så utsätter man systemet för många olika tester. Man kan dock aldrig vara säker på att man hittar alla fel som finns. När man skriver kod, så gör man detta i ett programmeringsspråk. Det är språket som bestämmer reglerna för kodens struktur och mening. Det finns i dag tusentals olika språk på marknaden. När man programmerar i några av dessa, så kan man överhuvudtaget inte göra vissa typer av fel som är väldigt lätta att göra i andra språk. Även när man kan göra samma typ av fel i två olika språk, så kanske det är lättare att upptäcka felet i det ena språket än i det andra. Kort sagt så är vissa språk mer säkra än andra, och i säkerhetskritiska system så bör givetvis så säkra språk som möjligt användas. Vårt examensarbete gick ut på att försöka förbät- tra säkerheten i ett visst system genom att skriva om en liten del av systemet i ett mer säkert språk än det ursprungliga. Systemet i fråga heter 800xA. 2 Automationssystemet 800xA 800xA är ett automationssystem som utvecklats av företaget ABB. Det används till att styra oljeplattformar, kärnkraftverk och många andra system där säkerheten är i fokus. För att mycket översiktligt förstå hur det fungerar när ett automationssystem som 800xA styr saker och ting, så låt oss se på ett exempel där temperaturen i ett rum ska styras. Systemet är då kopplat till en mottagare som mäter temperaturen. Värden på den aktuella temperaturen jämförs med ett referensvärde, alltså ett värde på den önskade temperaturen i rummet. Utifrån denna information beräknar systemet styrsignaler som skickas till en givare i rummet. I det här fallet är givaren ett termoelement. Den värme som elementet ger ifrån sig (och som alltså beror på de styrsignaler som har beräknats) är precis så stor att den önskade temperaturen i rummet ska kunna hållas. Principen för hur allt det här fungerar är densamma oavsett vad det är som ska styras. Koden i 800xA är för närvarande skriven i programmeringsspråken C och C++. Dessa språk är mycket populära och program som är skrivna i dem blir ofta små och snabba. Tyvärr har både C och C++ stora problem vad gäller säkerheten. 3 Säkerhetsproblem med C och C++ När man programmerar i C eller C++, så är det mycket lätt hänt att man gör något fel. Här ska vi nöja oss med att ta upp en enda felkälla. En vanlig sak man gör när man programmerar, är att man skapar objekt. Dessa objekt kan symbolisera allt möjligt, t ex människor, skolklasser, betygsdokument, leksaker och kartor. Varje objekt som skapas tar en del av programmets minne i anspråk. Därför är det viktigt att ta bort objekt man har skapat när de inte ska användas mer. Om man bara skapar objekt hela tiden men aldrig tar bort några, så tar programmets minne så småningom slut, vilket medför att programmet slutar fungera. Problemet med C och C++ är att när man programmerar i dessa språk så tvingas man att själv ta bort de objekt man skapar. Det är lätt hänt att man glömmer ta bort något objekt. Det är också lätt hänt att man råkar ta bort objekt som fortfarande används och alltså ännu inte borde ha tagits bort. Dessa fel kan vara svåra att upptäcka och de kan medföra stora problem. 4 Java, ett säkert språk Java är ett programmeringsspråk som har utvecklats av företaget Sun Microsystems. Det är ett mycket säkrare än språk än C och C++. Till exempel så behöver programmeraren inte själv ta bort objekt i Java, utan i språket finns en inbyggd så kallad Garbage Collector som automatiskt tar bort objekt som inte längre används. På så sätt blir några av de fel som lätt sker när man programmerar i C och C++ helt omöjliga att göra i Java. Borde då alla program som för närvarande är skrivna i C och C++ översättas till Java? Svaret är nej. Det finns nämligen andra parametrar än säkerhet att ta hänsyn till, t ex prestanda och minnesåtgång. 800xA är ett så kallat realtidssystem. I ett realtidssystem så är det inte tillräckligt om ett program gör det den ska; det måste dessutom göra det inom en viss tid. Det måste kunna garanteras att programmet aldrig tar för lång tid på sig. Problemet med standardversionen av Java är att det inte kan garanteras att program skrivna i det språket alltid uppfyller de tidskrav som finns. Anledningen till detta är faktiskt inget mindre än den inbyggda Garbage Collectorn. Nu är man dock inte tvungen att använda just standardversionen av Java. Vid institutionen för datavetenskap vid Lunds tekniska högskola har LJRT (Lund Java-based Real Time) utvecklats. Det är en så kallad Java-till-C-kompilator. Detta innebär att programmeraren skriver koden i Java (vilket medför säkerhetsfördelar) men att LJRT sedan översätter koden till C (vilket medför vissa andra fördelar). En fin sak med LJRT är att den har en inbyggd Garbage Collector som, till skillnad från standardversionens Garbage Collector, inte gör det omöjligt att garantera att programmet alltid uppfyller sina tidskrav. 5 Översättning till Java Som en del av vårt examensarbete provade vi att använda LJRT för att introducera Java i 800xA. Vi översatte en befintlig modul av systemet från C och C++ till Java och använde LJRT för att kompilera (översätta) det till C. Den C-kod som genererades av LJRT lade vi därefter till i den befintliga kodbasen för systemet. En stor del av vårt arbete handlade om att få bitarna att fungera tillsammans. För att vara säkra på att vår lösning fungerade bra och uppfyllde de krav som ställs på systemet följde vi en av ABBs formella testsviter för vår aktuella moduls funktionalitet. Testerna gick bra och vår Javalösning visade sig fungera som originalet. Två enkelt mätbara faktorer av stor vikt är prestanda och minnesåtgång. Det förstnämnda bedömde vi genom att mäta hur lång tid utvald kod körde. Minnesåtgången kunde vi fastställa genom att studera hur mycket ledigt minne 800xA hade när det var igång. Resultaten visade att det fanns en tydlig skillnad; vår Javalösning var både långsammare och tog mer plats. Det är inte ovanligt att det uppstår situationer där högre säkerhet går ut över effektivitet på detta vis. I många lägen kan det vara svårt att avgöra vilken lösning som är bäst. Ansträngningar för att kunna producera lösningar så billigt som möjligt brukar innebära att begränsad hårdvara används, vilket sätter höga krav på programvarans prestanda och minnesåtgång. Examensarbetet har konkret visat att man kan använda sig av andra programmeringsspråk för utveckling av produkten. Dessutom har vi sett att Javatill-C-kompilering är ett fungerande alternativ för att gradvis introducera Java i 800xA, vilket kan vara värdefullt om man inte vill översätta hela systemet på en gång.