Tarkvarasüsteemi ohutus

Tarkvarasüsteemi ohutus on üks tarkvaratehnika haru. See üritab tõhustada tarkvarasüsteemide ohutust, sekkudes süsteemide, eelkõige n-ö ohutuskriitiliste ("safety critical") süsteemide disainimisse, ehitusse, kasutusse ja hooldusse. Eelkõige on tähelepanu all süsteemid, mis võivad otseselt vigastada või ohtu seada inimeste elu või kahjustada märgataval määral keskkonda. 
Nagu ala nimetus ütleb, on ohutuse tagamiseks vaja selgeks teha seosed kogu süsteemi ulatuses, kuivõrd muudatusi füüsilisse maailma teevad lõpuks muud süsteemi osad, kui seda kõike juhtiv tarkvara ning neil võib esineda ka koosmõjusid. Arvutite ja mikrokontrollerite, mis on n-ö ühekiibiarvutid, võidukäigust näeb igaüks, et kellegi koostatud juhtprogrammid kontrollivad ja juhivad järjest rohkem asju meie ümber ning, et neile on usaldatud ka süsteemid, kus vigadega kaasnevad väga tõsised tagajärjed. Samas pole ohutuse pool tarkvaraarenduses sugugi hästi arenenud. Ohutustehnika tegeleb põhiliselt süsteemi töö selle poolega, kui süsteemi tekib viga ja see ei tööta nii nagu eeldatud.
Tarkvaravigadest põhjustatud õnnetusi.
Üks tuntuim õnnetustesari, mis oli põhjustanud põhiliselt vigadest tarkvaras, on Therac-25 juhtum. See oli kiiritusravimasin, mille kasutamisel 1985.–1987. aastal sai vähemalt kuus inimest lubatust 100 korda võimsama kiirgusdoosi ja kellest kolm surid selle tagajärjel. Masin töötas kahel viisil, esiteks tegi väikese võimsusega otse väljastatud elektronkiir teraapiat ning teiseks teraapiaks väljastas röntgenikiiri. Need saadi kui suure võimsusega väljastatud elektronkiirtele seati ette konverter, mis selle röntgenikiirteks muutis, filter mis need suurele pinnale laiali suunas ning kamber mis suunas ning mõõtis röntgenikiirte tugevust. Õnnetus juhtus, kui operaator oli ekslikult valinud suurema väljundvõimsuse x-klahviga, märganud seda ning sellele järgnevalt valinud "nool üles" ning "e" korrektse viisi jaoks ning vajutanud Enter-klahvi. Seejärel said patsiendid justkui suure elektrilöögi ning arvasid, et midagi läks valesti, operaatorid usaldasid liigselt masinat ning arvasid, et kõik on siiski korras. Antud juhul oli masin väljastanud selle suure võimsusega elektronkiire otse väiksele alale, sest väljundviis jäi muutmata, aga ka vahepealseid muutvaid seadmeid ei olnud kiirel ees. Järgnenud juurdlused leidsid: et tootja polnud lasknud koodi eraldi üle kontrollida; oli taaskasutatud eelmise mudeli koodipõhja, millel olid sisemised riistvara blokeeringud, et kaks viisi segamini ei töötaks; süsteem sai aru, et midagi on valesti, aga kuvas ainult teksti "viga", millele järgnes arv vahemikus 1–64, seda polnud kasutusjuhendis mainitud, ning sai vajutada p-nuppu, mis lihtsalt tühistas lihtsalt, ja sai jätkata.
Enamik tänapäeva meditsiiniaparatuuri sisaldab arvutisüsteeme ning pea kõik nende tagasikutsumised või leitud vead on just tarkvara vigade pärast. Välja on toodud, et põhjus seisneb selles, et kuigi osatähtsus süsteemi korrektses töötamises on võrdne riistvaraga, siis erinevalt masinaehitusest pole tarkvaraarenduses välja töötatud ning järjepidevas kasutamises tarkvara ohutust tagavaid meetodeid ega eeskirju. Tarkvaratööstus on viimase ajani seadnud põhiliselt esile ainult produktiivsuse ning keskmiselt jääb 1000 koodirea kohta sisse algselt 50 viga, 75% vigadest avastatakse testimise käigus, ülejäänud 25% jääb kasutajate avastada. Kvaliteetseks loetakse koodi, millel on 1–5 viga tuhande koodi rea kohta. Mikrolaine ahju juhtprogramm koosneb aga juba mõnesajast või tuhandest koodireast ning suuremad süsteemid nagu lennuki juhtsüsteemid koosnevad mitmest sajast tuhandest või lausa miljonist koodireast. Kui tavaliselt teeb personaalarvuti kasutaja programmi vea järel lihtsalt restardi, teeb oma töö uuesti või laseb inimesel arvuti möödapaneku parandada, siis ohutuskriitilistes süsteemides see võimalik pole ning veale järgneb tavaliselt õnnetus. Peamised ohutuskriitilised süsteemid on juba mainitud meditsiin, lennundus, muud liiklusvahendid, näiteks autod ja rongid, energeetika valdkond (sh tuumaenergia) ning relvad. 
Katastroofe on aga ka kaasnenud ka tavapärasemate tarkvaraprogrammide vigadest, näiteks üks naftaplatvorm (Sleipner A) varises paigaldamisel kokku, kuna ei arvutatud käsitsi üle mudeldusprogrammi tugevusarvutusi, milles esines viga ning raudbetoon alus ehitati liiga õhuke merepõhjas olevale rõhule vastupidamiseks.
Tarkvaravigadest põhjustatud juhtumite näiteid:
Mida teha tarkvarasüsteemide ohutuse suurendamiseks?
Põhiline on parandada programmeerijal iseenda tööd ning olla teadlik, et programmeerimisel tehakse tavaliselt palju vigu. Neid esineb ka suurte ning tähtsate süsteemide seas, mis mõnevõrra juba testitud võivad kellegi poolt olla. Inglismaa kaitseministeeriumi uuring näiteks selgitas välja, et isegi juba kasutusel olnud sõjaväe relvade ja masinate juhtsüsteemides, esines siiski ikka vigu, mis oleks suutnud kaks maksimaalset äärmust ära vahetada. 
Samuti tuleb arendajatel pidevalt endale meelde tuletada, kui katastroofilised võivad mõne juhtprogrammi vead olla ja vajalikul määral ka ohutusele tähelepanu pöörata, kuigi funktsionaalsus tundub lõpuks olevat see mida müüakse. Inglismaal kehtib EL-i masinaohutusdirektiivil põhinev seadus, mis määrab, et firma direktor või osakonnajuht, kes on hooletusse jätnud ohutuse tagamise masina disainil või ehitusel, mis põhjustab vigastusi, võidakse vastava õnnetuse põhjustamise eest kriminaalvastutusele võtta.
On küll mitmeid nii tegevusalade kui üldisi (IEEE STD 1228–1994 Software Safety Plans) tarkvara ohutust tagada püüdvaid tegevusjuhiseid, kuid on need enamuses ainult väga üldised meetodite kirjeldused. Tähtis on, et ohutuskriitilistes süsteemides oleks ohutuse pool kohe algusest sisse projekteeritud ning ehitatud põhiosa, mitte eraldi lisatud funktsioon ning et selle täideviimist pidevalt jälgitaks ja juhitaks mõne eraldi kõrgemal ametikohal oleva isiku poolt. Et tellijal oleks toodete talitlusest pidev ülevaade ning et ka tema vastutaks vigade tekkimise korral, sest klient teab võimalikke ohusituatsioone ja vigu paremini. Siin on oluline ka korraliku tegelikkusele vastava dokumentatsiooni loomine arendusprotsessi käigus, et klient saaks õigesti asjadest aru. Therac-25-l loodi ka korraliku mahuga dokumentatsioon, kuid ülevaatamisel selgus, et see oli vaid n-ö ilus jutt. 
Samuti pole hea, kui minnakse kogu süsteemi koondamise teed, nagu antud kiiritusravimasinal ning kogu tavaline mitmetahuline kontrollsüsteem on usaldatud vaid ühe arvuti hoolde. See toob kaasa oluliselt suurema riski, sest kui mingis väikses osas tekib tõrge, siis kantakse see sealt kogu süsteemile üle. See rikub ohutustehnika ("safety engineering") põhimõtteid, millega peaks ka ohutuskriitiliste süsteemide tarkvara insener tuttav olema, kuid pahatihti see nii pole.
Kõikides teistes inseneriteaduste harudes vaatab ja kontrollib kõik plaanid ja tööd eraldi veel kord üle suurte kogemustega vaneminsener, nii peaks see ka olema tarkvaraarenduses. On arutletud ka selle üle, et kõik insenerid peavad olema läbinud oma ameti kutsekvalifikatsiooni eksamid, et ehk peaks see olema nii ka tarkvaratehnikutel, kes ennast insenerideks peavad.
Formaalsed meetodid.
Kui üldiselt on tarkvara ohutuse ala alles arengu algusfaasis ning pole välja töötatud meetmeid, mis suudaks suure tõenäosusega ohutuse tagada, siis on siiski üks laiemalt levinud ja tunnustust leidnud tehnikate kogum – formaalsed meetodid. See sisaldab meetodeid nagu B-method, Lustre, Abstract State Macine jne. Need kõik varieeruvad mõnevõrra oma käsitlusviisidelt ja lõppeesmärkide osas. Ühine on neil see, et juba programmi spetsifikatsioon kirjutatakse üles matemaatika ning loogika tehteid kasutades ning üritatakse selle põhjal siis analüüsides välja selgitada kõikvõimalikud programmi käitumisviisid, programmeerimisel lähtutakse ja kasutatakse spetsifikatsiooni osasid ning lõpus võrreldakse programmi ning spetsifikatsioonide põhjal koostatud lõpptulemusi. Formaalsete meetodite kasutamine on väga kallis ning selle vastaste arvates ei anna vajalikku tulemust. Samas järjest enam nõutakse seda suuremate ohutuskriitiliste süsteemide korral (näiteks lennunduses), sest see suudab parandada arusaamist programmi tööst, enam ei selgu programmi käitumine arendamise lõppjärgus testimise käigus ning ühtlasi sunnib kasutama lihtsamaid/arusaadavamaid osi.